瀏覽代碼

Merge remote-tracking branch 'origin/develop3.0' into develop3.0

JAELYS 4 年之前
父節點
當前提交
38c41d330a
共有 100 個文件被更改,包括 2963 次插入9928 次删除
  1. 0 77
      TEAMModelGrpc/Services/BlobSASService.cs
  2. 0 93
      TEAMModelGrpc/Services/KnowledgeService.cs
  3. 0 124
      TEAMModelGrpc/Services/SyllabusService.cs
  4. 0 82
      TEAMModelGrpc/Services/VolumeService.cs
  5. 2 2
      TEAMModelGrpc/Startup.cs
  6. 0 115
      TEAMModelGrpc/TEAMModelOS.GRPC.xml
  7. 5 5
      TEAMModelOS.SDK/Context/Filters/HttpGlobalExceptionInvoke.cs
  8. 19 19
      TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs
  9. 2 2
      TEAMModelOS.SDK/DI/AzureCosmos/Inner/ID.cs
  10. 1 1
      TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs
  11. 2 2
      TEAMModelOS.Service/Models/SchoolInfo/Inner/Semester.cs
  12. 2 0
      TEAMModelOS.Service/Models/SchoolInfo/Survey.cs
  13. 2 0
      TEAMModelOS.Service/Models/SchoolInfo/Vote.cs
  14. 2 4
      TEAMModelOS.Service/Models/StudentInfo/LearnRecord.cs
  15. 4 0
      TEAMModelOS.Service/Models/TeacherInfo/LearnTask.cs
  16. 0 15
      TEAMModelOS.Service/Services/Analysis/Interfaces/IAchievementService.cs
  17. 0 13
      TEAMModelOS.Service/Services/ChangeFeed/IChangeFeedService.cs
  18. 0 10
      TEAMModelOS.Service/Services/ChangeFeed/IChangeService.cs
  19. 0 24
      TEAMModelOS.Service/Services/ChangeFeed/KnowledgeChangeFeed.cs
  20. 0 23
      TEAMModelOS.Service/Services/ChangeFeed/SyllabusVolumeChangeFeed.cs
  21. 0 12
      TEAMModelOS.Service/Services/Evaluation/Implements/EvaluatingService.cs
  22. 0 9
      TEAMModelOS.Service/Services/Evaluation/Interfaces/IEvaluatingService.cs
  23. 0 13
      TEAMModelOS.Service/Services/Evaluation/Interfaces/IHtmlAnalyzeService.cs
  24. 0 18
      TEAMModelOS.Service/Services/Evaluation/Interfaces/IImportExerciseService.cs
  25. 0 119
      TEAMModelOS.Service/Services/Learn/Implements/ServiceBusReviceService.cs
  26. 0 46
      TEAMModelOS.Service/Services/Learn/Implements/TimerWorkService.cs
  27. 0 14
      TEAMModelOS.Service/Services/Learn/Interfaces/IServiceBusReviceService.cs
  28. 0 16
      TEAMModelOS.Service/Services/Learn/Interfaces/IServiceBusService.cs
  29. 0 13
      TEAMModelOS.Service/Services/Learn/Interfaces/ITimerWorkService.cs
  30. 0 16
      TEAMModelOS.Service/Services/PowerPoint/Interface/IHtexService.cs
  31. 0 17
      TEAMModelOS.Service/Services/Syllabus/Interface/IKnowledgeService.cs
  32. 0 34
      TEAMModelOS.Service/Services/Syllabus/Interface/ISyllabusService.cs
  33. 0 16
      TEAMModelOS.Service/Services/Syllabus/Interface/IVolumeService.cs
  34. 5 1974
      TEAMModelOS.Service/TEAMModelOS.Model.xml
  35. 3 0
      TEAMModelOS.Service/TEAMModelOS.Service.csproj
  36. 4 0
      TEAMModelOS/ClientApp/src/api/courseMgmt.js
  37. 50 0
      TEAMModelOS/ClientApp/src/api/forgetPW.js
  38. 2 0
      TEAMModelOS/ClientApp/src/api/index.js
  39. 41 42
      TEAMModelOS/ClientApp/src/api/regist.js
  40. 24 11
      TEAMModelOS/ClientApp/src/common/BaseMock.vue
  41. 4 0
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.less
  42. 8 7
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue
  43. 5 3
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue
  44. 34 13
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.vue
  45. 4 1
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVotePie.vue
  46. 20 7
      TEAMModelOS/ClientApp/src/components/learnactivity/ChooseContent.vue
  47. 4 2
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  48. 8 2
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue
  49. 29 7
      TEAMModelOS/ClientApp/src/css/disabled-iview-form.less
  50. 33 30
      TEAMModelOS/ClientApp/src/router/routes.js
  51. 1 1
      TEAMModelOS/ClientApp/src/utils/countryCodeData.js
  52. 1 1
      TEAMModelOS/ClientApp/src/utils/js-fn.js
  53. 3 1
      TEAMModelOS/ClientApp/src/utils/public.js
  54. 0 0
      TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourse.less
  55. 0 394
      TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourse.vue
  56. 0 333
      TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourseClassroom.less
  57. 0 1011
      TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourseClassroom.vue
  58. 0 275
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseBaseSetting.less
  59. 0 538
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseBaseSetting.vue
  60. 0 333
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseClassroom.less
  61. 0 903
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseClassroom.vue
  62. 0 151
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseManage.less
  63. 0 383
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseManage.vue
  64. 0 70
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseSyllabus.less
  65. 0 214
      TEAMModelOS/ClientApp/src/view/coursemgmt/CourseSyllabus.vue
  66. 22 13
      TEAMModelOS/ClientApp/src/view/evaluation/bank/ExerciseList.vue
  67. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/bank/TestPaperList.less
  68. 126 0
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue
  69. 184 0
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChildList.vue
  70. 568 0
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue
  71. 631 570
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue
  72. 18 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.less
  73. 59 11
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreateExercises.vue
  74. 71 63
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  75. 0 267
      TEAMModelOS/ClientApp/src/view/evaluation/index/EditChild.vue
  76. 4 0
      TEAMModelOS/ClientApp/src/view/evaluation/index/PickExercise.css
  77. 3 3
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue
  78. 17 14
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue
  79. 58 0
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompose.vue
  80. 239 0
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSimpleCompletion.vue
  81. 1 2
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  82. 14 0
      TEAMModelOS/ClientApp/src/view/forgotPw/Index.less
  83. 297 0
      TEAMModelOS/ClientApp/src/view/forgotPw/Index.vue
  84. 1 1
      TEAMModelOS/ClientApp/src/view/login/Index.vue
  85. 3 0
      TEAMModelOS/ClientApp/src/view/newcourse/CourseClassroom.vue
  86. 9 0
      TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.less
  87. 94 44
      TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.vue
  88. 69 25
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  89. 0 2
      TEAMModelOS/ClientApp/src/view/regist/Index.vue
  90. 15 2
      TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.less
  91. 135 129
      TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.vue
  92. 0 1
      TEAMModelOS/ClientApp/src/view/selflearning/ActivityReport.less
  93. 0 20
      TEAMModelOS/ClientApp/src/view/selflearning/ActivityReport.vue
  94. 0 67
      TEAMModelOS/ClientApp/src/view/selflearning/CreateHomeWork.less
  95. 0 43
      TEAMModelOS/ClientApp/src/view/selflearning/CreateHomeWork.vue
  96. 0 137
      TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.less
  97. 0 500
      TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.vue
  98. 0 111
      TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.less
  99. 0 240
      TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.vue
  100. 0 0
      TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.less

+ 0 - 77
TEAMModelGrpc/Services/BlobSASService.cs

@@ -1,77 +0,0 @@
-using Google.Protobuf.WellKnownTypes;
-using Grpc.Core;
-using Grpc.Extension.Abstract;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using TEAMModelGrpc.Models;
-using TEAMModelOS;
-using TEAMModelOS.SDK.Context.Exception;
-using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
-
-namespace TEAMModelGrpc.Services
-{
-    public class BlobSASService : IGrpcService
-    {
-
-        private readonly IAzureBlobDBRepository _azureBlobDBRepository;
-
-        public BlobSASService(IAzureBlobDBRepository azureBlobDBRepository)
-        {
-            _azureBlobDBRepository = azureBlobDBRepository;
-        }
-
-        /// <summary>
-        /// 获取bolb共享访问权限
-        /// </summary>
-        /// <param name="empty"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        public async Task<BlobSASDto> GetContainerSasUri(Empty empty, ServerCallContext context) {
-            (string,string, string) aaa = await _azureBlobDBRepository.GetContainerSasUri();
-            BlobSASDto blobSASDto = new BlobSASDto();
-            blobSASDto.Url = aaa.Item1;
-            blobSASDto.Container = aaa.Item2;
-            blobSASDto.SAS = aaa.Item3;
-            return blobSASDto;
-        }
-
-        /// <summary>
-        /// 获取blob共享访问权限 (只读)
-        /// </summary>
-        /// <param name="blob"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        public async Task<BlobSASDto> GetContainerSASRead(BlobSASDto blob, ServerCallContext context)
-        {
-            (string, string) a = BlobUrlString(blob.Url);
-            string ContainerName = a.Item1;
-            string BlobName = a.Item2;
-            bool flg = IsBlobName(BlobName);
-            if (flg)
-            {
-                var SAS = await _azureBlobDBRepository.GetBlobSasUriRead(ContainerName, BlobName);
-                return new BlobSASDto { Url = SAS.url+SAS.sas };
-            }
-            else throw new BizException("文件名错误", ResponseCode.PARAMS_ERROR);
-        }
-
-        private static (string, string) BlobUrlString(string sasUrl)
-        {
-            sasUrl = sasUrl.Substring(8);
-            string[] sasUrls = sasUrl.Split("/");
-            string ContainerName;
-            ContainerName = sasUrls[1].Clone().ToString();
-            string item = sasUrls[0] + "/" + sasUrls[1] + "/";
-            string blob = sasUrl.Replace(item, "");
-            return (ContainerName, blob);
-        }
-
-        public static bool IsBlobName(string BlobName)
-        {
-            return System.Text.RegularExpressions.Regex.IsMatch(BlobName,
-             @"(?!((^(con)$)|^(con)\\..*|(^(prn)$)|^(prn)\\..*|(^(aux)$)|^(aux)\\..*|(^(nul)$)|^(nul)\\..*|(^(com)[1-9]$)|^(com)[1-9]\\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\\..*)|^\\s+|.*\\s$)(^[^\\\\\\:\\<\\>\\*\\?\\\\\\""\\\\|]{1,255}$)");
-        }
-    }
-}

+ 0 - 93
TEAMModelGrpc/Services/KnowledgeService.cs

@@ -1,93 +0,0 @@
-using Google.Protobuf;
-using Grpc.Core;
-using Grpc.Extension.Abstract;
-using Microsoft.AspNetCore.Authorization;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using TEAMModelGrpc.Models;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-using TEAMModelOS.Service.Services.Interface;
-
-namespace TEAMModelGrpc.Services
-{
- 
-    public class KnowledgeService : IGrpcService
-    {
-        private AzureCosmosFactory cosmosDBV3Repository;
-        private IKnowledgeService knowledgeService;
-
-        public KnowledgeService(AzureCosmosFactory cosmosDBV3Repository, IKnowledgeService knowledgeService)
-        {
-            this.cosmosDBV3Repository = cosmosDBV3Repository;
-            this.knowledgeService = knowledgeService;
-        }
-
-
-        /// <summary>
-        /// 查询知识点
-        /// </summary>
-        /// <param name="request"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task FinKnowledge(Dict request, IServerStreamWriter<Knowledge> responseStream, ServerCallContext context)
-        {
-            Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
-            keyValuePairs = request.ToDict();
-            List<Knowledge> knowledges = await cosmosDBV3Repository.FindByDict<Knowledge>(keyValuePairs);
-            knowledges.ForEach(x =>
-            {
-                responseStream.WriteAsync(x);
-            });
-        }
-
-
-        /// <summary>
-        /// 保存知识点
-        /// </summary>
-        /// <param name="requestStream"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task SaveKnowledge(IAsyncStreamReader<Knowledge> requestStream, IServerStreamWriter<Knowledge> responseStream, ServerCallContext context)
-        {
-            //Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
-            //keyValuePairs = request.ToDict();
-            List<Knowledge> knowledges = new List<Knowledge>();
-            await foreach (var message in requestStream.ReadAllAsync())
-            {
-                knowledges.Add(message);
-            }
-
-            await knowledgeService.SaveOrUpdateKnowledge(knowledges);
-
-            knowledges.ForEach(x =>
-            {
-                responseStream.WriteAsync(x);
-            });
-        }
-
-
-        /// <summary>
-        /// 删除知识点
-        /// </summary>
-        /// <param name="listPid"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task<ListPid> DeleteKnowledge(ListPid listPid, ServerCallContext context)
-        {
-            List<IdPk> idPks = await knowledgeService.DeleteKnowledge(listPid.idPks);//await cosmosDBV3Repository.DeleteAll<Knowledge>(listPid.idPks);
-            listPid.idPks = idPks;
-            return listPid;
-        }
-
-    }
-}

+ 0 - 124
TEAMModelGrpc/Services/SyllabusService.cs

@@ -1,124 +0,0 @@
-using Grpc.Core;
-using Grpc.Extension.Abstract;
-using Microsoft.AspNetCore.Authorization;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using TEAMModelGrpc.Models;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-using TEAMModelOS.Service.Services.Interface;
-
-namespace TEAMModelGrpc.Services
-{
-    /// <summary>
-    /// 课纲业务
-    /// </summary>
-    public class SyllabusService : IGrpcService
-    {
-        private ISyllabusService syllabusService;
-        private AzureCosmosFactory cosmosDBV3Repository;
-        /// <summary>
-        /// 构造函数
-        /// </summary>
-        /// <param name="syllabusService"></param>
-        /// <param name="cosmosDBV3Repository"></param>
-        public SyllabusService(ISyllabusService syllabusService, AzureCosmosFactory cosmosDBV3Repository)
-        {
-            this.syllabusService = syllabusService;
-            this.cosmosDBV3Repository = cosmosDBV3Repository;
-        }
-
-
-        /// <summary>
-        /// 查找课纲 
-        /// </summary>
-        /// <param name="request"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task FindSyllabusTree(Dict request, IServerStreamWriter<SyllabusTreeDto> responseStream, ServerCallContext context) 
-        {
-            Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
-            keyValuePairs = request.ToDict();
-            List<SyllabusTree> knowledges = await syllabusService.Find(keyValuePairs);
-            List<SyllabusTreeDto> list = knowledges.ToJson().FromJson<List<SyllabusTreeDto>>();
-
-            list.ForEach(x =>
-            {
-                responseStream.WriteAsync(x);
-            });
-        }
-
-        /// <summary>
-        /// 按节点新增课纲
-        /// </summary>
-        /// <param name="requestStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        public async Task<Response> SaveOrUpdateAsNodes(IAsyncStreamReader<SyllabusNode> requestStream,  ServerCallContext context) 
-        {
-
-            List<SyllabusNode> syllabusNodes = new List<SyllabusNode>();
-            await foreach (SyllabusNode syllabusNode in requestStream.ReadAllAsync()) 
-            {
-                syllabusNodes.Add(syllabusNode);
-            }
-
-            await syllabusService.SaveOrUpdateAsNodes(syllabusNodes);
-            Response response = new Response();
-            return response.Success();
-        }
-
-        /// <summary>
-        ///  按树形新增课纲结构
-        /// </summary>
-        /// <param name="requestStream"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        public async Task SaveOrUpdateAsTree(IAsyncStreamReader<SyllabusTreeDto> requestStream, IServerStreamWriter<SyllabusTreeDto> responseStream, ServerCallContext context)
-        {
-
-            List<SyllabusTree> syllabusTrees = new List<SyllabusTree>();
-            List<SyllabusTreeDto> syllabusTreeDtos = new List<SyllabusTreeDto>();
-            await foreach (SyllabusTreeDto syllabusNode in requestStream.ReadAllAsync())
-            {
-                syllabusTreeDtos.Add(syllabusNode);
-                SyllabusTree syllabusTree = syllabusNode.ToJson().FromJson<SyllabusTree>();
-                syllabusTrees.Add(syllabusTree);
-            }
-            await syllabusService.SaveOrUpdateAsTree(syllabusTrees);
-
-            syllabusTreeDtos.ForEach(x => {
-                responseStream.WriteAsync(x);
-            });
-        }
-
-
-        /// <summary>
-        /// 删除课纲
-        /// </summary>
-        /// <param name="request"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task DeleteSyllabus(Dict request, IServerStreamWriter<SyllabusTreeDto> responseStream, ServerCallContext context)
-        {
-            Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
-            keyValuePairs = request.ToDict();
-            List<Syllabus> syllabuses = await syllabusService.DeleteSyllabus(keyValuePairs);//await cosmosDBV3Repository.DeleteAll<Knowledge>(listPid.idPks);
-            List<SyllabusTreeDto> syllabusTreeDtos = syllabuses.ToJson().FromJson<List<SyllabusTreeDto>>();
-
-            syllabusTreeDtos.ForEach(x => { 
-                responseStream.WriteAsync(x);
-            });
-        }
-
-
-    }
-}

+ 0 - 82
TEAMModelGrpc/Services/VolumeService.cs

@@ -1,82 +0,0 @@
-using Grpc.Core;
-using Grpc.Extension.Abstract;
-using Microsoft.AspNetCore.Authorization;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using TEAMModelGrpc.Models;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-using TEAMModelOS.Service.Services.Interface;
-
-namespace TEAMModelGrpc.Services
-{
-    public class VolumeService :IGrpcService
-    {
-        private readonly AzureCosmosFactory azureCosmosDBRepository;
-        private IVolumeService volumeService;
-
-        public VolumeService(AzureCosmosFactory azureCosmosDBRepository, IVolumeService volumeService)
-        {
-            this.azureCosmosDBRepository = azureCosmosDBRepository;
-            this.volumeService = volumeService;
-        }
-
-        /// <summary>
-        /// 保存册别
-        /// </summary>
-        /// <param name="requestStream"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task SaveOrUpdateVolume(IAsyncStreamReader<Volume> requestStream, IServerStreamWriter<Volume> responseStream, ServerCallContext context) {
-
-            List<Volume> volumes = new List<Volume>();
-            await foreach (Volume syllabusNode in requestStream.ReadAllAsync())
-            {
-                List<Volume> volume = await volumeService.SaveOrUpdateVolume(syllabusNode);
-                volumes.AddRange(volume);
-            }
-            volumes.ForEach(x => {
-                responseStream.WriteAsync(x);
-            });
-        }
-
-        /// <summary>
-        /// 查询册别
-        /// </summary>
-        /// <param name="request"></param>
-        /// <param name="responseStream"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task FindVolume(Dict request, IServerStreamWriter<Volume> responseStream, ServerCallContext context) {
-
-            Dictionary<string, object> dict = request.ToDict();
-
-            List<Volume> syllabusVolumes = await azureCosmosDBRepository.FindByDict<Volume>(dict);
-
-            syllabusVolumes.ForEach(x => { 
-                responseStream.WriteAsync(x);
-            });
-        }
-
-
-        /// <summary>
-        ///  删除册别
-        /// </summary>
-        /// <param name="listPid"></param>
-        /// <param name="context"></param>
-        /// <returns></returns>
-        [Authorize]
-        public async Task<ListPid> Delete(ListPid listPid, ServerCallContext context)
-        {
-            List<IdPk> idPks = await azureCosmosDBRepository.DeleteAll<Volume>(listPid.idPks);
-            listPid.idPks = idPks;
-            return listPid;
-        }
-
-    }
-}

+ 2 - 2
TEAMModelGrpc/Startup.cs

@@ -107,7 +107,7 @@ namespace TEAMModelGrpc
 
             app.UseEndpoints(endpoints =>
             {
-                endpoints.MapGrpcService<KnowledgeService>();
+                endpoints.MapGrpcService<HomeWorkService>();
                 endpoints.MapGrpcHealthChecksService();
                 endpoints.MapGet("/generateJwtToken", context =>
                 {
@@ -122,7 +122,7 @@ namespace TEAMModelGrpc
             //CodeFirst的Grpc(会自动扫描TStartup所在程序集下的IGrpcSerivce)
 
 
-            app.UseGrpcExtensions<TEAMModelGrpc.Services.KnowledgeService>(options =>
+            app.UseGrpcExtensions<TEAMModelGrpc.Services.HomeWorkService>(options =>
             {
                 //CodeFirst配制
                 options.GlobalPackage = "TMDGrpc";

+ 0 - 115
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -206,22 +206,6 @@
             数据状态
             </summary>
         </member>
-        <member name="M:TEAMModelGrpc.Services.BlobSASService.GetContainerSasUri(Google.Protobuf.WellKnownTypes.Empty,Grpc.Core.ServerCallContext)">
-            <summary>
-            获取bolb共享访问权限
-            </summary>
-            <param name="empty"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.BlobSASService.GetContainerSASRead(TEAMModelGrpc.Models.BlobSASDto,Grpc.Core.ServerCallContext)">
-            <summary>
-            获取blob共享访问权限 (只读)
-            </summary>
-            <param name="blob"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
         <member name="M:TEAMModelGrpc.Services.ClassroomService.SaveOrUpdateVolume(Grpc.Core.IAsyncStreamReader{TEAMModelOS.Service.Models.Classroom},Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Classroom},Grpc.Core.ServerCallContext)">
             <summary>
             保存教室
@@ -317,105 +301,6 @@
             <param name="context"></param>
             <returns></returns>
         </member>
-        <member name="M:TEAMModelGrpc.Services.KnowledgeService.FinKnowledge(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Knowledge},Grpc.Core.ServerCallContext)">
-            <summary>
-            查询知识点
-            </summary>
-            <param name="request"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.KnowledgeService.SaveKnowledge(Grpc.Core.IAsyncStreamReader{TEAMModelOS.Service.Models.Knowledge},Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Knowledge},Grpc.Core.ServerCallContext)">
-            <summary>
-            保存知识点
-            </summary>
-            <param name="requestStream"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.KnowledgeService.DeleteKnowledge(TEAMModelGrpc.Models.ListPid,Grpc.Core.ServerCallContext)">
-            <summary>
-            删除知识点
-            </summary>
-            <param name="listPid"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="T:TEAMModelGrpc.Services.SyllabusService">
-            <summary>
-            课纲业务
-            </summary>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.#ctor(TEAMModelOS.Service.Services.Interface.ISyllabusService,TEAMModelOS.SDK.DI.AzureCosmosFactory)">
-            <summary>
-            构造函数
-            </summary>
-            <param name="syllabusService"></param>
-            <param name="cosmosDBV3Repository"></param>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.FindSyllabusTree(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelGrpc.Models.SyllabusTreeDto},Grpc.Core.ServerCallContext)">
-            <summary>
-            查找课纲 
-            </summary>
-            <param name="request"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.SaveOrUpdateAsNodes(Grpc.Core.IAsyncStreamReader{TEAMModelOS.Service.Models.SyllabusNode},Grpc.Core.ServerCallContext)">
-            <summary>
-            按节点新增课纲
-            </summary>
-            <param name="requestStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.SaveOrUpdateAsTree(Grpc.Core.IAsyncStreamReader{TEAMModelGrpc.Models.SyllabusTreeDto},Grpc.Core.IServerStreamWriter{TEAMModelGrpc.Models.SyllabusTreeDto},Grpc.Core.ServerCallContext)">
-            <summary>
-             按树形新增课纲结构
-            </summary>
-            <param name="requestStream"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.SyllabusService.DeleteSyllabus(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelGrpc.Models.SyllabusTreeDto},Grpc.Core.ServerCallContext)">
-            <summary>
-            删除课纲
-            </summary>
-            <param name="request"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.VolumeService.SaveOrUpdateVolume(Grpc.Core.IAsyncStreamReader{TEAMModelOS.Service.Models.Volume},Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Volume},Grpc.Core.ServerCallContext)">
-            <summary>
-            保存册别
-            </summary>
-            <param name="requestStream"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.VolumeService.FindVolume(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Volume},Grpc.Core.ServerCallContext)">
-            <summary>
-            查询册别
-            </summary>
-            <param name="request"></param>
-            <param name="responseStream"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
-        <member name="M:TEAMModelGrpc.Services.VolumeService.Delete(TEAMModelGrpc.Models.ListPid,Grpc.Core.ServerCallContext)">
-            <summary>
-             删除册别
-            </summary>
-            <param name="listPid"></param>
-            <param name="context"></param>
-            <returns></returns>
-        </member>
         <member name="T:TEAMModelGrpc.GreetReflection">
             <summary>Holder for reflection information generated from Protos/greet.proto</summary>
         </member>

+ 5 - 5
TEAMModelOS.SDK/Context/Filters/HttpGlobalExceptionInvoke.cs

@@ -1,4 +1,4 @@
-
+
 using Microsoft.AspNetCore.Http;
 using System;
 using System.Threading.Tasks;
@@ -42,18 +42,18 @@ namespace TEAMModelOS.SDK.Context.Filter
                     bizCode = ((BizException)ex).code;
                     if (bizCode == 401 || bizCode == 404 || bizCode == 502 || bizCode == 403)
                     {
-                        context.Response.StatusCode = bizCode;
+                        //context.Response.StatusCode = bizCode;
                     }
                     else
                     {
-                        context.Response.StatusCode = 200;
+                      //  context.Response.StatusCode = 200;
                     }
                     // context.Response.StatusCode = ((BizException)ex).code;
                 }
                 //未知异常
                 else
                 {
-                    context.Response.StatusCode = 500;
+                    //context.Response.StatusCode = 500;
                     //LogHelper.SetLog(LogLevel.Error, ex);
                 }
                 await HandleExceptionAsync(context, bizCode, ex.Message, ex.StackTrace);
@@ -105,7 +105,7 @@ namespace TEAMModelOS.SDK.Context.Filter
         {
             if (context.Response.StatusCode == 500)
             {
-                context.Response.StatusCode = 200;
+               // context.Response.StatusCode = 200;
             }
             var data = new ErrorResponse<string>(bizCode, msg, devmsg);
             context.Response.ContentType = Constants.CONTENT_TYPE_JSON;

+ 19 - 19
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosExtensions.cs

@@ -26,19 +26,19 @@ namespace TEAMModelOS.SDK.DI
     public static class AzureCosmosExtensions
     {
         /// <summary>
-        /// 遣湔袟
+        /// 缓存前缀
         /// </summary>
         private const string CacheCosmosPrefix = "cosmos:";
         /// <summary>
-        /// ttl奀酗 1鏃
+        /// ttl时长 1秒
         /// </summary>
         private const int ttl = 1;
         /// <summary>
-        /// 煦珜湮苤
+        /// 分页大小
         /// </summary>
         private const int pageSize = 200;
         /// <summary>
-        /// 閉奀奀潔
+        /// 超时时间
         /// </summary>
         private const int timeoutSeconds = 86400;
         public static int RU(this Response response)
@@ -96,7 +96,7 @@ namespace TEAMModelOS.SDK.DI
              
             AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
             entity.pk = container.type.Name;
-            entity.ttl = null;
+            entity.ttl = -1;
             ItemResponse<T> response = await container.container.CreateItemAsync<T>(entity);
             if (container.cache && RedisHelper.Instance != null)
             {
@@ -132,7 +132,7 @@ namespace TEAMModelOS.SDK.DI
                 lists.ForEach(async x =>
                 {
                     x.pk = type.Name;
-                    x.ttl = null;
+                    x.ttl = -1;
                     MemoryStream stream = new MemoryStream();
                     await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
                     object o = type.GetProperty(partitionKey).GetValue(x, null);
@@ -173,7 +173,7 @@ namespace TEAMModelOS.SDK.DI
         {
             AzureCosmosModel container = await azureCosmosFactory. InitializeCollection<T>();
             entity.pk = container.type.Name;
-            entity.ttl = null;
+            entity.ttl = -1;
             ItemResponse<T> response = await container.container.UpsertItemAsync(item: entity);
             if (container.cache && RedisHelper.Instance != null)
             {
@@ -208,7 +208,7 @@ namespace TEAMModelOS.SDK.DI
                 lists.ForEach(async x =>
                 {
                     x.pk = type.Name;
-                    x.ttl = null;
+                    x.ttl = -1;
                     MemoryStream stream = new MemoryStream();
                     await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
                     object o = type.GetProperty(partitionKey).GetValue(x, null);
@@ -343,7 +343,7 @@ namespace TEAMModelOS.SDK.DI
             string partitionKey =AzureCosmosUtil.GetPartitionKey<T>();
             Type type = typeof(T);
             entity.pk = type.Name;
-            entity.ttl = null;
+            entity.ttl = -1;
             object o = type.GetProperty(partitionKey).GetValue(entity, null);
             ItemResponse<T> response = await container.container.ReplaceItemAsync(entity, entity.id, new PartitionKey(o.ToString()));
             if (container.cache && RedisHelper.Instance != null)
@@ -390,7 +390,7 @@ namespace TEAMModelOS.SDK.DI
                 lists.ForEach(async x =>
                 {
                     x.pk = type.Name;
-                    x.ttl = null;
+                    x.ttl = -1;
                     MemoryStream stream = new MemoryStream();
                     await JsonSerializer.SerializeAsync(stream, x, new JsonSerializerOptions { IgnoreNullValues = true });
                     object o = type.GetProperty(partitionKey).GetValue(x, null);
@@ -515,7 +515,7 @@ namespace TEAMModelOS.SDK.DI
             }
             else
             {
-                throw new BizException("統杅峈諾", 500);
+                throw new BizException("参数为空", 500);
             }
 
         }
@@ -525,15 +525,15 @@ namespace TEAMModelOS.SDK.DI
             string pk =AzureCosmosUtil. GetPartitionKey<T>();
             AzureCosmosModel container = await azureCosmosFactory.InitializeCollection<T>();
             List<IdPk> idPks = new List<IdPk>();
-            //log4net 祩??
+            //log4net 日志記錄
             string uuidKey = Guid.NewGuid().ToString();
-            string logkey = "\r\n▽" + uuidKey + "▼\r\n";
-            LogHelper.Info(default(object),
+            string logkey = "\r\n【" + uuidKey + "】\r\n";
+            LogHelper.Info(new object(),
                            logkey
-                           + "刉壺------->>\r\n"
-                           + "桶ㄩ"
+                           + "删除------->>\r\n"
+                           + "表:"
                            + type.Name + "\r\n"
-                           + "杅擂ㄩ"
+                           + "数据:"
                            + enyites.ToApiJson()
                            + "\r\n" + logkey);
             if (container.monitor)
@@ -606,7 +606,7 @@ namespace TEAMModelOS.SDK.DI
                 }
                 else
                 {
-                    throw new BizException("帤梑善ID饜腔杅擂ㄛ刉壺囮啖");
+                    throw new BizException("未找到ID匹配的数据,删除失败");
                 }
             }
             else
@@ -666,7 +666,7 @@ namespace TEAMModelOS.SDK.DI
             }
             else
             {
-                throw new BizException("脤戙統杅斛剕扢离 .pk ", ResponseCode.PARAMS_ERROR);
+                throw new BizException("查询参数必须设置 .pk ", ResponseCode.PARAMS_ERROR);
             }
         }
         /// <summary>

+ 2 - 2
TEAMModelOS.SDK/DI/AzureCosmos/Inner/ID.cs

@@ -1,4 +1,4 @@
-using System;
+using System;
 using System.Collections.Generic;
 using System.Text;
 using System.Text.Json.Serialization;
@@ -7,7 +7,7 @@ namespace TEAMModelOS.SDK.DI
 {
     public interface ID
     {
-        int? ttl { get; set; }
+        int? ttl { get; set; } 
         string pk { get; set; }
         string id { get; set; }
         string code { get; set; }

+ 1 - 1
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageBlobExtensions.cs

@@ -85,7 +85,7 @@ namespace TEAMModelOS.SDK.DI
             }
             byte[] bytes = System.Text.Encoding.Default.GetBytes(text);
             Stream streamBlob= new MemoryStream(bytes);
-            await blockBlob.UploadAsync(streamBlob);
+            await blockBlob.UploadAsync(streamBlob,true);
             blockBlob.SetHttpHeaders(new BlobHttpHeaders { ContentType = content_type });
             AzureBlobModel model = new AzureBlobModel(fileName, name, folder, fileName, folder, content_type, bytes.Length)
             {

+ 2 - 2
TEAMModelOS.Service/Models/SchoolInfo/Inner/Semester.cs

@@ -8,8 +8,8 @@ namespace TEAMModelOS.Service.Models
     {
         public string semesterName { get; set; }
         public string count { get; set; }
-        public string month { get; set; }
-        public string day { get; set; }
+        public int month { get; set; }
+        public int day { get; set; }
         public string semesterCode { get; set; }
     }
 }

+ 2 - 0
TEAMModelOS.Service/Models/SchoolInfo/Survey.cs

@@ -55,6 +55,8 @@ namespace TEAMModelOS.Service.Models
 
         public long sequenceNumber { get; set; }
 
+        public string url { get; set; }
+
     }
     public class Item {
         public string stem { get; set; }

+ 2 - 0
TEAMModelOS.Service/Models/SchoolInfo/Vote.cs

@@ -91,6 +91,8 @@ namespace TEAMModelOS.Service.Models
         public List<string> other { get; set; }
 
 
+        public string url { get; set; }
+
         /// <summary>
         /// 选项
         /// </summary>

+ 2 - 4
TEAMModelOS.Service/Models/StudentInfo/LearnRecord.cs

@@ -35,6 +35,8 @@ namespace TEAMModelOS.Service.Models
     public class RecordStep {
 
         public int index { get; set; }
+        public int count { get; set; }
+        public int score { get; set; }
         public RecordStep() {
             resource = new List<RecordRes>();
         }
@@ -69,9 +71,5 @@ namespace TEAMModelOS.Service.Models
         /// 作答时长
         /// </summary>
         public int costTime { get; set; } = 0;
-        /// <summary>
-        /// 作答次数
-        /// </summary>
-        public int count { get; set; } = 0;
     }
 }

+ 4 - 0
TEAMModelOS.Service/Models/TeacherInfo/LearnTask.cs

@@ -52,5 +52,9 @@ namespace TEAMModelOS.Service.Models
         /// 是否闯关模式 0不闯关,1 闯关
         /// </summary>
         public int stage { get; set; }
+        /// <summary>
+        /// 闯关模式的通关分数
+        /// </summary>
+        public int passScore { get; set; }
     }
 }

+ 0 - 15
TEAMModelOS.Service/Services/Analysis/Interfaces/IAchievementService.cs

@@ -1,15 +0,0 @@
-using System.Collections.Generic;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Analysis.Interfaces
-{
-    public interface IAchievementService : IBusinessService
-    {
-        List<Dictionary<string, object>> GetPR(List<ExamResult> exams, List<List<double>> subSum,List<Student> students);
-        Dictionary<string, object> GetAverage(List<ExamResult> exams,List<string> gav, List<string> cav, List<List<double>> subSum, List<Student> students);
-        List<List<string>> ReName(List<List<string>> datas, List<string> ids,
-        List<Dictionary<string, int[]>> classToName, List<Student> students);
-
-    }
-}

+ 0 - 13
TEAMModelOS.Service/Services/ChangeFeed/IChangeFeedService.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Services.ChangeFeed
-{
-    public interface IChangeFeedService<T>
-    {
-        void Processor(IReadOnlyCollection<T> changes);
-    }
-}

+ 0 - 10
TEAMModelOS.Service/Services/ChangeFeed/IChangeService.cs

@@ -1,10 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.Service.Services.ChangeFeed
-{
-    public  interface IChangeService
-    {
-    }
-}

+ 0 - 24
TEAMModelOS.Service/Services/ChangeFeed/KnowledgeChangeFeed.cs

@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Services.ChangeFeed
-{
-    public class KnowledgeChangeFeed : IChangeFeedService<Knowledge>, IChangeService
-    {
-        private AzureCosmosFactory cosmosDBV3Repository;
-        public KnowledgeChangeFeed(AzureCosmosFactory azureCosmos) {
-            cosmosDBV3Repository = azureCosmos;
-        }
-        public   void Processor(IReadOnlyCollection<Knowledge> changes)
-        {
-            //List<Knowledge> s = await cosmosDBV3Repository.FindAll<Knowledge>();
-            Console.WriteLine(DateTimeOffset.Now.UtcTicks +"    "+changes.ToApiJson());
-        }
-    }
-}

+ 0 - 23
TEAMModelOS.Service/Services/ChangeFeed/SyllabusVolumeChangeFeed.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Services.ChangeFeed
-{
-    public class SyllabusVolumeChangeFeed : IChangeFeedService<Volume>, IChangeService
-    {
-        private AzureCosmosFactory cosmosDBV3Repository;
-        public SyllabusVolumeChangeFeed(AzureCosmosFactory azureCosmos)
-        {
-            cosmosDBV3Repository = azureCosmos;
-        }
-        public void Processor(IReadOnlyCollection<Volume> changes)
-        {
-            Console.WriteLine(DateTimeOffset.Now.UtcTicks + "    "+changes.ToApiJson());
-        }
-    }
-}

+ 0 - 12
TEAMModelOS.Service/Services/Evaluation/Implements/EvaluatingService.cs

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

+ 0 - 9
TEAMModelOS.Service/Services/Evaluation/Interfaces/IEvaluatingService.cs

@@ -1,9 +0,0 @@
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Exam.Interfaces
-{
-    public interface IEvaluatingService : IBusinessService
-    {
-
-    }
-}

+ 0 - 13
TEAMModelOS.Service/Services/Evaluation/Interfaces/IHtmlAnalyzeService.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Services.Exam.Interfaces
-{
-    public interface IHtmlAnalyzeService: IBusinessService
-    {
-        List<Models.ItemInfo> AnalyzeWordAsync(string htmlString, string Lang);
-  
-    }
-}

+ 0 - 18
TEAMModelOS.Service/Services/Evaluation/Interfaces/IImportExerciseService.cs

@@ -1,18 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Services.Exam.Interfaces
-{
-    public interface IImportExerciseService: IBusinessService
-    {
-      
-
-        Task<Dictionary<string, object>> UploadWord(IFormFile file);
-
-    }
-}

+ 0 - 119
TEAMModelOS.Service/Services/Learn/Implements/ServiceBusReviceService.cs

@@ -1,119 +0,0 @@
-using Microsoft.Azure.ServiceBus;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Text.Json;
-using System.Threading;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.SDK.Module.AzureServiceBus;
-using TEAMModelOS.Service.Models;
-using TEAMModelOS.Service.Services.Learn.Interfaces;
-
-namespace TEAMModelOS.Service.Services.Learn.Implements
-{
-    public class ServiceBusReviceService : IServiceBusReviceService
-    {
-        private readonly IAzureServiceBusService _serviceBus;
-        private readonly AzureCosmosFactory _cosmos;
-        private static ISubscriptionClient subscriptionClient;
-        public ServiceBusReviceService(IAzureServiceBusService azureServiceBus, AzureCosmosFactory cosmos)
-        {
-            _serviceBus = azureServiceBus;
-            _cosmos = cosmos;
-        }
-
-        public   void ReciveMessageAsync()
-        {
-            string SubName = "test_topic_ReciveTask";
-            subscriptionClient = _serviceBus.GetSubClient(SubName).subscriptionClient;
-            RegisterOnMessageHandlerAndReceiveMessages();
-          //  await subscriptionClient.CloseAsync();
-            //return "";
-        }
-        public void RegisterOnMessageHandlerAndReceiveMessages()
-        {
-            // Configure the message handler options in terms of exception handling, number of concurrent messages to deliver, etc.
-            var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
-            {
-                // Maximum number of concurrent calls to the callback ProcessMessagesAsync(), set to 1 for simplicity.
-                // Set it according to how many messages the application wants to process in parallel.
-                MaxConcurrentCalls = 1,
-
-                // Indicates whether MessagePump should automatically complete the messages after returning from User Callback.
-                // False below indicates the Complete will be handled by the User Callback as in `ProcessMessagesAsync` below.
-                AutoComplete = false
-            };
-            subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
-
-        }
-        public async Task ProcessMessagesAsync(Message message, CancellationToken token)
-        {
-            // Process the message.
-            Console.WriteLine($"Received message: SequenceNumber:{message.SystemProperties.SequenceNumber} Body:{Encoding.UTF8.GetString(message.Body)}");
-
-            // Complete the message so that it is not received again.
-            // This can be done only if the subscriptionClient is created in ReceiveMode.PeekLock mode (which is the default).
-            await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
-            Dictionary<string, object> dict = Encoding.UTF8.GetString(message.Body).FromApiJson<Dictionary<string, object>>();
-            Dictionary<string, object> obj = new Dictionary<string, object>();
-            dict.TryGetValue("id", out object id);
-            dict.TryGetValue("pk", out object pk);
-            dict.TryGetValue("name", out object name);
-            dict.TryGetValue("status", out object status);
-            if (name != null && id!=null && pk!=null && status!=null ) {
-                if (name.ToString() == typeof(Homework).Name) {
-                    Homework data= await   _cosmos.FindByIdPk<Homework>(id.ToString(), pk.ToString());
-                    data.status = int.Parse(status.ToString());
-                    await _cosmos.Update(data);
-                }
-                if (name.ToString() == typeof(Vote).Name)
-                {
-                    Vote data = await _cosmos.FindByIdPk<Vote>(id.ToString(), pk.ToString());
-                    data.status = int.Parse(status.ToString());
-                    await _cosmos.Update(data);
-                }
-                if (name.ToString() == typeof(Survey).Name)
-                {
-                    Survey data= await _cosmos.FindByIdPk<Survey>(id.ToString(), pk.ToString());
-                    data.status = int.Parse(status.ToString());
-                    await _cosmos.Update(data);
-                }
-                if (name.ToString() == typeof(ExamInfo).Name)
-                {
-                    ExamInfo data= await _cosmos.FindByIdPk<ExamInfo>(id.ToString(), pk.ToString());
-                    data.status = int.Parse(status.ToString());
-                    await _cosmos.Update(data);
-                }
-                if (name.ToString() == typeof(LearnTask).Name)
-                {
-                    LearnTask data = await _cosmos.FindByIdPk<LearnTask>(id.ToString(), pk.ToString());
-                    data.status = int.Parse(status.ToString());
-                    await _cosmos.Update(data);
-                }
-            }
-           
-            //return message;
-
-            // Note: Use the cancellationToken passed as necessary to determine if the subscriptionClient has already been closed.
-            // If subscriptionClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
-            // to avoid unnecessary exceptions.
-        }
-
-        public static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
-        {
-            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
-            var context = exceptionReceivedEventArgs.ExceptionReceivedContext;
-            Console.WriteLine("Exception context for troubleshooting:");
-            Console.WriteLine($"- Endpoint: {context.Endpoint}");
-            Console.WriteLine($"- Entity Path: {context.EntityPath}");
-            Console.WriteLine($"- Executing Action: {context.Action}");
-            return Task.CompletedTask;
-        }
-    }
-}

+ 0 - 46
TEAMModelOS.Service/Services/Learn/Implements/TimerWorkService.cs

@@ -1,46 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Services.Learn.Interfaces;
-
-namespace TEAMModelOS.Service.Services.Learn.Implements
-{
-    public class TimerWorkService: ITimerWorkService
-    {
-        private readonly AzureCosmosFactory _cosmos;
-
-        public TimerWorkService(AzureCosmosFactory cosmos)
-        {
-            _cosmos = cosmos;
-        }
-
-        public void TimerWork<T>(long startTime, int status , Dictionary<string, object> dict) where T : ID
-        {
-            System.Timers.Timer aTimer = new System.Timers.Timer();
-            // Create a timer with a two second interval.
-            long time = Math.Abs(startTime - new DateTimeOffset(DateTime.UtcNow).ToUnixTimeMilliseconds());
-            aTimer = new System.Timers.Timer(time);
-            // Hook up the Elapsed event for the timer. 
-            aTimer.Elapsed += async (sender, e) => await OnTimedEventAsync<T>(_cosmos,status, dict);
-            aTimer.AutoReset = false;
-            aTimer.Enabled = true;
-        }
-
-        public static async Task OnTimedEventAsync<T>(AzureCosmosFactory _cosmos, int status, Dictionary<string, object> dict) where T : ID
-        {
-            List<T> homeWorks = await _cosmos.FindByDict<T>(dict);
-            if (homeWorks.IsNotEmpty())
-            {
-                PropertyInfo propertyInfo = homeWorks[0].GetType().GetProperty("status");
-                for (int i = 0; i < homeWorks.Count; i++)
-                    propertyInfo.SetValue(homeWorks[i], status);
-                await _cosmos.SaveOrUpdateAll<T>(homeWorks);
-
-            }
-        }
-    }
-}

+ 0 - 14
TEAMModelOS.Service/Services/Learn/Interfaces/IServiceBusReviceService.cs

@@ -1,14 +0,0 @@
-using Microsoft.Extensions.Hosting;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Services.Learn.Interfaces
-{
-    public interface IServiceBusReviceService
-    {
-        public void ReciveMessageAsync();
-    }
-}

+ 0 - 16
TEAMModelOS.Service/Services/Learn/Interfaces/IServiceBusService.cs

@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-
-namespace TEAMModelOS.Service.Services.Learn.Interfaces
-{
-    public interface IServiceBusService : IBusinessService
-    {
-        public Task<long> SendMessage<T>(string TopicName, string id, string pk, long startTime,int status,string msgId);
-
-  
-
-    }
-}

+ 0 - 13
TEAMModelOS.Service/Services/Learn/Interfaces/ITimerWorkService.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.DI;
-
-namespace TEAMModelOS.Service.Services.Learn.Interfaces
-{
-    public interface ITimerWorkService : IBusinessService
-    {
-        public void TimerWork<T>(long startTime, int status,Dictionary<string, object> dict ) where T : ID;
-    }
-}

+ 0 - 16
TEAMModelOS.Service/Services/PowerPoint/Interface/IHtexService.cs

@@ -1,16 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.Service.Model.PowerPoint;
-
-namespace TEAMModelOS.Service.Services.PowerPoint.Interface
-{
-    public interface IHtexService : IBusinessService
-    {
-        Task<Dictionary<string, object>> LoadDoc(IFormFile file);
-        Task<Htex> AnalyzeHtmlToHtex(string htmlString, string Lang);
-    }
-}

+ 0 - 17
TEAMModelOS.Service/Services/Syllabus/Interface/IKnowledgeService.cs

@@ -1,17 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Services.Interface
-{
-    public interface IKnowledgeService : IBusinessService
-    {
-        public Task<List<Knowledge>> SaveOrUpdateKnowledge(List<Knowledge> request);
-
-        public Task<List<IdPk>> DeleteKnowledge(List<IdPk> listPid);
-    }
-}

+ 0 - 34
TEAMModelOS.Service/Services/Syllabus/Interface/ISyllabusService.cs

@@ -1,34 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.DI;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Services.Interface
-{
-    public interface ISyllabusService : IBusinessService
-    {
-
-        /// <summary>
-        /// 查找课纲 
-        /// </summary>
-        /// <param name="request"></param>
-        /// <returns></returns>
-        public Task<List<SyllabusTree>> Find(Dictionary<string, object> request);
-
-        /// <summary>
-        /// 保存或者修改课纲
-        /// </summary>
-        /// <param name="syllabusNodes"></param>
-        /// <returns></returns>
-        public Task<List<Syllabus>> SaveOrUpdateAsNodes(List<SyllabusNode> syllabusNodes);
-
-        public Task<List<SyllabusTree>> SaveOrUpdateAsTree(List<SyllabusTree> request);
-
-        public Task<List<Syllabus>> DeleteSyllabus(Dictionary<string, object> request);
-
-
-    }
-}

+ 0 - 16
TEAMModelOS.Service/Services/Syllabus/Interface/IVolumeService.cs

@@ -1,16 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.Service.Models;
-
-namespace TEAMModelOS.Service.Services.Interface
-{
-    public interface IVolumeService : IBusinessService
-    {
-
-        public  Task<List<Volume>> SaveOrUpdateVolume(Volume request);
-
-    }
-}

File diff suppressed because it is too large
+ 5 - 1974
TEAMModelOS.Service/TEAMModelOS.Model.xml


+ 3 - 0
TEAMModelOS.Service/TEAMModelOS.Service.csproj

@@ -14,4 +14,7 @@
   <ItemGroup>
     <PackageReference Include="protobuf-net" Version="2.4.6" />
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Services\Analysis\" />
+  </ItemGroup>
 </Project>

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

@@ -29,6 +29,10 @@ export default {
     deletePlan: function (data) {
         return post('/api/Course/deletePlan', data)
     },
+    //删除一节课的安排
+    deleteTime: function (data) {
+        return post('/api/Course/deleteTime', data)
+    },
     //获取教室关联的学生
     getClassroomStudent: function (data) {
         return post('/api/ClassStudent/find', data)

+ 50 - 0
TEAMModelOS/ClientApp/src/api/forgetPW.js

@@ -0,0 +1,50 @@
+import { corePost } from '@/filters/http'
+import config from '@/store/module/config'
+import jwtDecode from 'jwt-decode'
+
+export default {
+/**
+ * 重置密碼
+ * @param {String} applyType - 寄信類型(email, phone)
+ * @param {String} name - 姓名
+ * @param {String} account - 驗證帳號
+ * @param {String} pw - 密碼
+ * @param {String} country - 手機區碼,無須+號(有phone為必填)
+ * @param {String} pinCode - 驗證碼
+ */
+restPW: function(item)   {
+    return new Promise((resolve) => {
+        let srvAdr = localStorage.getItem('srvAdr')
+        let url = config.state[srvAdr].coreAPIUrl
+        let nonceStr = 'habook'  // 檢查項目
+        let data = {
+            "grant_type": "reset",
+            'client_id': config.state[srvAdr].clientID,
+            'nonce': nonceStr,
+            "password": item.pw,
+            "pin_code": item.pinCode.toString()
+        }
+
+        if(item.applyType == 'phone'){
+            data.account = '+' + item.country + '-' + item.account
+        } else {
+            data.account = item.account
+        }
+
+        corePost(url+'/oauth2/login', data).then( res => {
+            if(res.error){
+                resolve(res)
+            } else {
+            let t_data = jwtDecode(res.id_token)
+            if(nonceStr === t_data.nonce){
+                resolve(res)
+            } else {
+                resolve({error: 'nonce'})
+            }
+            }
+        },err => {
+            console.log(err)
+        })
+    })
+  },
+}

+ 2 - 0
TEAMModelOS/ClientApp/src/api/index.js

@@ -20,6 +20,7 @@ import teachMgmt from './teachMgmt'
 import schoolUser from './schoolUser'
 import accessToken from './accessToken'
 import regist from './regist'
+import forgetPW from './forgetPW'
 export default {
     accessToken,
     learnActivity,
@@ -41,6 +42,7 @@ export default {
     teachMgmt,
     schoolUser,
     regist,
+    forgetPW,
     // 获取登录跳转链接
     getLoginLink: function (data) {
         return post('api/login/login', data)

+ 41 - 42
TEAMModelOS/ClientApp/src/api/regist.js

@@ -3,50 +3,49 @@ import config from '@/store/module/config'
 import jwtDecode from 'jwt-decode'
 
 export default {
+/**
+ * 註冊帳號
+ * @param {String} applyType - 寄信類型(email, phone)
+ * @param {String} name - 姓名
+ * @param {String} account - 驗證帳號
+ * @param {String} pw - 密碼
+ * @param {String} country - 手機區碼,無須+號(有phone為必填)
+ * @param {String} pinCode - 驗證碼
+ */
+crtAccount: function(item)   {
+    return new Promise((resolve) => {
+      let srvAdr = localStorage.getItem('srvAdr')
+      let url = config.state[srvAdr].coreAPIUrl
+      let nonceStr = 'habook'  // 檢查項目
+      let data = {
+        "grant_type": "create",
+        'client_id': config.state[srvAdr].clientID,
+        'nonce': nonceStr,
+        "name" : item.name,
+        "password": item.pw,
+        "pin_code": item.pinCode.toString()
+      }
 
-    /**
-     * 註冊帳號
-     * @param {String} applyType - 寄信類型(email, phone)
-     * @param {String} name - 姓名
-     * @param {String} account - 驗證帳號
-     * @param {Stringn} pw - 密碼
-     * @param {String} country - 手機區碼,無須+號(有phone為必填)
-     * @param {String} pinCode - 驗證碼
-     */
-    crtAccount: function(item)   {
-        return new Promise((resolve) => {
-          let srvAdr = localStorage.getItem('srvAdr')
-          let url = config.state[srvAdr].coreAPIUrl
-          let nonceStr = 'habook'  // 檢查項目
-          let data = {
-            "grant_type": "create",
-            'client_id': config.state[srvAdr].clientID,
-            'nonce': nonceStr,
-            "name" : item.name,
-            "password": item.pw,
-            "pin_code": item.pinCode.toString()
-          }
+      if(item.applyType == 'phone'){
+          data.account = '+' + item.country + '-' + item.account
+      } else {
+        data.account = item.account
+      }
 
-          if(item.applyType == 'phone'){
-              data.account = '+' + item.country + '-' + item.account
+      corePost(url+'/oauth2/login', data).then( res => {
+        if(res.error){
+          resolve(res)
+        } else {
+          let t_data = jwtDecode(res.id_token)
+          if(nonceStr === t_data.nonce){
+            resolve(res)
           } else {
-            data.account = item.account
+            resolve({error: 'nonce'})
           }
-
-          corePost(url+'/oauth2/login', data).then( res => {
-            if(res.error){
-              resolve(res)
-            } else {
-              let t_data = jwtDecode(res.id_token)
-              if(nonceStr === t_data.nonce){
-                resolve(res)
-              } else {
-                resolve({error: 'nonce'})
-              }
-            }
-          },err => {
-            console.log(err)
-          })
-        })
-      },
+        }
+      },err => {
+        console.log(err)
+      })
+    })
+  },
 }

+ 24 - 11
TEAMModelOS/ClientApp/src/common/BaseMock.vue

@@ -30,8 +30,8 @@
 				isLoading: false,
 				acType: 0,
                 acId: '5ed79799-4e2d-471e-a484-deedb81a8ad7',
-                orderLearnId: 'b910aed3-c981-40c7-9753-edebb803999e',
-				unitId:'c223e06a-7ee7-4d09-b5b9-d8c7debdcf26'
+    //            orderLearnId: 'b910aed3-c981-40c7-9753-edebb803999e',
+				//unitId:'c223e06a-7ee7-4d09-b5b9-d8c7debdcf26'
 			};
 		}, 
 		created() {},
@@ -53,11 +53,9 @@
 							this.doMockEvaluation(this.acId)
 							break
                         case 4:
-                            this.acId = this.orderLearnId
 							this.doMockSelfLearning(this.acId)
                             break	
                         case 5:
-                            this.acId = this.unitId
 							this.doMockSelfLearning(this.acId)
 							break	
 						default:
@@ -176,16 +174,19 @@
                                 code: item.code,
                                 steps: []
                             }
-                            for (let index in acInfo[0].steps) {
+                            let compSteps = this.$jsFn.getBtwRandom(0, (acInfo[0].steps.length + 1))
+                            for (let index = 0; index < compSteps; index++) {
                                 let aswItem = {
                                     index: parseInt(index),
+									count:this.$jsFn.getBtwRandom(1,4),
+									score:this.$jsFn.getBtwRandom(50,100),
                                     answer: []
                                 }
                                 acInfo[0].steps[index].item.forEach((question, i) => {
                                     let stItem = {
                                         index: i,
                                         ans: this.randomAnswer(question),
-										count: this.$jsFn.getBtwRandom(0,5)
+										//count: this.$jsFn.getBtwRandom(0,5)
                                     }
                                     aswItem.answer.push(stItem)
                                 })
@@ -193,7 +194,6 @@
                             }
                             result.push(rdItem)
                         }
-						console.log(result)
                         this.$api.learnActivity.upsertRecord(result).then(
                             (res) => {
                                 if (!res.error && res.result.data) {
@@ -217,7 +217,6 @@
                     let students = await this.getStudentList(classes)
                     for (let item of students) {
                         let radom = this.$jsFn.getBtwRandom(0, 2)
-                        console.log('random:' + radom)
                         if (radom) {
                             let rdItem = {
                                 id: this.acId,
@@ -280,6 +279,7 @@
 						submitTime: new Date(Mock.mock('@datetime')).getTime()
 					})
 				})
+				console.log(result)
 				// 保存模拟数据
 				this.$api.learnActivity.SaveVoteRecords(result).then(res => {
 					if (!res.error && res.result.data) {
@@ -356,9 +356,22 @@
 				return new Promise((r, j) => {
 					this.$api.learnActivity.FindVote({
 						id: id
-					}).then(res => {
+					}).then(async res => {
 						if (!res.error && res.result.data) {
-							r(res.result.data[0])
+							let privateSas = await this.$tools.getPrivateSas()
+							let schoolSas = await this.$tools.getSchoolSas()
+							let i = res.result.data[0]
+							if (i.url) {
+								let sasString = i.code === this.$store.state.userInfo.TEAMModelId ? privateSas : schoolSas 
+								let jsonInfo = await this.$tools.getFile(i.url + sasString.sas)
+								let jsonData = JSON.parse(jsonInfo)
+								jsonData.id = i.id
+								jsonData.fileName = i.url.split('/')[i.url.split('/').length - 1].split('.json')[0]
+								r(jsonData)
+								console.log(jsonData)
+							}else{
+								r(i)
+							}
 						} else {
 							j(500)
 						}
@@ -503,7 +516,7 @@
 			},
 			
 			/* 根据题型生成随机答案 */
-			randomAnswer(item) {
+            randomAnswer(item) {
 				switch (item.type) {
 					case 'Single':
 						return [item.option[Math.floor(Math.random() * item.option.length)].code]

+ 4 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.less

@@ -29,6 +29,10 @@
         border: none;
         height: 38px;
     }
+	
+	.ivu-form textarea{
+		height: 150px;
+	}
 
     .ivu-input::-webkit-input-placeholder {
         color: #939393;

+ 8 - 7
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwForm.vue

@@ -36,7 +36,8 @@
             </FormItem>
 
             <FormItem label="作业描述" prop="description">
-                <div ref="descriptionEditor" style="text-align:left" v-show="hwFormEdit"></div>
+                <!-- <div ref="descriptionEditor" style="text-align:left" v-show="hwFormEdit"></div> -->
+				<Input v-model="hwForm.description" type="textarea" placeholder="" :class="!hwFormEdit ? 'hw-form-disabled':''" v-show="hwFormEdit"/>
                 <div v-html="hwForm.description" v-show="!hwFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff"></div>
                 <!--<Input v-model="hwForm.description" type="textarea" :autosize="{minRows: 2,maxRows: 5}" placeholder="请输入作业内容描述">--></Input>
             </FormItem>
@@ -325,7 +326,7 @@
                 this.currentState = item.state
                 this.defaultFileList = item.resource
                 this.defaultFileList = JSON.parse(JSON.stringify(item.resource))
-                this.descriptionEditor.txt.html(item.description)
+                // this.descriptionEditor.txt.html(item.description)
                 //this.uploadFileList = item.resource.length ? item.resource : []
             },
 
@@ -350,11 +351,11 @@
 
 
             /** 初始化作业详情的富文本编辑器 */
-            let descriptionEditor = new E(this.$refs.descriptionEditor)
-            descriptionEditor.customConfig = this.defaultConfig
-            descriptionEditor.customConfig.onchange = (html) => { this.hwForm.description = html }
-            descriptionEditor.create()
-            this.descriptionEditor = descriptionEditor
+            // let descriptionEditor = new E(this.$refs.descriptionEditor)
+            // descriptionEditor.customConfig = this.defaultConfig
+            // descriptionEditor.customConfig.onchange = (html) => { this.hwForm.description = html }
+            // descriptionEditor.create()
+            // this.descriptionEditor = descriptionEditor
         },
         watch: {
             editItem: {

+ 5 - 3
TEAMModelOS/ClientApp/src/components/learnactivity/BaseHwTable.vue

@@ -324,7 +324,7 @@
             }
         },
         created() {
-            this.getSasStr()
+            // this.getSasStr()
         },
         methods: {
             /**
@@ -497,8 +497,10 @@
              * @param blobUrl
              */
             onDownloadFile(downloadList) {
-                downloadList.forEach(item => {
-                    window.location.href = item + this.sasString
+                downloadList.forEach(async item => {
+					let fileSas = await this.$tools.getFileSas(item)
+					console.log(fileSas)
+                    window.location.href = item + '?' +  fileSas.sas
                 })
             },
 

+ 34 - 13
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.vue

@@ -69,6 +69,7 @@
 </template>
 <script>
     import E from 'wangeditor'
+	import uploadFile from '@/utils/upload.js'
     import UploadFile from '@/common/UploadFile.vue'
     export default {
         props: {
@@ -120,6 +121,7 @@
                     name: "",
                     target: [],
                     publishModel: "0",
+					status:100,
                     startTime: 0,
                     endTime: 0,
                     resource: []
@@ -150,11 +152,12 @@
              * 提交新增投票表单
              * @param name FormName
              */
-            handleSubmit(name) {
-                this.$refs[name].validate((valid) => {
+            async handleSubmit(name) {
+                this.$refs[name].validate(async (valid) => {
                     if (valid && this.getSimpleText(this.hwForm.description) && this.voteOptionsContent.length) {
                         let params = Object.assign({}, this.defaultParams)
                         let target = []
+						let fileName = this.$tools.guid()
                         let isReset = this.hwForm.isReset.length > 0
                         params.code = this.hwForm.code,
                         params.name = this.hwForm.name
@@ -168,8 +171,9 @@
                         params.option = this.voteOptionsContent
                         if (this.isEdit && this.editInfo.id) {
                             params.id = this.editInfo.id
+							fileName = this.editInfo.fileName
                         }
-
+						console.log(this.hwForm)
                         /** 替换投票对象格式 */
                         this.hwForm.target.forEach(item => {
                             target.push({
@@ -178,15 +182,31 @@
                             })
                         })
                         params.target = target
-                        this.isBtnLoading = true
-                        this.SaveorUpdataVote({ vote: params, reset: isReset }).then(res => {
-                            this.$Message.success((this.isEdit && this.editInfo.id) ? '修改成功!' : '添加成功!')
-                            this.$emit('onAddSuccess')
-                            this.isBtnLoading = false
-                        }).catch(error => {
-                            this.isBtnLoading = false
-                            console.log(error)
-                        })
+						console.log(fileName)
+						/* 保存BLOB以及COSMOS */
+						// 首先保存新题目的JSON文件到Blob 然后返回URL链接
+						let file = new File([JSON.stringify(params)], fileName + ".json", {type: ""});
+						// 根据题目类型 传到不同容器
+						let fileType = params.code === this.$store.state.userInfo.TEAMModelId ? 'private' : 'school'
+						// 等待上传blob的返回结果
+						let blobFile = await uploadFile.uploadFile(file,'vote',fileType)
+						if(blobFile.blobUrl){
+							// 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
+							params.url = blobFile.blobUrl
+							delete params.option
+							delete params.description
+							this.isBtnLoading = true
+							console.log(params)
+							this.SaveorUpdataVote({ vote: params, reset: isReset }).then(res => {
+							    this.$Message.success((this.isEdit && this.editInfo.id) ? '修改成功!' : '添加成功!')
+							    this.$emit('onAddSuccess')
+							    this.isBtnLoading = false
+							}).catch(error => {
+							    this.isBtnLoading = false
+							    console.log(error)
+							})
+						}
+                        
                     } else {
                         this.$Message.error('请将信息填写完整')
                     }
@@ -444,7 +464,8 @@
                         this.editInfo = null
                     }
                 },
-                deep: true
+                deep: true,
+				// immediate:true
             }
         }
     }

+ 4 - 1
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVotePie.vue

@@ -115,7 +115,9 @@
 
                 // 绘制图表
                 myPie.setOption(option)
-
+				this.$nextTick(()=>{
+					myPie.resize()
+				})
                 window.addEventListener('resize', function () {
                     myPie.resize()
                 })
@@ -145,6 +147,7 @@
                 deep: true,
                 handler(val) {
                     if (val.length) {
+						console.log("11111111111111111")
                         this.noChooseNum = val.filter(item => item.key === '').length ? val.filter(item => item.key === '')[0].result.length : 0
                         let sum = 0
                         val.forEach(item => {

+ 20 - 7
TEAMModelOS/ClientApp/src/components/learnactivity/ChooseContent.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="choose-content">
-        <Tabs type="card" name="chooseContent">
+        <Tabs type="card" name="chooseContent" @on-click="checkCurTab">
             <!-- 选择课纲内容 -->
-            <TabPane label="课纲" v-if="showSyllabus"  tab="chooseContent">
+            <TabPane label="课纲" name="syllabus" v-if="showSyllabus"  tab="chooseContent">
                 <div class="tab-wrap">
                     <div class="content-filter-wrap">
                         <div class="content-filter-item">
@@ -54,7 +54,7 @@
                 </div>
             </TabPane>
             <!-- 选择资源文件 -->
-            <TabPane label="内容" v-if="showContent" tab="chooseContent">
+            <TabPane label="内容" name="content" v-if="showContent" tab="chooseContent">
                 <div class="tab-wrap">
                     <div class="content-filter-wrap">
                         <div class="content-filter-item">
@@ -103,7 +103,7 @@
                 </div>
             </TabPane>
             <!-- 选择题库 -->
-            <TabPane label="题目" v-if="showQuestion" tab="chooseContent">
+            <TabPane label="题目" name="question" v-if="showQuestion" tab="chooseContent">
                 <div class="tab-wrap">
                     <vuescroll>
                         <Row class="question-filter-wrap">
@@ -179,7 +179,7 @@
                 </div>
             </TabPane>
             <!-- 补充内容 -->
-            <TabPane label="补充内容" v-if="showOther"  tab="chooseContent">
+            <TabPane label="补充内容" name="other" v-if="showOther"  tab="chooseContent">
                 <div class="tab-wrap dark-wang-editor dark-iview-input" style="padding:10px;">
                     <p class="label-name" style="margin-top:0px;">文字描述:</p>
                     <div ref="courseNotice"></div>
@@ -301,6 +301,20 @@
             }
         },
         methods: {
+            checkCurTab(name) {
+                switch (name) {
+                    case 'question':
+                        this.getResultCount()
+                        this.queryQuestionByPage()
+                        break
+                    default:
+                        break
+                }
+            },
+            //getQuestions() {
+            //    this.getResultCount()
+            //    this.queryQuestionByPage()
+            //},
             /**
              * 初始化富文本编辑器
              * */
@@ -719,8 +733,7 @@
             Date.prototype.toLocaleString = function () {
                 return this.getFullYear() + "/" + (this.getMonth() + 1) + "/" + this.getDate();
             }
-            this.getResultCount()
-            this.queryQuestionByPage()
+            
         }
     }
 </script>

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

@@ -144,6 +144,7 @@
 				return new Promise((resolve, reject) => {
 					this.$refs[name].validate((valid) => {
 						if (valid && this.getSimpleText(this.qnForm.description)) {
+							console.log(this.qnForm)
 							let params = Object.assign({}, this.defaultParams)
 							let target = []
 							params.code = this.userInfo.schoolCode
@@ -157,12 +158,13 @@
 							if (this.isEdit && this.editInfo.id) {
 								params.id = this.editInfo.id
 								params.createTime = this.editInfo.createTime
+								params.fileName = this.editInfo.fileName
 							}
 							/** 替换问卷对象格式 */
 							this.qnForm.target.forEach(item => {
 								target.push({
-									classroomCode: item.classroomCode,
-									classroomName: this.classRooms.filter(i => i.classroomCode === item.classroomCode)[0].classroomName
+									classroomCode: item,
+									classroomName: this.classRooms.filter(i => i.classroomCode === item)[0].classroomName
 								})
 							})
 							params.target = target

+ 8 - 2
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue

@@ -54,7 +54,7 @@
 							  </div>
 						</transition>
 						<!-- 工具栏 -->
-						<div class="qn-tools">
+						<div class="qn-tools" v-show="editable">
 							<div class="qn-tools-item" @click="onItemEdit(item,index)">
 								<Icon type="md-create" />
 								<span>编辑</span>
@@ -94,13 +94,14 @@
 			BaseAddItem,
 			BaseQnBar
 		},
-		props: ["editItem"],
+		props: ["editItem","isEdit"],
 		data() {
 			return {
 				curIndexList:[],
 				curItem:null,
 				barData:[],
 				editIndex:null,
+				editable:false,
 				isShowAnalysis:false,
 				isShowAllAnalysis:false,
 				addModal: false,
@@ -260,6 +261,11 @@
 				},
 				deep: true,
 				immediate: true
+			},
+			isEdit:{
+				handler(n,o){
+					this.editable = n
+				}
 			}
 		}
 	};

+ 29 - 7
TEAMModelOS/ClientApp/src/css/disabled-iview-form.less

@@ -26,19 +26,41 @@
         color: white;
     }
 
-    .ivu-select-multiple .ivu-tag{
-        background:#606060;
-        border:none;
+    .ivu-select-multiple .ivu-tag {
+        background: #606060;
+        border: none;
     }
-}
-.disabled-iview-select {
+
     .ivu-input[disabled] {
         border: none;
         background: none !important;
         font-size: 16px !important;
     }
 
-    .ivu-select-disabled .ivu-select-selection{
-        background:none;
+    .ivu-select-disabled .ivu-select-selection {
+        background: none;
     }
 }
+.disabled-iview-input {
+    .ivu-input-disabled {
+        border: none;
+        background: none !important;
+        font-size: 16px !important;
+    }
+
+    .ivu-disabled .ivu-selection {
+        background: none;
+    }
+}
+
+
+.disabled-iview-inputnumber {
+    .ivu-input-number-disabled .ivu-input-number-input {
+        text-align: center;
+        color:white;
+    }
+
+    .ivu-input-number-disabled {
+        border: none;
+    }
+} 

+ 33 - 30
TEAMModelOS/ClientApp/src/router/routes.js

@@ -35,6 +35,19 @@ export const routes = [
             }
         ]
     },
+    {
+        path: '/forgotpw', component: FrontEndMain,
+        children: [
+            {
+                name: 'forgotpw',
+                path: '/',
+                meta: {
+                    middleware: ['login?']
+                },
+                component: resolve => require(['@/view/forgotPw/Index.vue'], resolve)
+            }
+        ]
+    },
     {
         path: '/schoolList',
         component: Home,
@@ -196,20 +209,15 @@ export const routes = [
                         path: 'createCompose',
                         name: 'createCompose',
                         component: resolve => require(['@/view/evaluation/index/CreateCompose.vue'], resolve)
-                    },
-                    {
-                        path: 'editChild',
-                        name: 'editChild',
-                        component: resolve => require(['@/view/evaluation/index/EditChild.vue'], resolve)
                     }
                 ]
             },
             //个人课程管理(废弃)
-            {
-                path: 'courseManage',
-                name: 'courseManage',
-                component: resolve => require(['@/view/coursemgmt/CourseManage.vue'], resolve)
-            },
+            //{
+            //    path: 'courseManage',
+            //    name: 'courseManage',
+            //    component: resolve => require(['@/view/coursemgmt/CourseManage.vue'], resolve)
+            //},
             {
                 path: 'myCourse',
                 name: 'myCourse',
@@ -277,22 +285,22 @@ export const routes = [
                 component: resolve => require(['@/view/teachcontent/CreateLearnUnit.vue'], resolve)
             },
             //创建作业活动
-            {
-                path: 'createHomeWork',
-                name: 'createHomeWork',
-                component: resolve => require(['@/view/selflearning/CreateHomeWork.vue'], resolve)
-            },
+            //{
+            //    path: 'createHomeWork',
+            //    name: 'createHomeWork',
+            //    component: resolve => require(['@/view/selflearning/CreateHomeWork.vue'], resolve)
+            //},
             //创建编序式学习
             {
                 path: 'createOrderLearn',
                 name: 'createOrderLearn',
                 component: resolve => require(['@/view/teachcontent/CreateOrderLearn.vue'], resolve)
             },
-            {
-                path: 'createSelfLearn',
-                name: 'createSelfLearn',
-                component: resolve => require(['@/view/selflearning/CreateSelfLearn.vue'], resolve)
-            },
+            //{
+            //    path: 'createSelfLearn',
+            //    name: 'createSelfLearn',
+            //    component: resolve => require(['@/view/selflearning/CreateSelfLearn.vue'], resolve)
+            //},
             //管理评测页面
             {
                 path: 'manageEvaluation',
@@ -318,11 +326,11 @@ export const routes = [
                 component: resolve => require(['@/view/teachcontent/ManageOrderLearn.vue'], resolve)
             },
             //废弃自主学习活动
-            {
-                path: 'manageSelfLearn',
-                name: 'manageSelfLearn',
-                component: resolve => require(['@/view/selflearning/ManageSelfLearn.vue'], resolve)
-            },
+            //{
+            //    path: 'manageSelfLearn',
+            //    name: 'manageSelfLearn',
+            //    component: resolve => require(['@/view/selflearning/ManageSelfLearn.vue'], resolve)
+            //},
             //新版自主学习
             {
                 path: 'SelfLearn',
@@ -338,11 +346,6 @@ export const routes = [
                 path: 'manageVote',
                 name: 'manageVote',
                 component: resolve => require(['@/view/vote/ManageVote.vue'], resolve)
-            },
-            {
-                path: 'activityReport',
-                name: 'activityReport',
-                component: resolve => require(['@/view/selflearning/ActivityReport.vue'], resolve)
             }
         ]
     }

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


+ 1 - 1
TEAMModelOS/ClientApp/src/utils/js-fn.js

@@ -46,7 +46,7 @@ function getIndex(_arr, _obj) {
  * 产生某个范围的随机数
  */
 function getBtwRandom(start, end) {
-    return Math.floor(Math.random() * end) + start
+    return Math.floor(Math.random() * (end - start)) + start
 }
 /*
  * 根据学段编码获取对应学段信息

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

@@ -317,6 +317,7 @@ export default {
                     (res) => {
                         if (res.error == null) {
                             store.commit('setPrivateSas', res.result.data)
+							res.result.data.sas  = '?' + res.result.data.sas
                             r(res.result.data)
                         } else {
                             j(500)
@@ -345,6 +346,7 @@ export default {
                     (res) => {
                         if (res.error == null) {
                             store.commit('setSchoolSas', res.result.data)
+							res.result.data.sas  = '?' + res.result.data.sas
                             r(res.result.data)
                         } else {
                             j(500)
@@ -379,5 +381,5 @@ export default {
             )
         })
     }
-
+	
 }

+ 0 - 0
TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourse.less


+ 0 - 394
TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourse.vue

@@ -1,394 +0,0 @@
-<template>
-    <div class="course-mgmt-content">
-        <!--课程列表-->
-        <div class="course-list">
-            <!--列表头部-->
-            <div class="course-list-header">
-                <div v-if="!isSearch">
-                    <span class="list-label">{{$t('courseManage.courseList')}}</span>
-                    <Icon type="ios-search" color="white" size="18" class="add-icon" @click="toggleSearch" />
-                    <Icon type="md-trash" color="white" size="18" class="add-icon" @click="showComfirmDelete" />
-                    <Icon type="md-add" color="white" size="18" class="add-icon" :title="$t('courseManage.addCourse')" @click="addCourse" />
-                </div>
-                <div v-else class="dark-iview-input">
-                    <Input icon="ios-close"
-                           v-model="keyWord"
-                           placeholder="关键字搜索..."
-                           autofocus
-                           style="width:calc(100% - 15px)"
-                           @on-click="toggleSearch"
-                           @on-change="onSearchSubjectChange"
-                           @on-enter="onSearchSubjectChange" />
-                </div>
-            </div>
-            <!--列表内容-->
-            <div class="course-list-content">
-                <!--<span class="show-course-label">{{$t('courseManage.courseShow')}}<Icon type="ios-arrow-down" size="16" /></span>-->
-                <div v-if="$store.state.courseMgmt.courseList.length > 0" :class="index === $store.state.courseMgmt.currentCourseIndex ? 'course-list-item block-bg block-bg-active':'course-list-item block-bg'" v-for="(item,index) in $store.state.courseMgmt.courseList" :key="index" @click="selectCourse(index)">
-                    <p class="course-code">
-                        <Icon :type="item.scope === 'school' ? 'ios-barcode-outline' : 'md-person'" color="#AAAAAA" />
-                        {{item.baseInfo.courseCode}}
-                    </p>
-                    <p class="course-name">
-                        {{item.baseInfo.courseName}}
-                    </p>
-                    <Breadcrumb>
-                        <!--<BreadcrumbItem><Icon type="md-pricetag" style="margin-right:5px;" />{{fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.periodCode).periodName}}</BreadcrumbItem>-->
-                        <!--<BreadcrumbItem>{{fn.getGradeName($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.gradeCode)}}</BreadcrumbItem>-->
-                        <BreadcrumbItem><Icon type="md-pricetag" style="margin-right:5px;" />{{fn.getSubjectName($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.subjectCode)}}</BreadcrumbItem>
-                    </Breadcrumb>
-                    <Icon type="ios-browsers" title="复制" color="#EEEEEE" class="course-item-tool" size="30" />
-                </div>
-                <div v-if="$store.state.courseMgmt.courseList.length == 0" style="width:100%;text-align:center;padding-top:180px;">
-                    <EmptyData :textContent="$t('courseManage.noData1')"></EmptyData>
-                </div>
-            </div>
-        </div>
-        <!--课程详细内容-->
-        <div class="course-detail">
-            <div class="course-detail-header">
-                <span class="setting-label">{{$t('courseManage.classroomSetting')}}</span>
-            </div>
-            <AdminCourseClassroom type="admin"></AdminCourseClassroom>
-            <div v-if="$store.state.courseMgmt.courseList.length == 0" style="width:100%;text-align:center;margin-top:180px;">
-                <EmptyData></EmptyData>
-            </div>
-        </div>
-        <Modal v-model="deleteCourseStatus"
-               title="删除课程"
-               @on-ok="delCourse">
-            <p v-if="$store.state.courseMgmt.courseList.length > 0">确认删除{{$store.state.courseMgmt.courseList[$store.state.courseMgmt.currentCourseIndex].baseInfo.courseName}}?</p>
-        </Modal>
-        <Modal v-model="addCourseStatus"
-               title="新增课程"
-               @on-ok="delCourse">
-            <p v-if="$store.state.courseMgmt.courseList.length > 0">确认删除{{$store.state.courseMgmt.courseList[$store.state.courseMgmt.currentCourseIndex].baseInfo.courseName}}?</p>
-        </Modal>
-    </div>
-</template>
-<script>
-    import fn from '@/utils/js-fn.js'
-    import '@/utils/Math.uuid'
-    
-    import CourseBaseSetting from './CourseBaseSetting.vue'
-    import AdminCourseClassroom from './AdminCourseClassroom.vue'
-    import Loading from '@/common/Loading.vue'
-    import CourseSyllabus from './CourseSyllabus.vue'
-    export default {
-        components: {
-            CourseBaseSetting,
-            AdminCourseClassroom,
-            CourseSyllabus,
-            
-            Loading
-        },
-        data() {
-            return {
-                fn,
-                deleteCourseStatus: false,
-                addCourseStatus: false,
-                keyWord: '',
-                isSearch: false,
-                courseListShow: [],
-                currentSettingIndex: 0,
-                addCourseStatus: false,
-                demoLoginInfo: {
-                    user: 'admin',
-                    TEAMModelId: this.$store.state.userInfo.TEAMModelId,
-                    school: '醍摩豆书院',
-                    schoolCode: 'HBCN'
-                }
-            }
-        },
-        methods: {
-            /**切换搜索状态 */
-            toggleSearch() {
-                this.isSearch = !this.isSearch
-            },
-            getSchoolBaseInfo() {
-                this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                        this.isLoaded = true
-                    },
-                    (err) => {
-                        alert('API error!')
-                        this.isLoaded = true
-                    }
-                )
-            },
-            getClassroom() {
-                this.$store.dispatch('schoolBaseInfo/getClassroom').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                    },
-                    (err) => {
-                        alert('API error!')
-                    }
-                )
-            },
-            selectSetting(index) {
-                this.currentSettingIndex = index
-            },
-            selectCourse(index) {
-                this.$store.commit('courseMgmt/setCurrentCourseIndex', index)
-
-                this.$nextTick(() => {
-                    // 此时已经渲染完成
-                    if (this.$refs.courseBaseSetting != undefined) {
-                        this.$refs.courseBaseSetting.setNoticeContent()
-                    }
-                })
-            },
-            showComfirmDelete() {
-                this.deleteCourseStatus = true
-            },
-            /**删除课程 */
-            delCourse() {
-                let requestData = {
-                    id: this.$store.state.courseMgmt.courseList[this.$store.state.courseMgmt.currentCourseIndex].id
-                }
-                this.$api.courseMgmt.deleteCourse(requestData).then(
-                    res => {
-                        if (res.error == null) {
-                            let test = this.$store.state.courseMgmt.courseList
-                            let index = this.$store.state.courseMgmt.currentCourseIndex
-                            this.$store.commit('courseMgmt/setCurrentCourseIndex', 0)
-                            test.splice(index, 1)
-                            this.$store.commit('courseMgmt/setCourseList', test)
-                            this.$Message.success('删除成功!')
-                        } else {
-                            this.$Message.error('删除失败!')
-                        }
-                    },
-                    err => {
-                        this.$Message.error('删除失败!')
-                    }
-                )
-            },
-            showAddCourse() {
-                this.addCourseStatus = true
-            },
-            /**新增课程 */
-            addCourse() {
-                this.addCourseStatus = true
-                let item = {
-                    id: Math.uuid(),
-                    code: this.$store.state.userInfo.TEAMModelId,
-                    baseInfo: {
-                        courseCode: 'T968475',
-                        courseName: '未命名课程' + (this.$store.state.courseMgmt.courseList.length + 1),
-                        periodCode: '',
-                        gradeCode: '',
-                        subjectCode: '',
-                        notice: ''// 课程公告
-                    },
-                    assistTeacher: [], // 协同教师
-                    courseTime: [], // 上课时间表
-                    classroom: [], // 课程“教室”
-                    syllabus: []// 关联课纲
-                }
-                let test = this.$store.state.courseMgmt.courseList
-                test.push(item)
-                this.$store.commit('courseMgmt/setCourseList', test)
-                this.$store.commit('courseMgmt/setCurrentCourseIndex', this.$store.state.courseMgmt.courseList.length - 1)
-                setTimeout(() => {
-                    this.$refs.courseBaseSetting.setNoticeContent()
-                }, 500)
-                console.log(this.$refs.courseBaseSetting)
-                this.$refs.courseBaseSetting.baseEditStatus = false
-            },
-            getCourseInfo() {
-                this.$store.dispatch('courseMgmt/getCourseList').then(
-                    (res) => {
-                        console.log(res)
-                        if (res.code == 1 || res.code == 3) {
-                            this.schoolSetting = this.$store.state.schoolBaseInfo.schoolBaseInfo
-                        } else {
-                            // this.getDefaultData()
-                        }
-                        console.log(this.$store.state.courseMgmt.courseList)
-                    },
-                    (err) => {
-                        console.log(err)
-                    }
-                )
-            }
-        },
-        created() {
-            this.getCourseInfo()
-            this.getSchoolBaseInfo()
-            this.getClassroom()
-        }
-
-    }
-</script>
-<style lang="less" scoped>
-    @import './CourseManage.less';
-</style>
-<style lang="less">
-    .search-course .ivu-input {
-        background: none;
-        border-color: #424242;
-        border-radius: 8px;
-    }
-
-    .course-list-item .ivu-breadcrumb > span:last-child {
-        font-weight: 400;
-        color: #999;
-    }
-
-    .ivu-table-overflowY {
-        &::-webkit-scrollbar
-
-    { /*滚动条整体样式*/
-        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-        height: 1px;
-    }
-
-    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgb(124,124,124);
-    }
-
-    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgba(68,68,68,.5);
-    }
-
-    }
-
-    .course-base-info-content .ivu-input {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #828282;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
-
-    .course-base-info-content .ivu-form-item-label {
-        color: #929292;
-    }
-
-    .course-base-info-content .ivu-form-item-required .ivu-form-item-label:before {
-        color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-form-item-error .ivu-input:focus {
-        border: none;
-    }
-
-    .course-base-info-content .ivu-input-group-prepend {
-        border: none;
-        background: none;
-        color: white;
-        font-size: 14px;
-    }
-
-    .course-base-info-content .ivu-checkbox-wrapper {
-        float: right;
-        color: #929292;
-    }
-
-    .course-base-info-content .ivu-checkbox-inner {
-        background: none;
-        border-color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-checkbox-checked .ivu-checkbox-inner:after {
-        border-color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-select-selection {
-        border-color: #828282;
-        background: none;
-    }
-
-        .course-base-info-content .ivu-select-selection:hover {
-            border-color: #57a3f3;
-        }
-
-    .course-base-info-content .ivu-select-input {
-        color: white;
-        font-size: 16px;
-    }
-
-    .course-base-info-content .w-e-toolbar {
-        background: #383838 !important;
-        border-radius: 5px 5px 0px 0px;
-        border-color: #383838 !important;
-    }
-
-    .course-base-info-content .w-e-text-container {
-        border-color: #383838 !important;
-        border-radius: 0px 0px 5px 5px;
-        overflow-y: auto !important;
-        height: 220px !important;
-        z-index: 99 !important;
-    }
-
-    .course-base-info-content .w-e-text {
-        overflow-y: auto;
-        color: white;
-        &::-webkit-scrollbar
-
-    { /*滚动条整体样式*/
-        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-        height: 1px;
-    }
-
-    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgb(124,124,124);
-    }
-
-    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgba(68,68,68,.5);
-    }
-
-    }
-
-    /*对话框样式修改*/
-    .add-course-modal .ivu-modal-content {
-        background-color: #383838 !important;
-        height: 700px;
-    }
-
-    .add-course-modal .ivu-modal-header {
-        border-color: #454545;
-        background-color: #383838;
-        border-top-left-radius: 6px;
-        border-top-right-radius: 6px;
-    }
-
-    .add-course-modal .ivu-modal-mask {
-        background-color: rgba(20,20,20,.7);
-    }
-
-    .add-course-modal .ivu-input {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #828282;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
-
-    .add-course-modal .ivu-form-item-label {
-        color: #929292;
-    }
-
-    .add-course-modal .ivu-modal-body {
-        padding: 16px 30px;
-    }
-
-    .course-list-header .ivu-input {
-        color: white;
-    }
-</style>

+ 0 - 333
TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourseClassroom.less

@@ -1,333 +0,0 @@
-@first-bgColor: #141414;
-@second-bgColor: #1b1b1b;
-@third-bgColor: #222222;
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.course-classroom-box {
-    width: 100%;
-    height: ~"calc(100% - 45px)";
-    display: flex;
-    flex-direction: row;
-
-    .course-classroom-list {
-        width: 350px;
-        height: 100%;
-        border-right: 1px solid @borderColor;
-
-        .course-classroom-list-header {
-            width: 100%;
-            height: 40px;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-
-            .add-classroom-icon {
-                float: right;
-                line-height: 38px;
-                margin-right: 20px;
-                cursor: pointer;
-            }
-
-            .course-classroom-label {
-                margin-left: 10px;
-                color: @second-textColor;
-            }
-        }
-
-        .course-classroom-list-content {
-            width: 100%;
-            height: ~"calc(100% - 40px)";
-
-            .course-classroom-item {
-                padding: 10px 0px 10px 10px;
-                width: 100%;
-                cursor: pointer;
-                border-bottom: 1px solid @borderColor;
-                color: @second-textColor;
-
-                .classroom-name {
-                    font-size: 24px;
-                    color: white;
-                    font-weight: 500;
-                    margin: 5px 0px;
-                }
-
-                .classroom-info-value {
-                    color: white;
-                    margin-right: 15px;
-                }
-            }
-
-            .course-classroom-item-active {
-                background-image: -webkit-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: -o-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: -moz-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-            }
-        }
-    }
-
-    .course-classroom-info {
-        width: ~"calc(100% - 351px)";
-        height: 100%;
-        padding-left: 10px;
-
-        .course-classroom-info-header {
-            width: 100%;
-            height: 40px;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-
-            .course-classroom-label {
-                margin-left: 10px;
-                color: @second-textColor;
-            }
-        }
-
-        .course-classroom-info-content {
-            width: 100%;
-            height: ~"calc(100% - 40px)";
-        }
-    }
-}
-.system-classroom-box {
-    width: 100%;
-    height: 100%;
-    padding-right:30px;
-    .system-classroom-label {
-        margin-left: 10px;
-        color: @primary-textColor;
-        font-size: 20px;
-        font-weight:600;
-        padding-top: 20px;
-        margin-bottom: 15px;
-    }
-
-    .system-classroom-table{
-        margin-top:20px;
-        margin-left:10px;
-        border-top:1px solid @borderColor;
-    }
-}
-.classroom-box {
-    width: 100%;
-    height: 100%;
-
-    &-header {
-        width: 100%;
-        height: 40px;
-        border-bottom: 1px solid @borderColor;
-        line-height: 40px;
-
-        .setting-label {
-            color: @second-textColor;
-            margin-right: 50px;
-            margin-left: 10px;
-            cursor: pointer;
-        }
-
-        .setting-label-active {
-            color: white;
-            font-weight: 600;
-            border-bottom: 2px solid white;
-        }
-    }
-
-    &-content {
-        width: 100%;
-        height: ~"calc(100% - 40px)";
-        display: flex;
-        flex-direction: row;
-
-        .classroom-base-set {
-            width: 100%;
-            height: 100%;
-            /*display: flex;
-            flex-direction: row;*/
-
-            .class-qrcode-box {
-                width: 400px;
-                height: 100%;
-                padding-left: 10px;
-
-                .qrcode-label {
-                    color: @second-textColor;
-                    margin-top: 40px;
-                    text-align: center;
-                    margin-bottom: 20px;
-                    font-size:15px;
-                }
-            }
-
-            .classroom-base-info {
-                width: 100%;
-                height: 100%;
-                padding-left: 12px;
-                overflow-y: auto;
-
-                .classroom-info-item {
-                    width: 100%;
-                    margin-top: 20px;
-
-                    .classroom-attr-label {
-                        color: @second-textColor;
-                        font-size: 14px;
-                    }
-
-                    .classroom-attr-value {
-                        color: @primary-textColor;
-                        font-size: 18px;
-                        margin-top: 5px;
-                    }
-                }
-            }
-        }
-
-        .classroom-student {
-            width: 100%;
-            height: 100%;
-            overflow-y:auto;
-            .classroom-student-menu {
-                width:100%;
-                height:45px;
-                border-bottom:1px solid @borderColor;
-                line-height:45px;
-                padding-left:10px;
-                color:@primary-textColor;
-            }
-        }
-    }
-}
-.item-tools{
-    opacity:0;
-}
-.close-btn {
-  cursor: pointer;
-  float: right;
-  transform: rotate(0deg);
-  transition: transform 1s;
-}
-.close-btn:hover {
-  transform: rotate(270deg);
-  transition: transform 1s;
-}
-.add-learn-step-icon{
-
-}
-
-/*.course-time-info {
-    height: 100%;
-    width: 34%;
-    display: inline-block;
-    padding-left: 15px;*/
-
-
-.course-time-info-content {
-    width: 100%;
-    height: 100%;
-
-    .course-time-item {
-        width: 100%;
-        padding: 15px 0px 15px 15px;
-        border-bottom: 1px solid @borderColor;
-        display: flex;
-        flex-direction: row;
-        cursor: pointer;
-
-        .item-order {
-            font-size: 60px;
-            font-weight: 600;
-            width: 75px;
-            padding: 0 30px 0 10px;
-            display: flex;
-            flex-direction: row;
-            align-items: center;
-            justify-content: center;
-
-            .edit-time {
-                display: none;
-            }
-        }
-
-        &:hover .item-order .edit-time {
-            display: inline-block;
-        }
-
-        &:hover .item-order .item-order-index {
-            display: none;
-        }
-
-        .course-time-detail {
-            width: ~"calc(100% - 75px)";
-
-            .course-frequently {
-                /*position: relative;*/
-                width: 100%;
-                overflow: auto;
-
-                .course-date {
-                    float: right;
-                    margin-right: 50px;
-                    width: 127px;
-                    /*margin-left: 15px;*/
-                }
-
-                .course-week {
-                    width: 180px;
-                }
-            }
-
-            .course-time {
-                margin-top: 10px;
-                position: relative;
-                text-align: center;
-                width: 100%;
-                height: 40px;
-
-                .course-time-start {
-                    position: absolute;
-                    left: 0;
-                }
-
-                .course-time-end {
-                    position: absolute;
-                    right: 50px;
-                }
-            }
-
-            .course-classroom {
-                margin-top: 10px;
-            }
-
-            .course-time-action {
-                width: ~"calc(100% - 50px)";
-                display: flex;
-                flex-direction: row;
-                justify-content: space-between;
-                margin-top: 10px;
-
-                .smarll-confirm-btn {
-                    width: 45%;
-                    text-align: center;
-                    background-color: #4f4f4f;
-                    color: #A1A1A1;
-                    font-weight: 600;
-                    letter-spacing: 2px;
-                    cursor: pointer;
-                    user-select: none;
-                    border-radius: 5px;
-                    padding: 2px 0px;
-                }
-
-                .smarll-confirm-btn-active {
-                    background-color: #6DE2C4;
-                    color: white;
-                }
-            }
-        }
-    }
-}
-/*}*/

File diff suppressed because it is too large
+ 0 - 1011
TEAMModelOS/ClientApp/src/view/coursemgmt/AdminCourseClassroom.vue


+ 0 - 275
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseBaseSetting.less

@@ -1,275 +0,0 @@
-@first-bgColor: #141414;
-@second-bgColor: #1b1b1b;
-@third-bgColor: #222222;
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.common-header {
-    height: 45px;
-    width: 100%;
-    border-bottom: 1px solid @borderColor;
-    color: @second-textColor;
-    line-height: 45px;
-    padding-left: 10px;
-}
-
-.course-detail-content {
-    width: 100%;
-    height: ~"calc(100% - 49px)";
-    display: flex;
-    flex-direction: row;
-
-    .course-base-info {
-        height: 100%;
-        width: 33%;
-        border-right: 1px solid @borderColor;
-        display: inline-block;
-
-        .course-base-info-header {
-            .common-header
-        }
-
-        .course-base-info-content {
-            width: 100%;
-            height: ~"calc(100% - 45px)";
-            overflow-y: auto;
-            padding: 30px 20px 0px 10px;
-
-            &::-webkit-scrollbar { /*滚动条整体样式*/
-                width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-                height: 1px;
-            }
-
-            &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgb(124,124,124);
-            }
-
-            &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgba(68,68,68,.5);
-            }
-        }
-    }
-
-    .course-teacher-info {
-        padding-left: 15px;
-        height: 100%;
-        width: 33%;
-        border-right: 1px solid @borderColor;
-        display: inline-block;
-
-        .course-teacher-info-header {
-            .common-header
-        }
-
-        .course-teacher-info-content {
-            width: 100%;
-            height: ~"calc(100% - 45px)";
-            overflow-y: auto;
-
-            &::-webkit-scrollbar { /*滚动条整体样式*/
-                width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-                height: 1px;
-            }
-
-            &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgb(124,124,124);
-            }
-
-            &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgba(68,68,68,.5);
-            }
-
-            .course-teacher-item {
-                display: block;
-                padding: 10px 0px 10px 10px;
-                color: @second-textColor;
-                width: 100%;
-                border-bottom: 1px solid @borderColor;
-                font-size: 16px;
-            }
-
-            .course-teacher-search-box {
-                width: 100%;
-                height: 40px;
-                border-bottom: 1px solid @borderColor;
-                padding-left: 10px;
-                line-height: 40px;
-                color: white;
-
-                .search-course-teacher {
-                    float: right;
-                    width: 150px;
-                    margin-right: 28px;
-                    line-height: 40px;
-                }
-            }
-        }
-    }
-
-    .course-time-info {
-        height: 100%;
-        width: 34%;
-        display: inline-block;
-        padding-left: 15px;
-
-        .course-time-info-header {
-            .common-header
-        }
-
-        .course-time-info-content {
-            width: 100%;
-            height: ~"calc(100% - 45px)";
-            overflow-y: auto;
-
-            &::-webkit-scrollbar { /*滚动条整体样式*/
-                width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-                height: 1px;
-            }
-
-            &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgb(124,124,124);
-            }
-
-            &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-                -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-                background: rgba(68,68,68,.5);
-            }
-
-            .course-time-item {
-                width: 100%;
-                padding: 15px 0px 15px 15px;
-                border-bottom: 1px solid @borderColor;
-                display: flex;
-                flex-direction: row;
-                cursor: pointer;
-
-                .item-order {
-                    font-size: 60px;
-                    font-weight: 600;
-                    width: 75px;
-                    padding: 0 30px 0 10px;
-                    display: flex;
-                    flex-direction: row;
-                    align-items: center;
-                    justify-content: center;
-
-                    .edit-time {
-                        display: none;
-                    }
-                }
-
-                &:hover .item-order .edit-time {
-                    display: inline-block;
-                }
-
-                &:hover .item-order .item-order-index {
-                    display: none;
-                }
-
-                .course-time-detail {
-                    width: ~"calc(100% - 75px)";
-
-                    .course-frequently {
-                        /*position: relative;*/
-                        width: 100%;
-                        overflow: auto;
-
-                        .course-date {
-                            float: right;
-                            margin-right: 50px;
-                            width: 127px;
-                            /*margin-left: 15px;*/
-                        }
-
-                        .course-week {
-                            width: 180px;
-                        }
-                    }
-
-                    .course-time {
-                        margin-top: 10px;
-                        position: relative;
-                        text-align: center;
-                        width: 100%;
-                        height: 40px;
-
-                        .course-time-start {
-                            position: absolute;
-                            left: 0;
-                        }
-
-                        .course-time-end {
-                            position: absolute;
-                            right: 50px;
-                        }
-                    }
-
-                    .course-classroom {
-                        margin-top: 10px;
-                    }
-
-                    .course-time-action {
-                        width: ~"calc(100% - 50px)";
-                        display: flex;
-                        flex-direction: row;
-                        justify-content: space-between;
-                        margin-top: 10px;
-
-                        .smarll-confirm-btn {
-                            width: 45%;
-                            text-align: center;
-                            background-color: #4f4f4f;
-                            color: #A1A1A1;
-                            font-weight: 600;
-                            letter-spacing: 2px;
-                            cursor: pointer;
-                            user-select: none;
-                            border-radius: 5px;
-                            padding: 2px 0px;
-                        }
-
-                        .smarll-confirm-btn-active {
-                            background-color: #6DE2C4;
-                            color: white;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-.confirm-btn {
-    width: 100%;
-    height: 40px;
-    line-height: 40px;
-    text-align: center;
-    background-color: #4f4f4f;
-    margin: auto;
-    color: #A1A1A1;
-    font-size: 18px;
-    font-weight: 600;
-    letter-spacing: 2px;
-    cursor: pointer;
-    user-select: none;
-}
-
-.confirm-btn-active {
-    background-color: #6DE2C4;
-    color: white;
-}
-
-.search-btn-icon {
-    float: right;
-    margin-right: 30px;
-    margin-top: 10px;
-    cursor:pointer;
-}

+ 0 - 538
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseBaseSetting.vue

@@ -1,538 +0,0 @@
-<template>
-    <div class="course-detail-content">
-        <div class="course-base-info">
-            <div class="course-base-info-header">
-                <p>{{$t('courseManage.base.baseTag')}}</p>
-            </div>
-            <!--基础信息-->
-            <div class="course-base-info-content">
-                <Form ref="courseBaseInfo" :model="courseInfo.baseInfo" label-position="top" :rules="ruleValidate">
-                    <FormItem :label="$t('courseManage.base.courseName')" prop="courseName">
-                        <Input :class="baseEditStatus ? 'disabled-style':''" :disabled="baseEditStatus" v-model="courseInfo.baseInfo.courseName" placeholder="请输入课程名称..."></Input>
-                    </FormItem>
-                    <FormItem :label="$t('courseManage.base.coursePeriod')" v-if="isLoaded" prop="periodCode" :class="baseEditStatus ? 'disabled-style':''">
-                        <Select v-model="courseInfo.baseInfo.periodCode" :disabled="baseEditStatus" filterable style="width:100%" placeholder="请选择学制" :clearable="true">
-                            <Option v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :value="item.periodCode" :key="index">{{ item.periodName }}</Option>
-                        </Select>
-                    </FormItem>
-                    <FormItem :label="$t('courseManage.base.courseGrade')" prop="gradeCode" :class="baseEditStatus ? 'disabled-style':''">
-                        <Select v-model="courseInfo.baseInfo.gradeCode" :disabled="baseEditStatus" filterable style="width:100%" placeholder="请选择年级" :clearable="true">
-                            <Option v-for="(item,index) in fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,courseInfo.baseInfo.periodCode).grades" :value="item.gradeCode" :key="index">{{ item.gradeName }}</Option>
-                        </Select>
-                    </FormItem>
-                    <FormItem :label="$t('courseManage.base.courseSubject')" prop="subjectCode" :class="baseEditStatus ? 'disabled-style':''">
-                        <Select v-model="courseInfo.baseInfo.subjectCode" :disabled="baseEditStatus" filterable style="width:100%" placeholder="请选择科目" :clearable="true">
-                            <Option v-for="(item,index) in fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,courseInfo.baseInfo.periodCode).subjects" :value="item.subjectCode" :key="index">{{ item.subjectName }}</Option>
-                        </Select>
-                    </FormItem>
-                    <FormItem :label="$t('courseManage.base.courseNotice')" prop="notice">
-                        <div ref="courseNotice" v-show="!baseEditStatus"></div>
-                        <div v-show="baseEditStatus" style="height:260px;overflow-y:auto;color:white;font-size:16px;padding-left:10px;">
-                            <vuescroll>
-                                <div v-html="courseInfo.baseInfo.notice"></div>
-                            </vuescroll>
-                        </div>
-                        <Input v-model="courseInfo.baseInfo.notice" type="textarea" :autosize="{minRows: 2,maxRows: 5}" style="display:none"></Input>
-                    </FormItem>
-                </Form>
-                <Button type="text" width="100%" :class="isFull &&  !baseEditStatus? 'confirm-btn confirm-btn-active':'confirm-btn'" @click="submit('baseInfo')" :loading="isLoading">
-                    {{baseEditStatus ? $t('courseManage.btnEdit'):$t('courseManage.btnSave')}}
-                </Button>
-            </div>
-        </div>
-        <!--协同/任课教师-->
-        <div class="course-teacher-info">
-            <div class="course-teacher-info-header">
-                {{type == 'teacher' ? $t('courseManage.base.teachers') : $t('courseManage.base.teachers1')}}
-                <Checkbox v-model="scope" style="float:right;margin-right:25px;">{{$t('courseManage.base.addTeacher')}}</Checkbox>
-            </div>
-            <div class="course-teacher-info-content">
-                <div class="course-teacher-search-box" v-if="searchTeacherStatus">
-                    <Icon type="ios-search" color="white" size="18" class="search-btn-icon" @click="toggleSearch" />
-                </div>
-                <div v-else class="course-teacher-search-box dark-iview-input">
-                    <Input v-model="keyWord"
-                           search
-                           :placeholder="$t('courseManage.base.searchHolder')"
-                           style="width:calc(100% - 25px)"
-                           @on-click="toggleSearch"
-                           @on-search="getSchoolTeacher"/>
-                </div>
-                <CheckboxGroup v-model="courseInfo.assistTeacher" @on-change="saveChange">
-                    <Checkbox :label="item.TEAMModelId" :disabled="!baseEditStatus" class="course-teacher-item" v-for="(item,index) in teacherList" @click.native="checkStatus">{{item.name}}</Checkbox>
-                </CheckboxGroup>
-            </div>
-        </div>
-        <!--课程时段-->
-        <div class="course-time-info">
-            <div class="course-time-info-header">
-                <span>{{$t('courseManage.base.courseTime')}}</span>
-                <Icon type="md-add" color="white" size="18" @click="addCourseTime" style="float:right;margin-top:13px;margin-right:30px;cursor:pointer;" />
-            </div>
-            <div class="course-time-info-content">
-                <div v-if="courseInfo.courseTime.length > 0" class="course-time-item" v-for="(item,index) in courseInfo.courseTime" :key="index">
-                    <div class="item-order">
-                        <span class="item-order-index">{{index + 1}}</span>
-                        <Icon type="md-create" color="white" class="edit-time" size="50" :title="$t('courseManage.tips1')" @click="editCourseTime(index)" />
-                    </div>
-                    <div class="course-time-detail">
-                        <div class="course-frequently">
-                            <Select v-model="item.frequencyCode" :disabled="editTimeIndex !== index" size="small" style="width:112px" @on-change="selectFrequencyCode">
-                                <Option v-for="item in frequencyList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                            </Select>
-                            <Select v-if="item.frequencyCode === 'week'" v-model="item.frequencyName" class="course-date course-week" :disabled="editTimeIndex !== index" size="small">
-                                <Option v-for="item in weekList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                            </Select>
-                            <DatePicker v-if="item.frequencyCode === 'temporary' || item.frequency === 'month'" v-model="item.frequencyName" :disabled="editTimeIndex !== index" class="course-date" type="date" placeholder="选择日期" size="small" style="" format="yyyy-MM-dd"></DatePicker>
-                        </div>
-                        <div class="course-time">
-                            <TimePicker v-model="item.beginTime" :disabled="editTimeIndex !== index" format="HH:mm" :placeholder="$t('courseManage.base.start')" size="large" class="course-time-start" style="width: 112px;font-size:18px;"></TimePicker>
-                            <span style="margin-left: -50px;margin-top:10px;display:inline-block; color:#eeeeee;">{{$t('courseManage.base.text')}}</span>
-                            <TimePicker v-model="item.endTime" :disabled="editTimeIndex !== index" format="HH:mm" :placeholder="$t('courseManage.base.end')" size="large" class="course-time-end" style="width: 112px;font-size:18px;"></TimePicker>
-                        </div>
-                        <div class="course-classroom">
-                            <Select v-model="item.classroomCode" v-if="editTimeIndex === index" :placeholder="$t('courseManage.base.selectClassroomHolder')" size="small" style="width:calc(100% - 50px);">
-                                <Option v-for="item in $store.state.schoolBaseInfo.classroomList" :value="item.classroomCode" :key="item.classroomCode">{{ item.classroomName }}</Option>
-                            </Select>
-                            <p v-if="editTimeIndex !== index" style="color:white;padding-left:10px;"><span>{{$t('courseManage.base.courseClassroom')}}</span><span>{{getClassroomName(item.classroomCode)}}</span></p>
-                        </div>
-                        <div class="course-time-action" v-if="editTimeIndex === index">
-                            <div class="smarll-confirm-btn smarll-confirm-btn-active" @click="cancelEditTime(index)">{{$t('courseManage.btnCancel')}}</div>
-                            <div class="smarll-confirm-btn smarll-confirm-btn-active" style="margin:0px 15px;" @click="showDeleteTime(index)">{{$t('courseManage.btnDel')}}</div>
-                            <div class="smarll-confirm-btn smarll-confirm-btn-active" @click="submit('courseTime')">{{$t('courseManage.btnSave')}}</div>
-                        </div>
-                    </div>
-                </div>
-                <EmptyData v-if="courseInfo.courseTime.length == 0" style="margin-top:120px;"></EmptyData>
-            </div>
-        </div>
-        <Modal v-model="delTimeStatus"
-               title="删除时段"
-               @on-ok="deleteTime(editTimeIndex)">
-            <p>确定删除课程时段吗?</p>
-        </Modal>
-        
-    </div>
-</template>
-<script>
-    import fn from '@/utils/js-fn.js'
-    import E from 'wangeditor'
-    import { String } from 'core-js'
-    export default {
-        props: {
-            type: {
-                type: String,
-                default:'admin'
-            }
-        },
-        data() {
-            return {
-                fn,
-                delTimeStatus: false,
-                keyWord:'',
-                searchTeacherStatus: false,
-                isLoading: false,
-                baseEditStatus: true,
-                recordEdit: {},
-                scope: false,
-                isLoaded: false,
-                classroomList: [],
-                periodList: [],
-                gradeList: [],
-                subjectList: [],
-                teacherList: [],
-                noticeEditor: undefined,
-                editTimeIndex: -1,
-                isFull: false,
-                weekList: [
-                    {
-                        label: '星期一',
-                        value: 'MON'
-                    },
-                    {
-                        label: '星期二',
-                        value: 'TUE'
-                    },
-                    {
-                        label: '星期三',
-                        value: 'WED'
-                    },
-                    {
-                        label: '星期四',
-                        value: 'THU'
-                    },
-                    {
-                        label: '星期五',
-                        value: 'FRI'
-                    },
-                    {
-                        label: '星期六',
-                        value: 'SAT'
-                    },
-                    {
-                        label: '星期日',
-                        value: 'SUN'
-                    }
-                ],
-                frequencyList: [
-                    {
-                        label: '每日课程',
-                        value: 'day'
-                    },
-                    {
-                        label: '每周课程',
-                        value: 'week'
-                    },
-                    {
-                        label: '临时课程',
-                        value: 'temporary'
-                    }
-                ],
-                ruleValidate: {
-                    courseName: [
-                        { required: true, message: '课程名称不能为空', trigger: 'change' }
-                    ],
-                    periodCode: [
-                        { required: true, message: '学段信息不能为空', trigger: 'change' }
-                    ],
-                    gradeCode: [
-                        { required: true, message: '年级信息不能为空', trigger: 'change' }
-                    ],
-                    subjectCode: [
-                        { required: true, message: '科目信息不能为空', trigger: 'change' }
-                    ],
-                    notice: [
-                        { required: true, message: '课程公告不能为空', trigger: 'change' }
-                    ]
-                }
-            }
-        },
-        methods: {
-            //获取教师列表
-            getSchoolTeacher() {
-                let filterData = {
-                    '$.name': this.keyWord
-                }
-
-                if (!this.scope) {
-                    filterData.schoolCode = this.$store.state.userInfo.schoolCode
-                } else if (this.scope && this.keyWord == '') {
-                    this.$Message.warning('请输入id或者姓名搜索校外教师')
-                    return
-                }
-                this.$api.courseMgmt.getSchoolTeacher(filterData).then(
-                    (res) => {
-                        console.log(res)
-                        this.teacherList = res.result.data
-                    },
-                    (err) => {
-                        console.log(err)
-                    }
-                )
-            },
-            //选择课程频率
-            selectFrequencyCode(code) {
-                if (code == 'day') {
-                    this.courseInfo.courseTime[this.editTimeIndex].frequencyName = []
-                }
-            },
-            /**切换搜索状态 */
-            toggleSearch() {
-                //this.searchTeacherStatus = !this.searchTeacherStatus
-            },
-            validateForm() {
-                this.$refs['courseBaseInfo'].validate((valid) => {
-                    if (valid) {
-                        if (this.courseInfo.baseInfo.notice !== '' && this.courseInfo.baseInfo.notice !== '<p><br></p>') {
-                            this.isFull = true
-                        } else {
-                            this.courseInfo.baseInfo.notice = ''
-                            this.isFull = false
-                        }
-                    } else {
-                        this.isFull = false
-                    }
-                })
-            },
-            setNoticeContent() {
-                if (this.noticeEditor != undefined) {
-                    this.noticeEditor.txt.html(this.courseInfo.baseInfo.notice)
-                    setTimeout(() => {
-                        this.validateForm()
-                    }, 500)
-                }
-            },
-            editCourseTime(index) {
-                this.editTimeIndex = index
-                Object.assign(this.recordEdit, this.courseInfo.courseTime[index])
-            },
-            getClassroomName(code) {
-                let c = []
-                if (this.$store.state.schoolBaseInfo.classroomList !== undefined) {
-                    c = this.$store.state.schoolBaseInfo.classroomList.filter(
-                        (item) => {
-                            return item.classroomCode == code
-                        }
-                    )
-                }
-                return c.length > 0 ? c[0].classroomName : '暂未选择教室'
-            },
-            addCourseTime() {
-                this.courseInfo.courseTime.push(
-                    {
-                        frequencyCode: 'day', // 上课频率 每日、每周、每月、临时课程
-                        beginTime: '', // 课程开始时间
-                        endTime: '', // 课程结束时间
-                        classroomCode: '', // 上课班级/教室
-                        frequencyName: []// 临时课程
-                    }
-                )
-                this.editTimeIndex = this.courseInfo.courseTime.length - 1
-                this.recordEdit = {}
-            },
-            getSchoolBaseInfo() {
-                this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                        this.isLoaded = true
-                    },
-                    (err) => {
-                        alert('API error!')
-                        this.isLoaded = true
-                    }
-                )
-            },
-            getClassroom() {
-                this.$store.dispatch('schoolBaseInfo/getClassroom').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                    },
-                    (err) => {
-                        alert('API error!')
-                    }
-                )
-            },
-            initEditor() {
-                let noticeEditor = new E(this.$refs.courseNotice)
-                noticeEditor.customConfig.onchange = (html) => {
-                    this.courseInfo.notice = html
-                }
-                noticeEditor.customConfig.menus = [
-                    'bold', // 粗体
-                    'italic', // 斜体
-                    'underline', // 下划线
-                    'list', // 列表
-                    'link', // 插入链接
-                    'image' // 插入图片
-                ],
-                noticeEditor.customConfig.showLinkImg = false
-                noticeEditor.customConfig.uploadFileName = 'files'
-                noticeEditor.create()
-                noticeEditor.txt.html(this.courseInfo.baseInfo.notice)
-                this.noticeEditor = noticeEditor
-            },
-            checkStatus() {
-                if (!this.baseEditStatus) {
-                    this.$Message.warning('请先保存基础信息!')
-                }
-            },
-            submit(model) {
-                if (model == 'baseInfo') {
-                    if (this.baseEditStatus) {
-                        this.baseEditStatus = false
-                        this.validateForm()
-                    } else {
-                        this.validateForm()
-                        if (this.isFull) {
-                            this.isLoading = true
-                            this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                                res => {
-                                    if (res.error == null) {
-                                        this.$Message.success('保存成功!')
-                                    } else {
-                                        this.$Message.error('保存失败,API Error!')
-                                    }
-                                    this.baseEditStatus = true
-                                    this.isFull = false
-                                    this.isLoading = false
-                                },
-                                err => {
-                                    this.$Message.error('保存失败,API Error!')
-                                    this.baseEditStatus = true
-                                    this.isFull = false
-                                    setTimeout(() => {
-                                        this.isLoading = false
-                                    },1000)
-                                }
-                            )
-                        } else {
-                            this.$Message.error('请完善信息在保存!')
-                        }
-                    }
-                } else if (model == 'courseTime') {
-                    this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                        res => {
-                            if (res.error == null) {
-                                this.$Message.success('保存成功!')
-                                this.editTimeIndex = -1
-                                this.recordEdit = {}
-                            } else {
-                                this.$Message.error('保存失败,API Error!')
-                            }
-                        },
-                        err => {
-                            this.$Message.error('保存失败,API Error!')
-                        }
-                    )
-                }
-            },
-            saveChange() {
-                if (this.baseEditStatus) {
-                    this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                        res => {
-                            if (res.error == null) {
-                                this.$Message.success('保存成功!')
-                            } else {
-                                this.$Message.error('保存失败,API Error!')
-                            }
-                        },
-                        err => {
-                            this.$Message.error('保存失败,API Error!')
-                        }
-                    )
-                } else {
-                    this.$Message.error('请先保存课程基础信息!')
-                }
-            },
-            deleteTime(index) {
-                this.courseInfo.courseTime.splice(index, 1)
-                this.editTimeIndex = -1
-                this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                    res => {
-                        if (res.error == null) {
-                            this.$Message.success('修改成功!')
-                            this.editTimeIndex = -1
-                            this.recordEdit = {}
-                        } else {
-                            this.$Message.error('修改失败,API Error!')
-                        }
-                    },
-                    err => {
-                        this.$Message.error('修改失败,API Error!')
-                    }
-                )
-            },
-            showDeleteTime() {
-                this.delTimeStatus = true
-            },
-            cancelEditTime(index) {
-                if (JSON.stringify(this.recordEdit) !== '{}') {
-                    Object.assign(this.courseInfo.courseTime[index], this.recordEdit)
-                } else {
-                    this.courseInfo.courseTime.splice(index, 1)
-                }
-                this.editTimeIndex = -1
-                this.recordEdit = {}
-            }
-        },
-        mounted() {
-            this.initEditor()
-        },
-        created() {
-            this.getSchoolBaseInfo()
-            this.getClassroom()
-            this.getSchoolTeacher()
-        },
-        computed: {
-            courseInfo: {
-                get() {
-                    return this.$store.getters['courseMgmt/courseInfo']
-                },
-                set(newVal) {
-                    console.log(newVal)
-                }
-            }
-        },
-        watch: {
-            'courseInfo.baseInfo': {
-                handler(val, oldVal) {
-                    this.$refs['courseBaseInfo'].validate((valid) => {
-                        if (valid) {
-                            if (this.courseInfo.baseInfo.notice !== '' && this.courseInfo.baseInfo.notice !== '<p><br></p>') {
-                                this.isFull = true
-                            } else {
-                                this.courseInfo.baseInfo.notice = ''
-                                this.isFull = false
-                            }
-                        } else {
-                            this.isFull = false
-                        }
-                    })
-                },
-                deep: true // true 深度监听
-            }
-        }
-    }
-</script>
-<style lang="less" scoped>
-    @import './CourseBaseSetting.less';
-</style>
-<style>
-    .course-base-info-content .w-e-menu {
-        z-index: 9 !important;
-    }
-
-    .course-teacher-item .ivu-checkbox {
-        float: right;
-        margin-right: 30px;
-    }
-
-    .course-teacher-item .ivu-checkbox-inner, .course-teacher-search-box .ivu-checkbox-inner {
-        background: none;
-    }
-
-    .search-course-teacher .ivu-input {
-        background: none;
-        border-color: #424242;
-        border-radius: 8px;
-    }
-
-    .course-base-info-content .w-e-toolbar .w-e-menu:hover i {
-        color: white !important;
-    }
-
-    .course-time-item .ivu-select-selection, .course-time-item .ivu-input {
-        background: none;
-        color: white;
-    }
-
-        .course-time-item .ivu-select-disabled .ivu-select-selection, .course-time-item .ivu-input[disabled] {
-            border: none;
-        }
-
-    .course-time-item .course-time .ivu-input[disabled] {
-        font-size: 30px;
-    }
-
-    .course-time-item .ivu-select-disabled .ivu-select-selection .ivu-select-arrow {
-        display: none;
-    }
-
-    .disabled-style .ivu-select-disabled .ivu-select-selection .ivu-select-arrow {
-        display: none;
-    }
-
-    .disabled-style .ivu-select-disabled .ivu-select-selection, .disabled-style .ivu-input[disabled] {
-        border: none;
-        font-size: 18px !important;
-    }
-
-    .disabled-style .ivu-select-input[disabled] {
-        -webkit-text-fill-color: white;
-        font-size: 18px;
-    }
-</style>

+ 0 - 333
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseClassroom.less

@@ -1,333 +0,0 @@
-@first-bgColor: #141414;
-@second-bgColor: #1b1b1b;
-@third-bgColor: #222222;
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.course-classroom-box {
-    width: 100%;
-    height: ~"calc(100% - 45px)";
-    display: flex;
-    flex-direction: row;
-
-    .course-classroom-list {
-        width: 350px;
-        height: 100%;
-        border-right: 1px solid @borderColor;
-
-        .course-classroom-list-header {
-            width: 100%;
-            height: 40px;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-
-            .add-classroom-icon {
-                float: right;
-                line-height: 38px;
-                margin-right: 20px;
-                cursor: pointer;
-            }
-
-            .course-classroom-label {
-                margin-left: 10px;
-                color: @second-textColor;
-            }
-        }
-
-        .course-classroom-list-content {
-            width: 100%;
-            height: ~"calc(100% - 40px)";
-
-            .course-classroom-item {
-                padding: 10px 0px 10px 10px;
-                width: 100%;
-                cursor: pointer;
-                border-bottom: 1px solid @borderColor;
-                color: @second-textColor;
-
-                .classroom-name {
-                    font-size: 24px;
-                    color: white;
-                    font-weight: 500;
-                    margin: 5px 0px;
-                }
-
-                .classroom-info-value {
-                    color: white;
-                    margin-right: 15px;
-                }
-            }
-
-            .course-classroom-item-active {
-                background-image: -webkit-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: -o-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: -moz-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-                background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-            }
-        }
-    }
-
-    .course-classroom-info {
-        width: ~"calc(100% - 351px)";
-        height: 100%;
-        padding-left: 10px;
-
-        .course-classroom-info-header {
-            width: 100%;
-            height: 40px;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-
-            .course-classroom-label {
-                margin-left: 10px;
-                color: @second-textColor;
-            }
-        }
-
-        .course-classroom-info-content {
-            width: 100%;
-            height: ~"calc(100% - 40px)";
-        }
-    }
-}
-.system-classroom-box {
-    width: 100%;
-    height: 100%;
-    padding-right:30px;
-    .system-classroom-label {
-        margin-left: 10px;
-        color: @primary-textColor;
-        font-size: 20px;
-        font-weight:600;
-        padding-top: 20px;
-        margin-bottom: 15px;
-    }
-
-    .system-classroom-table{
-        margin-top:20px;
-        margin-left:10px;
-        border-top:1px solid @borderColor;
-    }
-}
-.classroom-box {
-    width: 100%;
-    height: 100%;
-
-    &-header {
-        width: 100%;
-        height: 40px;
-        border-bottom: 1px solid @borderColor;
-        line-height: 40px;
-
-        .setting-label {
-            color: @second-textColor;
-            margin-right: 50px;
-            margin-left: 10px;
-            cursor: pointer;
-        }
-
-        .setting-label-active {
-            color: white;
-            font-weight: 600;
-            border-bottom: 2px solid white;
-        }
-    }
-
-    &-content {
-        width: 100%;
-        height: ~"calc(100% - 40px)";
-        display: flex;
-        flex-direction: row;
-
-        .classroom-base-set {
-            width: 100%;
-            height: 100%;
-            /*display: flex;
-            flex-direction: row;*/
-
-            .class-qrcode-box {
-                width: 400px;
-                height: 100%;
-                padding-left: 10px;
-
-                .qrcode-label {
-                    color: @second-textColor;
-                    margin-top: 40px;
-                    text-align: center;
-                    margin-bottom: 20px;
-                    font-size:15px;
-                }
-            }
-
-            .classroom-base-info {
-                width: ~"calc(100% - 400px)";
-                height: 100%;
-                padding-left: 12px;
-                overflow-y: auto;
-
-                .classroom-info-item {
-                    width: 100%;
-                    margin-top: 20px;
-
-                    .classroom-attr-label {
-                        color: @second-textColor;
-                        font-size: 14px;
-                    }
-
-                    .classroom-attr-value {
-                        color: @primary-textColor;
-                        font-size: 18px;
-                        margin-top: 5px;
-                    }
-                }
-            }
-        }
-
-        .classroom-student {
-            width: 100%;
-            height: 100%;
-            overflow-y:auto;
-            .classroom-student-menu {
-                width:100%;
-                height:45px;
-                border-bottom:1px solid @borderColor;
-                line-height:45px;
-                padding-left:10px;
-                color:@primary-textColor;
-            }
-        }
-    }
-}
-.item-tools{
-    opacity:0;
-}
-.close-btn {
-  cursor: pointer;
-  float: right;
-  transform: rotate(0deg);
-  transition: transform 1s;
-}
-.close-btn:hover {
-  transform: rotate(270deg);
-  transition: transform 1s;
-}
-.add-learn-step-icon{
-
-}
-
-/*.course-time-info {
-    height: 100%;
-    width: 34%;
-    display: inline-block;
-    padding-left: 15px;*/
-
-
-.course-time-info-content {
-    width: 100%;
-    height: 100%;
-
-    .course-time-item {
-        width: 100%;
-        padding: 15px 0px 15px 15px;
-        border-bottom: 1px solid @borderColor;
-        display: flex;
-        flex-direction: row;
-        cursor: pointer;
-
-        .item-order {
-            font-size: 60px;
-            font-weight: 600;
-            width: 75px;
-            padding: 0 30px 0 10px;
-            display: flex;
-            flex-direction: row;
-            align-items: center;
-            justify-content: center;
-
-            .edit-time {
-                display: none;
-            }
-        }
-
-        &:hover .item-order .edit-time {
-            display: inline-block;
-        }
-
-        &:hover .item-order .item-order-index {
-            display: none;
-        }
-
-        .course-time-detail {
-            width: ~"calc(100% - 75px)";
-
-            .course-frequently {
-                /*position: relative;*/
-                width: 100%;
-                overflow: auto;
-
-                .course-date {
-                    float: right;
-                    margin-right: 50px;
-                    width: 127px;
-                    /*margin-left: 15px;*/
-                }
-
-                .course-week {
-                    width: 180px;
-                }
-            }
-
-            .course-time {
-                margin-top: 10px;
-                position: relative;
-                text-align: center;
-                width: 100%;
-                height: 40px;
-
-                .course-time-start {
-                    position: absolute;
-                    left: 0;
-                }
-
-                .course-time-end {
-                    position: absolute;
-                    right: 50px;
-                }
-            }
-
-            .course-classroom {
-                margin-top: 10px;
-            }
-
-            .course-time-action {
-                width: ~"calc(100% - 50px)";
-                display: flex;
-                flex-direction: row;
-                justify-content: space-between;
-                margin-top: 10px;
-
-                .smarll-confirm-btn {
-                    width: 45%;
-                    text-align: center;
-                    background-color: #4f4f4f;
-                    color: #A1A1A1;
-                    font-weight: 600;
-                    letter-spacing: 2px;
-                    cursor: pointer;
-                    user-select: none;
-                    border-radius: 5px;
-                    padding: 2px 0px;
-                }
-
-                .smarll-confirm-btn-active {
-                    background-color: #6DE2C4;
-                    color: white;
-                }
-            }
-        }
-    }
-}
-/*}*/

+ 0 - 903
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseClassroom.vue

@@ -1,903 +0,0 @@
-<template>
-    <div class="course-classroom-box">
-        <!--课程教室列表-->
-        <div class="course-classroom-list">
-            <div class="course-classroom-list-header">
-                <span class="course-classroom-label">{{$t('courseManage.classroom.classroomList')}}</span>
-                <Poptip trigger="hover" placement="left-start" class="add-classroom-icon" v-if="type == teacher">
-                    <Icon type="md-add" color="white" size="18" />
-                    <div slot="content">
-                        <p @click="addClassroom(1)"><Icon type="ios-barcode-outline" color="white" size="18" style="margin-right:8px;" />{{$t('courseManage.classroom.addClassroomProp1')}}</p>
-                        <p @click="addClassroom(0)" style="margin-top:10px;"><Icon type="md-person" color="white" size="18" style="margin-right:8px;" />{{$t('courseManage.classroom.addClassroomProp2')}}</p>
-                    </div>
-                </Poptip>
-                <Icon v-else type="md-add" color="white" size="18" style="float:right;margin-right:15px;margin-top:10px;cursor:pointer;" @click="addClassroom(1)"/>
-            </div>
-            <div class="course-classroom-list-content">
-                <div v-if="courseInfo.classroom.length > 0" v-for="(item,index) in courseClassroomList" :key="index" @click="changeClassroom(index)" :class="currentClassroomIndex === index ? 'course-classroom-item block-bg block-bg-active':'course-classroom-item block-bg'">
-                    <p class="classroom-code"><Icon :type="item.scope === 'school' ? 'ios-barcode-outline' : 'md-person'" color="white" size="18" style="margin-right:8px;" />{{item.classroomCode}}</p>
-                    <p class="classroom-name">{{item.classroomName}}</p>
-                    <p class="classroom-info ">
-                        <span class="classroom-info-label">{{$t('courseManage.classroom.studentCount')}}</span>
-                        <span class="classroom-info-value">{{item.studentCount}}</span>
-                        <span class="classroom-info-label">{{$t('courseManage.classroom.headmaster')}}</span>
-                        <span class="classroom-info-value">{{item.headMaster}}</span>
-                    </p>
-                </div>
-                <EmptyData v-if="courseInfo.classroom.length == 0" style="padding-top:100px;"></EmptyData>
-            </div>
-        </div>
-
-        <div class="course-classroom-info">
-            <div class="course-classroom-info-header">
-                <span class="course-classroom-label">{{$t('courseManage.classroom.classroomManage')}}</span>
-            </div>
-
-            <div class="course-classroom-info-content">
-                <EmptyData v-if="selectSystemStatus == 0 && courseInfo.classroom.length == 0" style="padding-top:100px;"></EmptyData>
-                <!--选择系统教室block-->
-                <div :class="selectSystemStatus == 1 ? 'system-classroom-box animated fadeIn': ''" v-if="selectSystemStatus == 1">
-                    <p class="system-classroom-label">
-                        <span>{{$t('courseManage.classroom.chooseClassroom')}}</span>
-                        <Icon type="md-close" color="white" size="24" :title="$t('courseManage.classroom.closeChoose')" class="close-btn" @click="closeSelectClassroom" />
-                    </p>
-                    <div class="system-classroom-filter">
-                        <Input v-model="searchText" clearable :placeholder="$t('courseManage.classroom.searchHolder1')" style="width: 200px;margin-left:10px;">
-                        <Icon type="ios-search" slot="prefix" />
-                        </Input>
-                        <Select v-model="searchPeriod" style="width:20%;margin-left:5%;" :placeholder="$t('stuAccount.periodHolder')" clearable>
-                            <Option v-for="(item,index) in periodList" :value="item.periodCode" :key="index" @click.native="getGradeList(index)">{{ item.periodName }}</Option>
-                        </Select>
-                        <Select v-model="searchGrade" style="width:20%;margin-left:1%;" :placeholder="$t('stuAccount.gradeHolder')" clearable>
-                            <Option v-for="(item,index) in gradeList" :value="item.gradeCode" :key="index">{{ item.gradeName }}</Option>
-                        </Select>
-                    </div>
-                    <Table :columns="systemColumns" height="600" :data="systemClassroomList" class="system-classroom-table">
-                        <template slot-scope="{ row ,index}" slot="action">
-                            <Button class="item-tools" type="success" size="small" @click="selectClassroom(index)">{{$t('courseManage.classroom.btnChoose')}}</Button>
-                        </template>
-                    </Table>
-                </div>
-
-                <!--教室基础信息和学生名单管理-->
-                <div class="classroom-box" v-if="selectSystemStatus == 0 && courseInfo.classroom.length > 0">
-                    <!--header选项卡-->
-                    <div class="classroom-box-header">
-                        <span :class="currentSetIndex === 0 ? 'setting-label setting-label-active':'setting-label'" @click="selectSetIndex(0)">{{$t('courseManage.classroom.baseSetting')}}</span>
-                        <span :class="currentSetIndex === 1 ? 'setting-label setting-label-active':'setting-label'" @click="selectSetIndex(1)">{{$t('courseManage.classroom.studentList')}}</span>
-                    </div>
-
-                    <div class="classroom-box-content" v-if="courseClassroomList.length > 0">
-                        <!--教室基础信息-->
-                        <div v-show="currentSetIndex === 0" :class="currentSetIndex === 0 ? 'classroom-base-set animated fadeIn':'classroom-base-set animated fadeOut'">
-                            <div :class="courseClassroomList[currentClassroomIndex].scope == 'personal' ? 'class-qrcode-box animated fadeIn':'class-qrcode-box'" style="border-right: 1px solid #424242;" v-if="courseClassroomList[currentClassroomIndex].code == $store.state.userInfo.TEAMModelId">
-                                <p class="qrcode-label">{{$t('courseManage.classroom.joinCode')}}</p>
-                                <div id="qrcode" ref="qrcode" style="padding:30px;background-color:white;width:260px;margin:auto;"></div>
-                            </div>
-                            <div class="classroom-base-info">
-                                <div class="classroom-info-item">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomCode')}}</p>
-                                    <p class="classroom-attr-value">{{courseClassroomList[currentClassroomIndex].classroomCode}}</p>
-                                </div>
-                                <div class="classroom-info-item">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomName')}}</p>
-                                    <p class="classroom-attr-value">{{courseClassroomList[currentClassroomIndex].classroomName}}</p>
-                                </div>
-                                <div class="classroom-info-item" v-show="courseClassroomList[currentClassroomIndex].scope == 'school'">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomAttr')}}</p>
-                                    <p class="classroom-attr-value">
-                                        {{fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,courseClassroomList[currentClassroomIndex].periodCode).periodName }} / {{fn.getGradeName($store.state.schoolBaseInfo.schoolBaseInfo,courseClassroomList[currentClassroomIndex].gradeCode)}}
-                                    </p>
-                                </div>
-                                <!--班主任-->
-                                <!--<div class="classroom-info-item">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomTeacher')}}</p>
-                                    <p class="classroom-attr-value">{{courseClassroomList[currentClassroomIndex].headMaster}}</p>
-                                </div>-->
-                                <!--授课老师-->
-                                <div class="classroom-info-item dark-iview-select">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomTeacher1')}}</p>
-                                    <Select v-model="model1" style="width:240px">
-                                        <Option v-for="item in teacherList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                                    </Select>
-
-                                </div>
-                                <div class="classroom-info-item">
-                                    <p class="classroom-attr-label">{{$t('courseManage.classroom.classroomNotice')}}</p>
-                                    <div ref="classroomNotice" style="width:90%;margin-top:10px;"></div>
-                                </div>
-                            </div>
-                            <div :class="courseClassroomList[currentClassroomIndex].scope == 'personal' ? 'class-qrcode-box animated fadeIn':'class-qrcode-box'" style="border-left: 1px solid #424242;" v-show="courseClassroomList[currentClassroomIndex].scope == 'school'">
-                                <EmptyData style="margin-top:220px;" :textContent="$t('courseManage.classroom.schoolPlan')"></EmptyData>
-                            </div>
-                        </div>
-
-                        <!--学生名单-->
-                        <div v-show="currentSetIndex === 1" class="classroom-student">
-                            <vuescroll>
-                                <div class="classroom-student-menu">
-                                    <Button type="primary" size="small" style="float:right;margin-right:60px;margin-top:10px;" @click="customGroup">{{$t('courseManage.classroom.autoGroupBtn')}}</Button>
-                                    <div style="float:right;margin-right:30px;" v-show="courseClassroomList[currentClassroomIndex].code == $store.state.userInfo.TEAMModelId">
-                                        <Button type="info" size="small" style="">{{$t('courseManage.classroom.deleteStuBtn')}}</Button>
-                                    </div>
-                                    <div style="float:right;margin-right:30px;" v-show="courseClassroomList[currentClassroomIndex].code == $store.state.userInfo.TEAMModelId" @click="showStudentList">
-                                        <Button type="info" size="small" style="">{{$t('courseManage.classroom.addStuBtn')}}</Button>
-                                    </div>
-                                    <div style="float:right;margin-right:40px;">
-                                        <span style="margin-right:5px;">{{$t('courseManage.classroom.removeStudent1')}}</span>
-                                        <Select v-model="currentGroup" style="width:80px" size="small">
-                                            <Option v-for="(item,index) in groupList" :value="index" :key="index" @click.native="setGroup">{{ item.group+ '('+item.groupName+')' }}</Option>
-                                        </Select>
-                                        <span style="margin-right:10px;margin-left:5px;">{{$t('courseManage.classroom.removeStudent2')}}</span>
-                                    </div>
-
-                                </div>
-                                <Table :columns="studentColumn" :data="courseClassroomList[currentClassroomIndex].students" class="system-classroom-table" :loading="studentTabelLoading" height="600" @on-selection-change="getSelections" no-data-text="暂无学生">
-                                    <Loading slot="loading"></Loading>
-                                    <template slot-scope="{ row ,index}" slot="action">
-                                        <strong></strong>
-                                    </template>
-                                </Table>
-
-                            </vuescroll>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-        <Modal v-model="customGroupStatus"
-               :title="$t('courseManage.classroom.autoGroupBtn')"
-               @on-ok="comfirmCustomRules" class="custom-group">
-            <Form :label-width="80" :label-colon="true">
-                <FormItem :label="$t('courseManage.classroom.studentCountLabel')">
-                    <span>{{classroomStudent.length}}人</span>
-                </FormItem>
-                <FormItem :label="$t('courseManage.classroom.groupCountLabel')">
-                    <InputNumber :max="10" :min="1" v-model="groupNum"></InputNumber>
-                </FormItem>
-                <FormItem :label="$t('courseManage.classroom.groupTypeLabel')">
-                    <RadioGroup v-model="groupType">
-                        <Radio label="1">
-                            <span>{{$t('courseManage.classroom.groupType1')}}</span>
-                        </Radio>
-                        <Radio label="2">
-                            <span>{{$t('courseManage.classroom.groupType2')}}</span>
-                        </Radio>
-                        <Radio label="3">
-                            <span>{{$t('courseManage.classroom.groupType3')}}</span>
-                        </Radio>
-                    </RadioGroup>
-                </FormItem>
-            </Form>
-        </Modal>
-        <Modal v-model="newPersonalStatus"
-               :title="$t('courseManage.classroom.personalClassroomTitle')"
-               @on-ok="confirmNewClassroom" class="custom-group">
-            <Form ref="personalClassroom" :model="personalClassroom" label-position="top" label-colon>
-                <FormItem :label="$t('courseManage.classroom.invitationCode')" prop="classroomCode">
-                    <span style="font-size:18px;">{{personalClassroom.classroomCode}}</span>
-                </FormItem>
-                <FormItem :label="$t('courseManage.classroom.classroomName')" prop="classroomName">
-                    <Input v-model="personalClassroom.classroomName" :placeholder="$t('courseManage.classroom.classroomName')">
-                    </Input>
-                </FormItem>
-            </Form>
-        </Modal>
-        <Modal v-model="addStudentStatus"
-               title="添加学生"
-               width="1000"
-               class-name="dark-iview-modal"
-               @on-ok="confirmAddStudent">
-            <StudentList @selectedStudent="handleSelectStudent"></StudentList>
-        </Modal>
-    </div>
-</template>
-<script>
-    import QRCode from 'qrcodejs2'
-    import E from 'wangeditor'
-    import fn from '@/utils/js-fn.js'
-    
-    import StudentList from '@/components/coursemgmt/StudentList.vue'
-    import '@/utils/Math.uuid'
-    import Loading from '@/common/Loading.vue'
-    export default {
-        components: {
-             Loading, StudentList
-        },
-        props: {
-            type: {
-                type: String,
-                default: 'admin'
-            }
-        },
-        data() {
-            return {
-                fn,
-                model1:'',
-                selectedStudent:[],
-                addStudentStatus: false,
-                studentTabelLoading: false,
-                joinQRcode: undefined,
-                personalClassroom: {
-                    classroomCode: '',
-                    classroomName: '',
-                    notice: ''
-                },
-                teacherList:[],
-                newPersonalStatus: false,
-                groupNum: 2,
-                groupType: '1',
-                selections: [],
-                customGroupStatus: false,
-                currentGroup: '',
-                groupList: [
-                    {
-                        group: 'A',
-                        groupName: '组别别名A'
-                    },
-                    {
-                        group: 'B',
-                        groupName: '组别别名B'
-                    },
-                    {
-                        group: 'C',
-                        groupName: '组别别名C'
-                    },
-                    {
-                        group: 'D',
-                        groupName: '组别别名D'
-                    },
-                    {
-                        group: 'E',
-                        groupName: '组别别名E'
-                    }
-                ],
-                selectSystemStatus: 0,
-                classroomEditor: undefined,
-                test: '',
-                searchText: '',
-                searchPeriod: '',
-                searchGrade: '',
-                gradeList: [],
-                periodList: [],
-                currentSetIndex: 0,
-                systemClassroomList: [],//系统教室列表
-                classroomList:[],//系统教室和个人教室列表
-                systemColumns: [
-                    {
-                        title: '教室编码',
-                        key: 'classroomCode'
-                    },
-                    {
-                        title: '教室名称',
-                        key: 'classroomName'
-                    },
-                    {
-                        title: '学制',
-                        key: 'periodName'
-                    },
-                    {
-                        title: '年级',
-                        key: 'gradeName'
-                    },
-                    {
-                        title: '学生数',
-                        key: 'studentCount',
-                        align: 'center',
-                        width: 100
-                    },
-                    {
-                        title: ' ',
-                        slot: 'action',
-                        width: 120
-                    }
-                ],
-                currentClassroomIndex: 0,
-                classroomStudent: [
-                    {
-                        seatNo: 1,
-                        name: '学生姓名',
-                        period: '高中',
-                        grade: '三年级',
-                        group: 'A',
-                        groupName: '组别A'
-                    },
-                    {
-                        seatNo: 2,
-                        name: '学生姓名',
-                        period: '高中',
-                        grade: '三年级',
-                        group: 'A',
-                        groupName: '组别A'
-                    }, {
-                        seatNo: 3,
-                        name: '学生姓名',
-                        period: '高中',
-                        grade: '三年级',
-                        group: 'A',
-                        groupName: '组别A'
-                    }
-                ],
-                studentColumn: []
-            }
-        },
-        methods: {
-            //确认添加学生
-            confirmAddStudent() {
-                let requestData = {
-                    id: this.courseClassroomList[this.currentClassroomIndex].classroomCode,
-                    code: this.$store.state.userInfo.schoolCode,
-                    studentId: this.selectedStudent.map((item) => {
-                        return item.studentId
-                    })
-                }
-                this.$api.courseMgmt.addClassroom([requestData]).then(
-                    (res) => {
-                        this.$Message.success('添加成功!')
-                    },
-                    (err) => {
-                        this.$Message.error('添加失败!')
-                    }
-                )
-            },
-            
-            //处理选择学生事件
-            handleSelectStudent(students) {
-                console.log(students)
-                this.selectedStudent = students
-            },
-            showStudentList() {
-                this.addStudentStatus = true
-            },
-            
-            //获取教室关联的学生
-            getClassroomStudent() {
-                this.studentTabelLoading = true
-                this.$api.courseMgmt.getClassroomStudent(
-                    {
-                        classroomCode: this.courseClassroomList[this.currentClassroomIndex].classroomCode,
-                        code: this.courseClassroomList[this.currentClassroomIndex].code
-                    }
-                ).then(
-                    (res) => {
-                        this.courseClassroomList[this.currentClassroomIndex].getStatus = true
-                        let students = res.result.extend.students
-                        for (let index in students) {
-                            let currentClassroomlInfo = this.$JSONPath.query(this.$store.state.schoolBaseInfo.classroomList, "$..[?(@.classroomCode=='" + students[index].classroomCode + "')]")
-                            if (currentClassroomlInfo.length > 0) {
-                                let currentSchoolInfo = this.$JSONPath.query(this.$store.state.schoolBaseInfo.schoolBaseInfo, "$..period[?(@.periodCode=='" + currentClassroomlInfo[0].periodCode + "')]")
-                                students[index].periodName = currentSchoolInfo[0].periodName
-                                students[index].periodCode = currentSchoolInfo[0].periodCode
-                                students[index].gradeName = this.$JSONPath.query(currentSchoolInfo, "$..grades[?(@.gradeCode=='" + currentClassroomlInfo[0].gradeCode + "')]")[0].gradeName
-                                students[index].gradeCode = currentClassroomlInfo[0].gradeCode
-                                students[index].classroomName = currentClassroomlInfo[0].classroomName
-                                students[index].groupName = '组别A'
-                                students[index].group = 'A'
-
-                            }
-                        }
-                        this.$set(this.courseClassroomList[this.currentClassroomIndex], 'students', students)
-                        this.studentTabelLoading = false
-                    },
-                    (err) => {
-                        this.studentTabelLoading = false
-                    }
-                )
-            },
-            initData() {
-                this.studentColumn = [
-                    {
-                        title: ' ',
-                        type: 'selection',
-                        width: 80
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC1'),
-                        key: 'seatNo',
-                        width: 140,
-                        align: 'center',
-                        sortable: true
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC2'),
-                        key: 'name',
-                        align: 'left '
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC3'),
-                        key: 'periodName',
-                        width: 150,
-                        align: 'center'
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC4'),
-                        key: 'gradeName',
-                        width: 150,
-                        align: 'center',
-                        sortable: true
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC5'),
-                        key: 'group',
-                        width: 150,
-                        align: 'center',
-                        sortable: true
-                    },
-                    {
-                        title: this.$t('courseManage.classroom.studentTableC6'),
-                        key: 'groupName',
-                        width: 150,
-                        align: 'center'
-                    }
-                ]
-            },
-            changeClassroom(index) {
-                this.currentClassroomIndex = index
-                this.selectSystemStatus = 0
-                if (this.courseClassroomList[this.currentClassroomIndex].code == this.$store.state.userInfo.TEAMModelId) {
-                    if (this.joinQRcode == undefined) {
-                        this.createQRCode('https://account.habookaclass.biz/')
-                    } else {
-                        this.joinQRcode.clear()
-                        this.joinQRcode.makeCode('http://www.baidu.com')
-                    }
-                } else {
-                    this.joinQRcode = undefined
-                }
-                this.initEditor()
-                if (!this.courseClassroomList[this.currentClassroomIndex].getStatus && this.currentSetIndex == 1) {
-                    this.getClassroomStudent()
-                }
-            },
-            selectClassroom(index) {
-                this.selectSystemStatus = 0
-                this.courseInfo.classroom.push(this.systemClassroomList[index].classroomCode)
-                this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                    res => {
-                        if (res.error == null) {
-                            this.$Message.success('保存成功!')
-                        } else {
-                            this.$Message.error('保存失败,API Error!')
-                        }
-                        this.baseEditStatus = true
-                        this.isFull = false
-                    },
-                    err => {
-                        this.$Message.error('保存失败,API Error!')
-                        this.baseEditStatus = true
-                        this.isFull = false
-                    }
-                )
-            },
-            confirmNewClassroom() {
-                this.personalClassroom['scope'] = 'personal'
-                this.personalClassroom['code'] = this.$store.state.userInfo.TEAMModelId
-                this.personalClassroom['headMaster'] = 'HABOOK(测试名字)'
-                this.personalClassroom['id'] = Math.uuid()
-                this.$api.schoolSetting.classroomSettingSaveOrUpdate(this.personalClassroom).then(
-                    (res) => {
-                        if (res.error == null) {
-                            let resData = res.result.data
-                            let [...classrooms] = this.$store.state.schoolBaseInfo.classroomList
-                            classrooms.push(resData)
-                            this.classroomList.push(resData)
-                            this.$store.commit('schoolBaseInfo/setClassroomList', classrooms)
-                            this.courseInfo.classroom.push(resData.classroomCode)
-                            this.$api.courseMgmt.saveOrUpdateCourse([this.courseInfo]).then(
-                                (res) => {
-                                    if (res.error == null) {
-                                        this.$Message.success('个人教室添加成功!')
-                                    } else {
-                                        this.$Message.error('个人教室添加失败!')
-                                    }
-                                },
-                                (err) => {
-                                    this.$Message.error('个人教室添加失败!')
-                                }
-                            )
-                        }
-                    },
-                    (err) => {
-                        this.$Message.error('个人教室添加失败!')
-                    }
-                )
-            },
-            closeSelectClassroom() {
-                this.selectSystemStatus = 0
-            },
-            comfirmCustomRules() {
-                if (this.groupNum === 0) {
-                    this.$Message.warning('分组数量不能为0')
-                } else if (this.groupType == 0) {
-                    this.$Message.warning('请设置分组方式')
-                } else {
-                    switch (this.groupType) {
-                        case '1':
-                            this.randomGroup()
-                            break
-                        case '2':
-                            this.orderGroup()
-                            break
-                        case '3':
-                            this.orderGroupS()
-                            break
-                        default:
-                            break
-                    }
-                }
-            },
-            orderGroupS() {
-                let surplus = this.classroomStudent.length % this.groupNum// 余数
-                let maxCount = surplus == 0 ? this.classroomStudent.length / this.groupNum : Math.ceil(this.classroomStudent.length / this.groupNum)// 每组最大人数
-                this.classroomStudent = this.classroomStudent.sort((a, b) => {
-                    a.seatNo > b.seatNo
-                })
-                for (let i = 0; i < maxCount; i++) {
-                    for (let j = 0; j < this.groupNum; j++) {
-                        let startIndex = this.groupNum * i
-                        if (startIndex + j < this.classroomStudent.length) {
-                            this.classroomStudent[startIndex + j].group = j + 1
-                            this.classroomStudent[startIndex + j].groupName = '组别别名' + (j + 1)
-                        } else {
-                            break
-                        }
-                    }
-                }
-            },
-            orderGroup() {
-                let surplus = this.classroomStudent.length % this.groupNum// 余数
-                let maxCount = surplus == 0 ? this.classroomStudent.length / this.groupNum : Math.ceil(this.classroomStudent.length / this.groupNum)// 每组最大人数
-                this.classroomStudent = this.classroomStudent.sort((a, b) => {
-                    a.seatNo > b.seatNo
-                })
-                let flag = 0
-                let startIndex = 0
-                for (let i = 0; i < this.groupNum; i++) {
-                    for (let j = 0; j < maxCount; j++) {
-                        if (startIndex + j < this.classroomStudent.length) {
-                            this.classroomStudent[startIndex + j].group = i + 1
-                            this.classroomStudent[startIndex + j].groupName = '组别别名' + (i + 1)
-                        } else {
-                            break
-                        }
-                    }
-                    startIndex += maxCount
-                    flag++
-                    if (flag == surplus) {
-                        maxCount--
-                    }
-                }
-            },
-            randomGroup() {
-                let surplus = this.classroomStudent.length % this.groupNum// 余数
-                let surplusCount = surplus// 余数
-                let maxCount = surplus == 0 ? this.classroomStudent.length / this.groupNum : Math.ceil(this.classroomStudent.length / this.groupNum)// 每组最大人数
-                let record = {}// 记录每个组已经分配的人数
-                for (let i = 1; i <= this.groupNum; i++) {
-                    record[i] = 0
-                }
-                let flag = true
-                for (let index in this.classroomStudent) {
-                    let groupIndex = fn.getBtwRandom(1, this.groupNum)
-                    if (record[groupIndex] < maxCount) {
-                        record[groupIndex] = record[groupIndex] + 1
-                    } else {
-                        for (let key in record) {
-                            if (record[key] < maxCount) {
-                                record[key] = record[key] + 1
-                                groupIndex = key
-                                break
-                            }
-                        }
-                    }
-                    this.classroomStudent[index].group = groupIndex
-                    this.classroomStudent[index].groupName = '组别别名' + groupIndex
-                    if (record[groupIndex] == maxCount) {
-                        surplusCount--
-                    }
-                    if (surplusCount <= 0 && surplus > 0 && flag) {
-                        maxCount--
-                        flag = false
-                    }
-                }
-            },
-            getSelections(selection) {
-                this.selections = selection
-                console.log(selection)
-            },
-            setGroup() {
-                if (this.currentGroup == '') {
-                    this.$Message.warning('请设置组别')
-                    return
-                }
-                if (this.selections.length == 0) {
-                    this.$Message.warning('请选择需要设置组别的学生')
-                    return
-                }
-                let groupInfo = this.groupList[this.currentGroup]
-                for (let item of this.selections) {
-                    let index = fn.getIndex(this.classroomStudent, item)
-                    if (index !== -1) {
-                        this.classroomStudent[index].group = groupInfo.group
-                        this.classroomStudent[index].groupName = groupInfo.groupName
-                    } else {
-                        this.$Message.error('error!')
-                    }
-                }
-            },
-            customGroup() {
-                this.customGroupStatus = true
-            },
-            getClassroomList() {
-                this.$store.dispatch('schoolBaseInfo/getClassroom').then(
-                    (res) => {
-                        if (res.code == 1 || res.code == 3) {
-                            this.systemClassroomList.push(...this.$store.state.schoolBaseInfo.classroomList)
-                            this.classroomList.push(...this.$store.state.schoolBaseInfo.classroomList)
-                        }
-                    },
-                    (err) => {
-                        console.log(err)
-                    }
-                )
-            },
-            getPersonalClassroom() {
-                let requestData = {
-                    code: this.$store.state.userInfo.TEAMModelId
-                }
-                this.$api.schoolSetting.findClassInfo(requestData).then(
-                    res => {
-                        if (res.error == null) {
-                            this.classroomList.push(...res.result.data)
-                        } else {
-                            alert('API error!')
-                        }
-                    },
-                    err => {
-                        alert('API error!')
-                    }
-                )
-            },
-            addClassroom(value) {
-                if (value == 1) {
-                    this.selectSystemStatus = value
-                } else if (value == 0) {
-                    let randomCode = 'P'
-                    for (let i = 0; i < 8; i++) {
-                        randomCode += fn.getBtwRandom(0, 9)
-                    }
-                    this.personalClassroom.classroomCode = randomCode
-                    this.newPersonalStatus = true
-                }
-            },
-
-            selectSetIndex(index) {
-                this.currentSetIndex = index
-                if (this.courseClassroomList[this.currentClassroomIndex].scope == 'personal') {
-                    if (this.joinQRcode == undefined) {
-                        this.createQRCode('https://account.habookaclass.biz/')
-                    } else {
-                        this.joinQRcode.clear()
-                        this.joinQRcode.makeCode('http://www.baidu.com')
-                    }
-                } else {
-                    this.joinQRcode = undefined
-                }
-                if (!this.courseClassroomList[this.currentClassroomIndex].getStatus) {
-                    this.getClassroomStudent()
-                }
-            },
-            initEditor() {
-                if (this.classroomEditor == undefined) {
-                    let noticeEditor = new E(this.$refs.classroomNotice)
-                    noticeEditor.customConfig.onchange = (html) => {
-                        this.test = html
-                    }
-                    noticeEditor.customConfig.menus = [
-                        'bold', // 粗体
-                        'italic', // 斜体
-                        'underline', // 下划线
-                        'list', // 列表
-                        'link', // 插入链接
-                        'image' // 插入图片
-                    ],
-                        noticeEditor.customConfig.showLinkImg = false
-                    noticeEditor.customConfig.uploadFileName = 'files'
-                    noticeEditor.create()
-                    this.classroomEditor = noticeEditor
-                } else {
-                    this.classroomEditor.txt.html('')
-                }
-            },
-            createQRCode(url) {
-                this.$nextTick(() => {
-                    // 此时已经渲染完成
-                    let qrcode = new QRCode('qrcode', {
-                        width: 200, // 设置宽度,单位像素
-                        height: 200, // 设置高度,单位像素
-                        text: url // 设置二维码内容或跳转地址
-                    })
-                    this.joinQRcode = qrcode
-                })
-            }
-        },
-        mounted() {
-            this.initEditor()
-            
-        },
-        created() {
-            this.initData()
-            this.getClassroomList()
-            this.getPersonalClassroom()
-        },
-        computed: {
-            courseInfo: {
-                get() {
-                    return this.$store.getters['courseMgmt/courseInfo']
-                },
-                set(newVal) {
-                }
-            },
-            courseClassroomList() {
-                let a = []
-                a = this.classroomList.filter((item, index) => {
-                    return this.courseInfo.classroom.indexOf(item.classroomCode) != -1
-                })
-                return a
-            }
-        }
-    }
-</script>
-<style scoped lang="less">
-    @import './CourseClassroom.less';
-</style>
-
-<style>
-    .classroom-student #loadingBox {
-        margin-top:0px !important;
-    }
-    .classroom-student .ivu-spin-fix {
-        background:rgba(103, 103, 103, 0.27);
-    }
-    .add-classroom-icon .ivu-poptip-inner {
-        background-color: #404040;
-        color: white;
-    }
-
-    .add-classroom-icon .ivu-poptip-arrow::after {
-        display: none;
-    }
-
-    .add-classroom-icon .ivu-poptip-title:after, .add-classroom-icon .ivu-poptip-title {
-        display: none;
-    }
-
-    .system-classroom-box .ivu-input, .system-classroom-box .ivu-select-selection {
-        background: none;
-        border-color: #424242;
-    }
-
-        .system-classroom-box .ivu-input:focus, .system-classroom-box .ivu-input:hover {
-            border-color: #57A3F3 !important;
-        }
-
-        .system-classroom-box .ivu-select-selection:focus, .system-classroom-box .ivu-select-selection:hover {
-            border-color: #57A3F3 !important;
-        }
-
-    .system-classroom-table .ivu-table, .system-classroom-table .ivu-table td, .system-classroom-table .ivu-table th, .system-classroom-table .ivu-table:before {
-        background: none;
-        color: white;
-        border-color: #424242;
-    }
-
-    .system-classroom-table .ivu-table-row-hover .item-tools {
-        opacity: 1;
-        transition: opacity 1s;
-    }
-
-    .system-classroom-table .ivu-table-row-hover {
-        background: #303030;
-    }
-
-    .sc-container .ivu-input, .sc-container .ivu-select-selection {
-        background: none;
-        color: white;
-    }
-
-    .classroom-base-info .w-e-toolbar {
-        background: #383838 !important;
-        border-radius: 5px 5px 0px 0px;
-        border-color: #383838 !important;
-    }
-
-    .classroom-base-info .w-e-text-container {
-        border-color: #383838 !important;
-        border-radius: 0px 0px 5px 5px;
-        overflow-y: auto !important;
-        height: 220px !important;
-    }
-
-    .classroom-base-info .w-e-text {
-        overflow-y: auto;
-        color: white;
-        &::-webkit-scrollbar
-
-    { /*滚动条整体样式*/
-        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-        height: 1px;
-    }
-
-    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgb(124,124,124);
-    }
-
-    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgba(68,68,68,.5);
-    }
-
-    }
-
-    .classroom-base-info .w-e-toolbar .w-e-menu:hover i {
-        color: white !important;
-    }
-
-    .ivu-table-row-hover .item-tools {
-        opacity: 1;
-        transition: opacity .2s;
-    }
-
-    /*对话框样式修改*/
-    .custom-group .ivu-modal-content {
-        background-color: #383838 !important;
-        color: white;
-    }
-
-    .custom-group .ivu-modal-header {
-        border-color: #454545;
-        color: white;
-        background-color: #383838;
-        border-top-left-radius: 6px;
-        border-top-right-radius: 6px;
-    }
-
-    .custom-group .ivu-modal-mask {
-        background-color: rgba(20,20,20,.7);
-    }
-
-    .custom-group .ivu-input {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #828282;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
-
-    .custom-group .ivu-form-item-label {
-        color: #929292;
-    }
-
-    .custom-group .ivu-modal-body {
-        padding: 16px 30px;
-    }
-
-    .custom-group .ivu-modal-footer {
-        border-color: #454545;
-    }
-
-    .custom-group .ivu-modal-header p, .custom-group .ivu-modal-header-inner {
-        color: white;
-        font-weight: 600;
-    }
-
-    .custom-group .ivu-btn-text {
-        color: white;
-    }
-
-        .custom-group .ivu-btn-text:hover {
-            color: black;
-        }
-</style>

+ 0 - 151
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseManage.less

@@ -1,151 +0,0 @@
-@first-bgColor: #141414;
-@second-bgColor: #1b1b1b;
-@third-bgColor: #222222;
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-
-
-.course-mgmt-content {
-    width: 100%;
-    height: 100%;
-    background-color: @first-bgColor;
-
-    .course-list {
-        width: 26%;
-        height: 100%;
-        float: left;
-        padding-left: 15px;
-    }
-
-    .course-detail {
-        width: 74%;
-        height: 100%;
-        float: right;
-        padding-left: 15px;
-    }
-}
-.select-class-label {
-    color: white;
-    margin-right: 15px;
-    margin-left: 22px;
-}
-
-.course-list {
-    border-right: 1px solid @borderColor;
-
-    .course-list-header {
-        width: 100%;
-        height: 45px;
-        position: relative;
-        border-bottom: 1px solid @borderColor;
-        line-height: 45px;
-
-        .list-label {
-            font-size: 16px;
-            color: @second-textColor;
-        }
-
-        .search-course {
-            display: inline-block;
-            position: absolute;
-            left: 10px;
-            right: 10px;
-            top: 16px;
-        }
-
-        .add-icon {
-            float: right;
-            margin-right: 20px;
-            margin-top: 12px;
-            cursor: pointer;
-        }
-    }
-
-    .course-list-content {
-        width: 100%;
-        height: ~"calc(100% - 45px)";
-
-        .show-course-label {
-            font-size: 10px;
-            color: @second-textColor;
-            display: block;
-            padding: 4px 0px 4px 15px;
-            border-bottom: 1px solid @borderColor;
-            font-weight: 800;
-        }
-
-        .course-list-item {
-            width: 100%;
-            padding: 12px 0px 12px 15px;
-            color: @second-textColor;
-            border-bottom: 1px solid @borderColor;
-            position: relative;
-            cursor: pointer;
-
-            .course-code {
-            }
-
-            .course-name {
-                font-size: 20px;
-                color: white;
-                font-weight: 600;
-                margin: 5px 0px;
-            }
-
-            .course-item-tool {
-                position: absolute;
-                right: 50px;
-                top: 35px;
-                display: none;
-            }
-        }
-
-        .course-list-item-active {
-            background-image: -webkit-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-            background-image: -o-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-            background-image: -moz-linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-            background-image: linear-gradient(90deg, rgba(30,30,30,0) 0%, rgba(110,110,110,.2) 50%, rgba(110,110,110,.4) 100%);
-
-            .course-item-tool {
-                display: inline-block;
-            }
-        }
-    }
-}
-
-.course-detail {
-
-    .course-detail-header {
-        width: 100%;
-        height: 45px;
-        line-height: 45px;
-        border-bottom: 1px solid @borderColor;
-        padding-left: 10px;
-
-        .setting-label {
-            color: @second-textColor;
-            margin-right: 60px;
-            cursor: pointer;
-        }
-
-        .setting-label-active {
-            color: white;
-            font-weight: 600;
-            border-bottom: 2px solid white;
-        }
-    }
-
-    
-}
-.modal-title {
-    color: #7F7F7F;
-    font-size: 18px;
-    font-weight: 800;
-    display: inline-block;
-    width: 100%;
-    text-align: center;
-}

+ 0 - 383
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseManage.vue

@@ -1,383 +0,0 @@
-<template>
-    <div class="course-mgmt-content">
-        <!--课程列表-->
-        <div class="course-list">
-            <!--列表头部-->
-            <div class="course-list-header">
-                <div v-if="!isSearch">
-                    <span class="list-label">{{$t('courseManage.courseList1')}}</span>
-                    <Icon type="ios-search" color="white" size="18" class="add-icon" @click="toggleSearch" />
-                    <Icon type="md-trash" color="white" size="18" class="add-icon" @click="showComfirmDelete" />
-                    <Icon type="md-add" color="white" size="18" class="add-icon" :title="$t('courseManage.addCourse')" @click="addCourse" />
-                </div>
-                <div v-else class="dark-iview-input">
-                    <Input icon="ios-close"
-                           v-model="keyWord"
-                           placeholder="关键字搜索..."
-                           autofocus
-                           style="width:calc(100% - 15px)"
-                           @on-click="toggleSearch"
-                           @on-change="onSearchSubjectChange"
-                           @on-enter="onSearchSubjectChange" />
-                </div>
-            </div>
-            <!--列表内容-->
-            <div class="course-list-content">
-                <!--<span class="show-course-label">{{$t('courseManage.courseShow')}}<Icon type="ios-arrow-down" size="16" /></span>-->
-                <div v-if="$store.state.courseMgmt.courseList.length > 0" :class="index === $store.state.courseMgmt.currentCourseIndex ? 'course-list-item block-bg block-bg-active':'course-list-item block-bg'" v-for="(item,index) in $store.state.courseMgmt.courseList" :key="index" @click="selectCourse(index)">
-                    <p class="course-code">
-                        <Icon :type="item.scope === 'school' ? 'ios-barcode-outline' : 'md-person'" color="#AAAAAA" />
-                        {{item.baseInfo.courseCode}}
-                    </p>
-                    <p class="course-name">
-                        {{item.baseInfo.courseName}}
-                    </p>
-                    <Breadcrumb>
-                        <BreadcrumbItem><Icon type="md-pricetag" style="margin-right:5px;" />{{fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.periodCode).periodName}}</BreadcrumbItem>
-                        <BreadcrumbItem>{{fn.getGradeName($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.gradeCode)}}</BreadcrumbItem>
-                        <BreadcrumbItem>{{fn.getSubjectName($store.state.schoolBaseInfo.schoolBaseInfo,item.baseInfo.subjectCode)}}</BreadcrumbItem>
-                    </Breadcrumb>
-                    <Icon type="ios-browsers" title="复制" color="#EEEEEE" class="course-item-tool" size="30" />
-                </div>
-                <div v-if="$store.state.courseMgmt.courseList.length == 0" style="width:100%;text-align:center;padding-top:180px;">
-                    <EmptyData :textContent="$t('courseManage.noData1')"></EmptyData>
-                </div>
-            </div>
-        </div>
-        <!--课程详细内容-->
-        <div class="course-detail">
-            <div class="course-detail-header">
-                <span :class="currentSettingIndex === 0 ? 'setting-label line-bottom line-bottom-active':'setting-label line-bottom'" @click="selectSetting(0)">{{$t('courseManage.baseSetting')}}</span>
-                <span :class="currentSettingIndex === 1 ? 'setting-label line-bottom line-bottom-active':'setting-label line-bottom'" @click="selectSetting(1)">{{$t('courseManage.syllabusSetting')}}</span>
-                <span :class="currentSettingIndex === 2 ? 'setting-label line-bottom line-bottom-active':'setting-label line-bottom'" @click="selectSetting(2)">{{$t('courseManage.classroomSetting')}}</span>
-            </div>
-            <CourseBaseSetting type="teacher" ref="courseBaseSetting" v-if="currentSettingIndex === 0 && $store.state.courseMgmt.courseList.length > 0" :class="currentSettingIndex === 0 ? 'animated fadeIn':'animated fadeOut'"></CourseBaseSetting>
-            <CourseSyllabus v-if="currentSettingIndex === 1 && $store.state.courseMgmt.courseList.length > 0" :class="currentSettingIndex === 1 ? 'animated fadeIn':'animated fadeOut'"></CourseSyllabus>
-            <CourseClassroom type="teacher" v-if="currentSettingIndex === 2 && $store.state.courseMgmt.courseList.length > 0" :class="currentSettingIndex === 2 ? 'animated fadeIn':'animated fadeOut'"></CourseClassroom>
-            <div v-if="$store.state.courseMgmt.courseList.length == 0" style="width:100%;text-align:center;margin-top:180px;">
-                <EmptyData></EmptyData>
-            </div>
-        </div>
-        <Modal v-model="deleteCourseStatus"
-               title="删除课程"
-               @on-ok="delCourse">
-            <p v-if="$store.state.courseMgmt.courseList.length > 0">确认删除{{$store.state.courseMgmt.courseList[$store.state.courseMgmt.currentCourseIndex].baseInfo.courseName}}?</p>
-        </Modal>
-    </div>
-</template>
-<script>
-    import fn from '@/utils/js-fn.js'
-    import '@/utils/Math.uuid'
-    
-    import CourseBaseSetting from './CourseBaseSetting.vue'
-    import CourseClassroom from './CourseClassroom.vue'
-    import Loading from '@/common/Loading.vue'
-    import CourseSyllabus from './CourseSyllabus.vue'
-    export default {
-        components: {
-            CourseBaseSetting,
-            CourseClassroom,
-            CourseSyllabus,
-            
-            Loading
-        },
-        data() {
-            return {
-                fn,
-                deleteCourseStatus: false,
-                keyWord:'',
-                isSearch: false,
-                courseListShow: [],
-                currentSettingIndex: 0,
-                addCourseStatus: false
-            }
-        },
-        methods: {
-            /**切换搜索状态 */
-            toggleSearch() {
-                this.isSearch = !this.isSearch
-            },
-            getSchoolBaseInfo() {
-                this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                        this.isLoaded = true
-                    },
-                    (err) => {
-                        alert('API error!')
-                        this.isLoaded = true
-                    }
-                )
-            },
-            getClassroom() {
-                this.$store.dispatch('schoolBaseInfo/getClassroom').then(
-                    (res) => {
-                        if (res.code == 2) {
-                            alert('数据为空!')
-                        }
-                    },
-                    (err) => {
-                        alert('API error!')
-                    }
-                )
-            },
-            selectSetting(index) {
-                this.currentSettingIndex = index
-            },
-            selectCourse(index) {
-                this.$store.commit('courseMgmt/setCurrentCourseIndex', index)
-                
-                this.$nextTick(() => {
-                    // 此时已经渲染完成
-                    if (this.$refs.courseBaseSetting != undefined) {
-                        this.$refs.courseBaseSetting.setNoticeContent()
-                    }
-                })
-            },
-            showComfirmDelete() {
-                this.deleteCourseStatus = true
-            },
-            /**删除课程 */
-            delCourse() {
-                let requestData = {
-                    id:this.$store.state.courseMgmt.courseList[this.$store.state.courseMgmt.currentCourseIndex].id
-                }
-                this.$api.courseMgmt.deleteCourse(requestData).then(
-                    res => {
-                        if (res.error == null) {
-                            let test = this.$store.state.courseMgmt.courseList
-                            let index = this.$store.state.courseMgmt.currentCourseIndex
-                            this.$store.commit('courseMgmt/setCurrentCourseIndex', 0)
-                            test.splice(index, 1)
-                            this.$store.commit('courseMgmt/setCourseList', test)
-                            this.$Message.success('删除成功!')
-                        } else {
-                            this.$Message.error('删除失败!')
-                        }
-                    },
-                    err => {
-                        this.$Message.error('删除失败!')
-                    }
-                )
-            },
-            /**新增课程 */
-            addCourse() {
-                this.addCourseStatus = true
-                let item = {
-                    id: Math.uuid(),
-                    code: this.$store.state.userInfo.TEAMModelId,
-                    baseInfo: {
-                        courseCode: 'T968475',
-                        courseName: '未命名课程'+(this.$store.state.courseMgmt.courseList.length + 1),
-                        periodCode: '',
-                        gradeCode: '',
-                        subjectCode: '',
-                        notice: ''// 课程公告
-                    },
-                    assistTeacher: [], // 协同教师
-                    courseTime: [], // 上课时间表
-                    classroom: [], // 课程“教室”
-                    syllabus: []// 关联课纲
-                }
-                let test = this.$store.state.courseMgmt.courseList
-                test.push(item)
-                this.$store.commit('courseMgmt/setCourseList', test)
-                this.$store.commit('courseMgmt/setCurrentCourseIndex', this.$store.state.courseMgmt.courseList.length - 1)
-                setTimeout(() => {
-                    this.$refs.courseBaseSetting.setNoticeContent()
-                }, 500)
-                console.log(this.$refs.courseBaseSetting)
-                this.$refs.courseBaseSetting.baseEditStatus = false
-            },
-            getCourseInfo() {
-                this.$store.dispatch('courseMgmt/getCourseList').then(
-                    (res) => {
-                        console.log(res)
-                        if (res.code == 1 || res.code == 3) {
-                            this.schoolSetting = this.$store.state.schoolBaseInfo.schoolBaseInfo
-                        } else {
-                            // this.getDefaultData()
-                        }
-                        console.log(this.$store.state.courseMgmt.courseList)
-                    },
-                    (err) => {
-                        console.log(err)
-                    }
-                )
-            }
-        },
-        created() {
-            this.getCourseInfo()
-            this.getSchoolBaseInfo()
-            this.getClassroom()
-        }
-
-    }
-</script>
-<style lang="less" scoped>
-    @import './CourseManage.less';
-</style>
-<style lang="less">
-    .search-course .ivu-input {
-        background: none;
-        border-color: #424242;
-        border-radius: 8px;
-    }
-
-    .course-list-item .ivu-breadcrumb > span:last-child {
-        font-weight: 400;
-        color: #999;
-    }
-
-    .ivu-table-overflowY {
-        &::-webkit-scrollbar
-
-    { /*滚动条整体样式*/
-        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-        height: 1px;
-    }
-
-    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgb(124,124,124);
-    }
-
-    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgba(68,68,68,.5);
-    }
-
-    }
-
-    .course-base-info-content .ivu-input {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #828282;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
-
-    .course-base-info-content .ivu-form-item-label {
-        color: #929292;
-    }
-
-    .course-base-info-content .ivu-form-item-required .ivu-form-item-label:before {
-        color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-form-item-error .ivu-input:focus {
-        border: none;
-    }
-
-    .course-base-info-content .ivu-input-group-prepend {
-        border: none;
-        background: none;
-        color: white;
-        font-size: 14px;
-    }
-
-    .course-base-info-content .ivu-checkbox-wrapper {
-        float: right;
-        color: #929292;
-    }
-
-    .course-base-info-content .ivu-checkbox-inner {
-        background: none;
-        border-color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-checkbox-checked .ivu-checkbox-inner:after {
-        border-color: #6DE2C4;
-    }
-
-    .course-base-info-content .ivu-select-selection {
-        border-color: #828282;
-        background: none;
-    }
-
-        .course-base-info-content .ivu-select-selection:hover {
-            border-color: #57a3f3;
-        }
-
-    .course-base-info-content .ivu-select-input {
-        color: white;
-        font-size: 16px;
-    }
-
-    .course-base-info-content .w-e-toolbar {
-        background: #383838 !important;
-        border-radius: 5px 5px 0px 0px;
-        border-color: #383838 !important;
-    }
-
-    .course-base-info-content .w-e-text-container {
-        border-color: #383838 !important;
-        border-radius: 0px 0px 5px 5px;
-        overflow-y: auto !important;
-        height: 220px !important;
-        z-index: 99 !important;
-    }
-
-    .course-base-info-content .w-e-text {
-        overflow-y: auto;
-        color: white;
-        &::-webkit-scrollbar
-
-    { /*滚动条整体样式*/
-        width: 5px; /*高宽分别对应横竖滚动条的尺寸*/
-        height: 1px;
-    }
-
-    &::-webkit-scrollbar-thumb { /*滚动条里面小方块*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgb(124,124,124);
-    }
-
-    &::-webkit-scrollbar-track { /*滚动条里面轨道*/
-        -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
-        background: rgba(68,68,68,.5);
-    }
-
-    }
-
-    /*对话框样式修改*/
-    .add-course-modal .ivu-modal-content {
-        background-color: #383838 !important;
-        height: 700px;
-    }
-
-    .add-course-modal .ivu-modal-header {
-        border-color: #454545;
-        background-color: #383838;
-        border-top-left-radius: 6px;
-        border-top-right-radius: 6px;
-    }
-
-    .add-course-modal .ivu-modal-mask {
-        background-color: rgba(20,20,20,.7);
-    }
-
-    .add-course-modal .ivu-input {
-        background: none;
-        border: none;
-        border-bottom: 1px solid #828282;
-        border-radius: 0px;
-        color: white;
-        font-size: 16px;
-    }
-
-    .add-course-modal .ivu-form-item-label {
-        color: #929292;
-    }
-
-    .add-course-modal .ivu-modal-body {
-        padding: 16px 30px;
-    }
-
-    .course-list-header .ivu-input {
-        color: white;
-    }
-</style>

+ 0 - 70
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseSyllabus.less

@@ -1,70 +0,0 @@
-@first-bgColor: #141414;
-@second-bgColor: #1b1b1b;
-@third-bgColor: #222222;
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.course-syllabus-content {
-  width: 100%;
-  height: ~"calc(100% - 45px)";
-  color: @second-textColor;
-
-  .course-syllabus-tab-box {
-    width: 100%;
-    height: 45px;
-    border-bottom: 1px solid @borderColor;
-    padding-left: 10px;
-
-    .tab-label {
-      line-height: 45px;
-      color: @second-textColor;
-      margin-right: 55px;
-      cursor: pointer;
-    }
-
-    .tab-label-active {
-      color: white;
-      font-weight: 600;
-      border-bottom: 2px solid white;
-    }
-  }
-
-  .syllabus-filter-box {
-    width: 100%;
-    padding: 20px 10px;
-    border-bottom: 1px solid @borderColor;
-
-    span {
-      color: @second-textColor;
-    }
-  }
-
-  .course-syllabus-box {
-    width: 100%;
-    height: ~"calc(100% - 146px)"; 
-    position: relative;
-
-    .syllabus-title {
-      color: white;
-      padding: 5px 0px 15px 0px;
-      font-size: 16px;
-      font-weight: 500;
-      border-bottom: 1px solid @borderColor;
-    }
-
-    .syllabus-point {
-      margin-top: 30px;
-    }
-
-    .syllabus-content {
-      margin-top: 30px;
-    }
-
-    .syllabus-question {
-      margin-top: 30px;
-    }
-  }
-}

+ 0 - 214
TEAMModelOS/ClientApp/src/view/coursemgmt/CourseSyllabus.vue

@@ -1,214 +0,0 @@
-<template>
-    <div class="course-syllabus-content">
-        <div class="course-syllabus-tab-box">
-            <span :class="currentTabIndex == 0 ? 'tab-label tab-label-active':'tab-label'" @click="selectSyllabusTab(0)">{{$t('courseManage.syllabus.schoolSyllabus')}}</span>
-            <span :class="currentTabIndex == 1 ? 'tab-label tab-label-active':'tab-label'" @click="selectSyllabusTab(1)">{{$t('courseManage.syllabus.personalSyllabus')}}</span>
-        </div>
-        <div class="syllabus-filter-box">
-            <div class="dark-iview-select">
-                <span>{{$t('courseManage.syllabus.period')}}</span>
-                <Select v-model="filters.periodCode" filterable style="width:200px;" :placeholder="$t('courseManage.syllabus.placeHolder1')" :clearable="true" size="small">
-                    <Option v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :value="item.periodCode" :key="index" @click.native="getCurrentGrade(index)">{{ item.periodName }}</Option>
-                </Select>
-                <span style="margin-left:30px;">{{$t('courseManage.syllabus.subject')}}</span>
-                <Select v-model="filters.subjectCode" filterable style="width:200px;" :placeholder="$t('courseManage.syllabus.placeHolder2')" :clearable="true" size="small">
-                    <Option v-for="(item,index) in fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,filters.periodCode).subjects" :value="item.subjectCode" :key="index">{{ item.subjectName }}</Option>
-                </Select>
-                <span style="margin-left:30px;">{{$t('courseManage.syllabus.grade')}}</span>
-                <Select v-model="filters.gradeCode" filterable style="width:200px;" :placeholder="$t('courseManage.syllabus.placeHolder3')" :clearable="true" size="small">
-                    <Option v-for="(item,index) in fn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,filters.periodCode).grades" :value="item.gradeCode" :key="index">{{ item.gradeName }}</Option>
-                </Select>
-                </br>
-                <Checkbox v-model="showAll" style="margin-top:15px;">{{$t('courseManage.syllabus.text')}}</Checkbox>
-            </div>
-        </div>
-        <div class="course-syllabus-box">
-            <Split v-model="split1">
-                <div slot="left" class="demo-split-pane" style="padding-top:15px;">
-                    <vuescroll>
-                        <Collapse simple accordion @on-change="getVolumeCode" v-show="volumes.length > 0">
-                            <Panel v-for="(item,index) in volumes" :name="item.volumeCode" :key="index">
-                                {{item.volumeName}}
-                                <div slot="content">
-                                    <Tree ref="syllabusTree" :data="syllabus" show-checkbox multiple @on-check-change="getSelectSyllabus($event,index)"></Tree>
-                                </div>
-                            </Panel>
-                        </Collapse>
-                        <EmptyData v-show="volumes.length == 0" style="margin-top:100px;" fontSize="18px"></EmptyData>
-                    </vuescroll>
-                </div>
-                <div slot="right" class="demo-split-pane" style="padding-top:15px;padding-left:20px;overflow:auto;height: 100%;">
-                    <vuescroll>
-                        <p class="syllabus-title">2.1 等差数列求和</p>
-                        <div class="syllabus-point">
-                            <p>{{$t('courseManage.syllabus.knowledge')}}</p>
-                            <EmptyData :iconWidth="50" :fontSize="'10px'"></EmptyData>
-                        </div>
-                        <div class="syllabus-content">
-                            <p>{{$t('courseManage.syllabus.content')}}</p>
-                            <EmptyData :iconWidth="50" :fontSize="'10px'"></EmptyData>
-                        </div>
-                        <div class="syllabus-question">
-                            <p>{{$t('courseManage.syllabus.question')}}</p>
-                            <EmptyData :iconWidth="50" :fontSize="'10px'"></EmptyData>
-                        </div>
-                    </vuescroll>
-                </div>
-            </Split>
-
-        </div>
-    </div>
-</template>
-<script>
-    import fn from '@/utils/js-fn.js'
-    
-    export default {
-        data() {
-            return {
-                fn,
-                checkedSyllabus: [],
-                syllabus: [],
-                volumes: [],
-                split1: 0.8,
-                showAll: false,
-                currentTabIndex: 0,
-                filters: {
-                    periodCode: '',
-                    gradeCode: '',
-                    subjectCode: ''
-                },
-                gradeList: [],
-                subjectList: []
-            }
-        },
-        methods: {
-            getSelectSyllabus(data, index) {
-                let checkItem = this.$refs.syllabusTree[index].getCheckedAndIndeterminateNodes()
-                let checkedIds = checkItem.map((item, index) => {
-                    return item.id
-                })
-                if (checkItem.length > 0) {
-                    this.checkedSyllabus[checkItem[0].volumeCode] = checkedIds
-                    console.log(this.checkedSyllabus)
-                }
-            },
-            getVolumeCode(keys) {
-                if (keys.length > 0) {
-                    this.getSyllabusByVolume(keys[0])
-                }
-            },
-            selectSyllabusTab(index) {
-                this.currentTabIndex = index
-            },
-            getCurrentGrade(index) {
-                this.gradeList = this.$store.state.schoolBaseInfo.schoolBaseInfo.period[index].grades
-                this.subjectList = this.$store.state.schoolBaseInfo.schoolBaseInfo.period[index].subjects
-            },
-            getSyllabusByVolume(code) {
-                let requestData = {
-                    volumeCode: code,
-                    status: 1
-                }
-                this.$api.syllabus.GetTreeByVolume(requestData).then(
-                    (res) => {
-                        if (res.error == null) {
-                            this.syllabus = res.result.data
-                        } else {
-                            alert('API error!')
-                        }
-                    },
-                    (err) => {
-                        alert('API error!')
-                    }
-                )
-            },
-            getVolumes() {
-                let requestData = {
-                    periodCode: this.filters.periodCode,
-                    status: 1,
-                    subjectCode: this.filters.subjectCode,
-                    type: this.currentTabIndex,
-                    code:this.currentTabIndex == 1 ? this.$store.state.userInfo.TEAMModelId : this.$store.state.userInfo.schoolCode
-                }
-                this.$api.syllabus.GetVolumes(requestData).then(
-                    res => {
-                        if (res.error == null) {
-                            this.volumes = res.result.data
-                        } else {
-                            alert('API error!')
-                        }
-                    },
-                    err => {
-                        alert('API error!')
-                    }
-                )
-            }
-        },
-        watch: {
-            filters: {
-                deep: true,
-                handler(val, oldVal) {
-                    this.getVolumes()
-                }
-            }
-        },
-        created() {
-            this.filters.periodCode = this.$store.state.schoolBaseInfo.schoolBaseInfo.period[0].periodCode
-            this.filters.subjectCode = this.$store.state.schoolBaseInfo.schoolBaseInfo.period[0].subjects[0].subjectCode
-        }
-    }
-</script>
-<style scoped lang="less">
-    @import './CourseSyllabus.less';
-</style>
-<style>
-    .syllabus-filter-box .ivu-select-input {
-        color: white;
-    }
-
-    .syllabus-filter-box .ivu-select-selection {
-        border-color: #424242;
-    }
-
-    .course-syllabus-content .ivu-checkbox-inner {
-        background: none;
-    }
-
-    .course-syllabus-box .ivu-tree-title {
-        color: #a5a5a5;
-    }
-
-    .course-syllabus-box .ivu-split-trigger-vertical .ivu-split-trigger-bar {
-        background: #FFF;
-    }
-
-    .course-syllabus-box .ivu-split-trigger-vertical {
-        background: #303030;
-        border-color: #424242;
-    }
-
-    .course-syllabus-box .ivu-collapse-simple, .course-syllabus-box .ivu-collapse-content {
-        background: none;
-        color: white;
-    }
-
-    .course-syllabus-box .ivu-collapse, .course-syllabus-box .ivu-collapse > .ivu-collapse-item, .course-syllabus-box .ivu-collapse > .ivu-collapse-item > .ivu-collapse-header {
-        border: none;
-    }
-
-        .course-syllabus-box .ivu-collapse > .ivu-collapse-item > .ivu-collapse-header {
-            color: white;
-        }
-
-    .course-syllabus-box .ivu-collapse-content {
-        padding-left: 47px;
-    }
-
-    .course-syllabus-box .ivu-collapse > .ivu-collapse-item.ivu-collapse-item-active > .ivu-collapse-header {
-        border: none;
-    }
-
-    .course-syllabus-box .ivu-tree-empty {
-        color: #909090;
-    }
-</style>

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

@@ -107,8 +107,9 @@
 				</div>
 				<transition name="slide">
 					<div v-show="collapseList.indexOf(exerciseList.indexOf(item)) > -1" class="toggle-area">
+					<div v-if="item.type !== 'Compose'">
 						<!-- 答案展示部分 -->
-						<div class="item-explain" v-show="isShowAnswer">
+						<div class="item-explain">
 							<span class="explain-title">【答ㅤ案】</span>
 							<div class="item-explain-details">
 								<!-- 问答题答案 -->
@@ -127,14 +128,14 @@
 							</div>
 						</div>
 						<!-- 解析部分 -->
-						<div class="item-explain" v-show="isShowAnswer">
+						<div class="item-explain">
 							<span class="explain-title">【解ㅤ析】</span>
 							<div class="item-explain-details">
 								<span v-html="item.explain || '暂无解析'"></span>
 							</div>
 						</div>
 						<!-- 知识点部分 -->
-						<div class="item-explain" v-show="isShowAnswer">
+						<div class="item-explain">
 							<span class="explain-title">【知识点】</span>
 							<div class="item-explain-details">
 								<span v-if="!item.points.length">暂未绑定知识点</span>
@@ -146,6 +147,11 @@
 							</div>
 						</div>
 					</div>
+					<!-- 如果是综合题 则加载子题渲染组件 -->
+					<div v-else>
+						<BaseChild :children="item.children"></BaseChild>
+					</div>
+					</div>
 				</transition>
 				<!-- 底部题目操作栏 -->
 				<div class="item-tools">
@@ -180,13 +186,13 @@
 	</div>
 </template>
 <script>
-	import Loading from '@/common/Loading.vue'
 	import BaseImport from '../components/BaseImport'
+	import BaseChild from '../components/BaseChild'
 	import BaseEditExercise from '../components/BaseEditExercise'
 
 	export default {
 		components: {
-			Loading,
+			BaseChild,
 			BaseImport,
 			BaseEditExercise
 		},
@@ -300,7 +306,6 @@
 					/* 查找当前页面所有知识点ID换名称 */
 					this.getPointsByIds(this.getPointIds(list)).then(res => {
 						this.allPointList = res
-						console.log(this.allPointList)
 					})
 					
 					let privateSas = await this.$tools.getPrivateSas()
@@ -401,19 +406,23 @@
 			 * @param id
 			 */
 			onQuestionToggle(index, id, e) {
+				if(e.target.className === 'item-tools') return
 				e.stopPropagation()
 				let listIndex = this.collapseList.indexOf(index)
 				if (listIndex > -1) {
 					this.collapseList.splice(listIndex, 1)
 				} else {
 					/** 如果是首次展开 则需要获取详细数据 否则直接展开 */
-					if (!this.exerciseList[index].answer.length) {
-						this.collapseList.push(index)
-						this.pageScrollTo(e.target.offsetTop + 420) // 490就是 content-wrap 距离顶部高度
-					} else {
-						this.collapseList.push(index)
-						this.pageScrollTo(e.target.offsetTop + 420) // 490就是 content-wrap 距离顶部高度
-					}
+					// if (!this.exerciseList[index].answer.length) {
+					// 	this.collapseList.push(index)
+					// 	this.pageScrollTo(e.target.offsetTop + 320) // 490就是 content-wrap 距离顶部高度
+					// } else {
+					// 	this.collapseList.push(index)
+					// 	this.pageScrollTo(e.target.offsetTop + 320) // 490就是 content-wrap 距离顶部高度
+					// }
+					
+					this.collapseList.push(index)
+					this.pageScrollTo(e.target.offsetTop + 320)
 
 				}
 

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

@@ -122,7 +122,7 @@
         background: White;
         margin-top: 15px;
         .fl-col-center;
-        align-items: start;
+        align-items: flex-start;
         border-radius: 5px;
         cursor: pointer;
 

+ 126 - 0
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChild.vue

@@ -0,0 +1,126 @@
+<template>
+	<div class="child-wrap">
+		<div class="child-item" v-for="(item,index) in children">
+			<div class="child-item-question">
+				<span class="child-item-question-order">【小题{{ index + 1 }}】</span>
+				<p class="child-item-question-content" v-html="item.question"></p>
+			</div>
+			<!-- 选项部分 -->
+			<div v-for="(option,optionIndex) in item.option" :key="optionIndex" class="child-item-option" style="pointer-events:none">
+				<div>
+					<div class="child-item-option-order">{{String.fromCharCode(64 + parseInt(optionIndex+1))}} : </div>
+					<div class="child-item-option-text" v-html="option.value"></div>
+				</div>
+			</div>
+			<!-- 答案展示部分 -->
+			<div class="item-explain">
+				<span class="explain-title">【答ㅤ案】</span>
+				<div class="item-explain-details">
+					<!-- 问答题答案 -->
+					<div v-if="item.type === 'Subjective'">
+						<span v-for="(answer,index) in item.answer" :key="index" v-html="item.answer.length ? answer : '未设置答案'"></span>
+					</div>
+					<!-- 填空题答案 -->
+					<div v-else-if="item.type === 'Complete'">
+						<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index"
+						 v-html="answer"></span>
+					</div>
+					<!-- 其余题型答案 -->
+					<div v-else>
+						<span :class="[ item.type === 'Complete' ? 'item-answer-item':'']" v-for="(answer,index) in item.answer" :key="index">{{answer}}</span>
+					</div>
+				</div>
+			</div>
+			<!-- 解析部分 -->
+			<div class="item-explain">
+				<span class="explain-title">【解ㅤ析】</span>
+				<div class="item-explain-details">
+					<span v-html="item.explain || '暂无解析'"></span>
+				</div>
+			</div>
+			<!-- 知识点部分 -->
+			<div class="item-explain">
+				<span class="explain-title">【知识点】</span>
+				<div class="item-explain-details">
+					<span v-if="!item.points.length">暂未绑定知识点</span>
+					<div v-else>
+						<span v-for="point in item.points" class="item-point-tag">
+							<span>{{ point }}</span>
+						</span>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+<script>
+	import '@/utils/Math.uuid'
+	export default {
+		components: {},
+		props: {
+			children: {
+				type: Array,
+				default: []
+			}
+		},
+		data() {
+			return {
+				
+			}
+		},
+		created() {
+		},
+		methods: {
+
+
+			
+		},
+
+		mounted() {
+
+		},
+
+		watch: {
+			
+		}
+
+	}
+</script>
+
+<style lang="less" scoped>
+	.child-wrap{
+		.child-item{
+			margin:40px 10px 0 10px;
+			
+			&-question{
+				font-weight: bold;
+				// color:#01b087;
+				
+				&-order{
+					 color:#10abe7;
+				}
+				&-content{
+					margin-left: 5px;
+				}
+			}
+			
+			&-option{
+				font-size: 14px;
+				margin: 10px 5px;
+				margin-left: 80px;
+				
+				&-order{
+					display: inline-block;
+					width: 25px;
+				}
+				
+				&-text{
+					display: inline-block;
+					margin-left: 5px;
+					width: calc(90% - 25px);
+					vertical-align: text-top;
+				}
+			}
+		}
+	}
+</style>

+ 184 - 0
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseChildList.vue

@@ -0,0 +1,184 @@
+<template>
+	<div>
+		<div class="child-list-wrap">
+			<draggable class="list-group" tag="div" v-model="childrenList" v-bind="dragOptions" @start="drag = true" @end="onDragEnd">
+				<transition-group type="transition" :name="!drag ? 'flip-list' : null">
+					<div class="child-item" v-for="(item,index) in childrenList" :key="index">
+						<div class="child-item-question">
+							<span class="child-item-question-order">({{ index + 1}})</span>
+							<p class="child-item-question-content" v-html="item.question"></p>
+						</div>
+						<div class="item-tools-wrap">
+							<div class="item-tools-t flex-row-center" @click="onEditChild(item,index)">
+								<Icon type="ios-brush-outline" />编辑</div>
+							<div class="item-tools-t flex-row-center" @click="onDeleteChild(item,index)">
+								<Icon type="ios-archive-outline" />删除</div>
+						</div>
+					</div>
+				</transition-group>
+			</draggable>
+		</div>
+		<!-- 添加子题弹窗 -->
+		<Modal v-model="editChildModal" width="1080" footer-hide class="">
+			<div class="modal-header" slot="header">编辑子题</div>
+			<BaseCreateChild @addFinish='onEditChildFinish' refId="childListEdit" :editItem="curItem"></BaseCreateChild>
+		</Modal>
+	</div>
+</template>
+<script>
+	import BaseCreateChild from '@/view/evaluation/components/BaseCreateChild'
+	import draggable from "vuedraggable"
+	export default {
+		components: {
+			BaseCreateChild , draggable
+		},
+		props: {
+			childList: {
+				type: Array,
+				default: []
+			}
+		},
+		data() {
+			return {
+				editChildModal: false,
+				drag: false,
+				childrenList: [],
+				items:[],
+				curIndex: null,
+				curItem: null
+			}
+		},
+		created() {
+			this.childrenList = this.childList
+		},
+		methods: {
+			
+			// 拖拽完成之后
+			onDragEnd(val) {
+				console.log(this.childrenList)
+				this.$emit('onEditChildFinish', this.childrenList)
+				this.drag = false
+			},
+			
+			onEditChild(item, index) {
+				this.curItem = item
+				this.curIndex = index
+				this.editChildModal = true
+			},
+
+			onEditChildFinish(item) {
+				console.log(item)
+				this.$set(this.childrenList, this.curIndex, item)
+				this.editChildModal = false
+				this.$emit('onEditChildFinish', this.childrenList)
+			},
+
+			onDeleteChild(item, index) {
+				this.$Modal.confirm({
+					title: '提示',
+					content: '<p>确认删除该小题吗?</p>',
+					okText: '确认',
+					cancelText: '取消',
+					onOk: () => {
+						this.childrenList.splice(index, 1)
+						this.$emit('onEditChildFinish', this.childrenList)
+					}
+				})
+
+			}
+
+
+		},
+		
+		computed: {
+			dragOptions() {
+				return {
+					animation: 200,
+					group: "description",
+					disabled: false,
+					ghostClass: "ghost"
+				};
+			}
+		},
+		mounted() {
+			// this.childrenList = this.childList
+		},
+
+		watch: {
+			childList: {
+				handler(newValue) {
+					if (newValue) {
+						console.log(newValue)
+						this.childrenList = JSON.parse(JSON.stringify(newValue))
+					}
+				},
+				deep: true
+			}
+		}
+
+	}
+</script>
+
+<style lang="less" scoped>
+	.child-list-wrap {
+		.child-item {
+			position: relative;
+			margin: 10px 0;
+			padding: 20px 10px;
+			border: 1px solid #e6e6e6;
+			cursor: move;
+
+			&-question {
+
+				&-order {
+					display: inline-block;
+				}
+
+				&-content {
+					display: inline-block;
+					margin-left: 5px;
+				}
+			}
+
+			&:hover {
+				border: 1px solid #01b4ef;
+
+				.item-tools-wrap {
+					display: unset;
+				}
+			}
+		}
+
+		.item-tools-wrap {
+			position: absolute;
+			right: 0;
+			top: -30px;
+			width: auto;
+			height: 30px;
+			margin: 0;
+			padding: 0;
+			background: #01b4ef;
+			display: none;
+		}
+
+		.item-tools-t {
+			height: 100%;
+			padding: 0 15px;
+			float: left;
+			color: white;
+			cursor: pointer;
+		}
+
+		.item-tools-t:hover {
+			background: #4a5ae6;
+		}
+
+		/*横向垂直水平居中*/
+		.flex-row-center {
+			display: flex;
+			flex-direction: row;
+			justify-content: center;
+			align-items: center;
+		}
+	}
+</style>

+ 568 - 0
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue

@@ -0,0 +1,568 @@
+<template>
+	<div class="ev-container" :id="refId">
+		<div class="display-flex">
+			<div class="exersices-attr my-radio-style">
+				<IconText :text="'关联认知层次'" :color="'#00b8ff'" :icon="'md-planet'"></IconText>
+				<Select v-model="exerciseField">
+					<Option v-for="(item,index) in fieldList" :value="index" :key="index">{{ item }}</Option>
+				</Select>
+			</div>
+			<div class="exersices-attr my-radio-style">
+				<IconText :text="'关联知识点'" :color="'#00b8ff'" :icon="'md-infinite'"></IconText>
+				<Button type="info" style="margin-top:20px" @click="selectPointsModal = true" v-if="exercisePoints.length === 0">选择知识点</Button>
+				<div v-else style="margin-top:10px">
+					<span v-for="(item,index) in exercisePoints" :key="index" class="exercise-item-point">
+						{{item.name}}
+						<span class="exercise-item-point-close">
+							<Icon type="md-close" @click="onDeletePoint(index)" /></span>
+					</span>
+					<span class="exercise-item-point-modify" @click="selectPointsModal = true">修改</span>
+				</div>
+			</div>
+
+		</div>
+		<div class="exersices-attr display-flex">
+			<div class="exersices-attr my-radio-style">
+				<IconText :text="'选择题型'" :color="'#00b8ff'" :icon="'md-pricetags'"></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="exersices-attr edit-exersices-attr-diff my-radio-style">
+				<IconText :text="'题目难度'" :color="'#00b8ff'" :icon="'md-pulse'"></IconText>
+				<RadioGroup v-model="exersicesDiff" type="button">
+					<Radio label="1" @click.native="diffChange($event,'1')">容易</Radio>
+					<Radio label="2" @click.native="diffChange($event,'2')">较易</Radio>
+					<Radio label="3" @click.native="diffChange($event,'3')">一般</Radio>
+					<Radio label="4" @click.native="diffChange($event,'4')">较难</Radio>
+					<Radio label="5" @click.native="diffChange($event,'5')">困难</Radio>
+				</RadioGroup>
+			</div>
+		</div>
+
+		<BaseSingle v-if="exersicesType==='Single'" ref="single" :editItem="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">
+			<IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:10px;"></IconText>
+			<div>
+				<div ref="analysisEditor" style="text-align:left"></div>
+			</div>
+		</div>
+
+		<!-- 补救的富文本部分 -->
+		<div class="exersices-analysis">
+			<IconText :text="'补救资源'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:10px"></IconText>
+			<Button type="info" class="btn-relate-content" @click="isRelatedContent = true">关联内容</Button>
+			<div>
+				<div ref="repairEditor" style="text-align:left"></div>
+			</div>
+			<!-- 显示关联的内容 -->
+			<div v-for="item in relateFileList" :key="item.id" style="margin:10px 0">
+				<span>
+					<Icon type="md-checkmark" color="#1BC6B0" size="20" /></span>
+				<span style="margin-left:10px">{{ item.fileName }}</span>
+			</div>
+		</div>
+
+		<div class="save-wrap display-flex">
+			<Button type="success" @click="getContent(exersicesType)" :loading="saveLoading">保存</Button>
+		</div>
+
+		<!-- 选择知识点弹窗 -->
+		<Modal v-model="selectPointsModal" :title="'选择知识点'" width="600px" class="related-point-modal" style="z-index:99999">
+			<BasePoints v-if="selectPointsModal" ref="pointRef" :period="schoolInfo.period[curPeriodIndex].periodCode" :subject="subjectList[curSubjectIndex].subjectCode"
+			 @onCheckChange="onCheckChange"></BasePoints>
+			<!--<CreateNewChild v-if="isLoadModal" ref="newChild" :isChildEdit="isChildEdit" :editItem="editChild"></CreateNewChild>-->
+			<div slot="footer">
+				<Button type="text" @click="selectPointsModal = false">取消</Button>
+				<Button type="primary" @click="selectPointsModal = false">确定</Button>
+			</div>
+		</Modal>
+
+		<!-- 关联内容弹窗 -->
+		<Modal v-model="isRelatedContent" width="880" footer-hide class="relate-modal related-modal">
+			<div class="modal-header" slot="header">内容关联</div>
+			<ChooseContent :showSyllabus="isFalse" :showOther="isFalse" :showQuestion="isFalse" v-if="isRelatedContent"
+			 @on-select-file="onSelectFile" @on-cancel-file="onSelectFile"></ChooseContent>
+
+			<Button class="modal-btn" :loading="isLoading" @click="onConfirmRelate">确认</Button>
+		</Modal>
+
+	</div>
+</template>
+<script>
+	import uploadFile from '@/utils/upload.js'
+	import 'videojs-contrib-hls.js/src/videojs.hlsjs'
+	import IconText from '@/components/evaluation/IconText.vue'
+	import BaseSingle from '@/view/evaluation/types/BaseSingle.vue'
+	import BaseMultiple from '@/view/evaluation/types/BaseMultiple.vue'
+	import BaseCompletion from '@/view/evaluation/types/BaseCompletion.vue'
+	import BaseJudge from '@/view/evaluation/types/BaseJudge.vue'
+	import BaseSubjective from '@/view/evaluation/types/BaseSubjective.vue'
+	import BasePoints from '@/view/evaluation/components/BasePoints'
+	import ChooseContent from '@/components/learnactivity/ChooseContent'
+	import E from 'wangeditor'
+	// 默认创建题目模板
+	const defaultExercise = {
+		question: '',
+		options: [],
+		level: 1,
+		answer: [],
+		explain: '',
+		type: ''
+	}
+	export default {
+		components: {
+			IconText,
+			BaseSingle,
+			BaseJudge,
+			BaseMultiple,
+			BaseCompletion,
+			BaseSubjective,
+			BasePoints,
+			ChooseContent
+		},
+		props: {
+			editItem: {
+				type: Object,
+				default: null
+			},
+			refId: {
+				type: String,
+				default: 'createChild'
+			},
+			curPeriodIndex:{
+				type:Number,
+				default:0
+			},
+			curSubjectIndex:{
+				type:Number,
+				default:0
+			}
+		},
+		data() {
+			return {
+				isRelatedContent: false,
+				selectPointsModal: false,
+				isEdit: false,
+				isFalse: false,
+				isLoading: false,
+				relateFileList: [],
+				editInfo: {},
+				schoolInfo: {},
+				saveLoading: false,
+				exersicesType: 'Single',
+				exerciseField: 0,
+				exercisePeriod: 0,
+				exerciseGrade: [],
+				exerciseSubject: 0,
+				exerciseScope: 0,
+				exercisePoints: [],
+				scopeList: ['个人题库', '校本题库'],
+				fieldList: ['知识', '理解', '应用', '分析', '综合', '评鉴'],
+				periodList: [],
+				gradeList: [],
+				subjectList: [],
+				exersicesDiff: '1',
+				analysisContent: '',
+				repairContent: '',
+				stemContent: '',
+				analysisEditor: null,
+				repairEditor: null,
+				defaultConfig: {
+					uploadImgShowBase64: true,
+					menus: this.$tools.wangEditorMenu
+				}
+			}
+		},
+		created() {
+			this.getSchoolInfo()
+		},
+		methods: {
+			getSchoolInfo() {
+				this.$store.dispatch('schoolBaseInfo/getSchoolBaseData').then(res => {
+					this.schoolInfo = res.data
+					if (res.data.period.length) {
+						this.gradeList = res.data.period[0].grades
+						this.subjectList = res.data.period[0].subjects
+					}
+
+				})
+			},
+
+			onSelectFile(val) {
+				this.relateFileList = val.files
+			},
+
+			onConfirmRelate() {
+				console.log(this.relateFileList)
+				this.isRelatedContent = false
+			},
+
+			async getContent(type) {
+				let exerciseItem = Object.assign({}, defaultExercise)
+				switch (type) {
+					case 'Single':
+						console.log(this.$refs.single)
+						exerciseItem.question = this.$refs.single.stemContent
+						exerciseItem.option = ((this.$refs.single.optionsContent.length === this.$refs.single.options.length) && this.checkOptionNull(
+							this.$refs.single.optionsContent)) ? this.$refs.single.optionsContent : null
+						exerciseItem.type = this.exersicesType
+						exerciseItem.level = +this.exersicesDiff
+						exerciseItem.explain = this.analysisContent
+						exerciseItem.answer = [String.fromCharCode(64 + parseInt(this.$refs.single.trueIndex + 1))]
+
+						break
+					case 'Multiple':
+						exerciseItem.question = this.$refs.multiple.stemContent
+						exerciseItem.option = ((this.$refs.multiple.optionsContent.length === this.$refs.multiple.options.length) &&
+							this.checkOptionNull(this.$refs.multiple.optionsContent)) ? this.$refs.multiple.optionsContent : null
+						exerciseItem.type = this.exersicesType
+						exerciseItem.level = +this.exersicesDiff
+						exerciseItem.explain = this.analysisContent
+						exerciseItem.answer = this.$refs.multiple.transferArr
+						break
+					case 'Judge':
+						exerciseItem.question = this.$refs.judge.stemContent
+						exerciseItem.option = []
+						exerciseItem.type = this.exersicesType
+						exerciseItem.level = +this.exersicesDiff
+						exerciseItem.explain = this.analysisContent
+						exerciseItem.answer = [this.$refs.judge.trueAnswer]
+						break
+					case 'Complete':
+						exerciseItem.question = this.$refs.complete.stemContent
+						exerciseItem.option = []
+						exerciseItem.type = this.exersicesType
+						exerciseItem.level = +this.exersicesDiff
+						exerciseItem.explain = this.analysisContent
+						exerciseItem.answer = this.$refs.complete.optionsContent.map(item => item.value)
+						break
+					case 'Subjective':
+						exerciseItem.question = this.$refs.subjective.stemContent
+						exerciseItem.option = []
+						exerciseItem.type = this.exersicesType
+						exerciseItem.level = +this.exersicesDiff
+						exerciseItem.explain = this.analysisContent
+						exerciseItem.answer = [this.$refs.subjective.answerContent]
+						break
+				}
+				exerciseItem.repair = this.repairContent
+				exerciseItem.repairResource = this.relateFileList
+				exerciseItem.field = this.fieldList[this.exerciseField]
+				exerciseItem.points = this.exercisePoints.map(item => item.id)
+				exerciseItem.code = this.$parent.$parent.exerciseScope === 0 ? this.$store.state.userInfo.TEAMModelId : this.$store
+					.state.userInfo.schoolCode
+
+				// 判断获取的数据是否有空数据以及是否为空字符串
+				if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(
+						exerciseItem.explain)) {
+					// this.saveLoading = true
+					this.$emit('addFinish', exerciseItem)
+				} else {
+					console.log(exerciseItem)
+					this.$Message.warning('请将题目填写完整!')
+				}
+			},
+
+			/* 知识点勾选变动事件 */
+			onCheckChange(val, list) {
+				this.exercisePoints = []
+				val.forEach(item => {
+					this.exercisePoints.push(list.filter(point => point.id === item)[0])
+				})
+			},
+
+			/**
+			 * 移除指定知识点
+			 * @param index
+			 */
+			onDeletePoint(index) {
+				this.exercisePoints.splice(index, 1)
+				this.$refs.pointRef.$children[1].onDeletePoint(index)
+			},
+
+			// 题目类型转换
+			typeChange(val) {
+				if (this.isEdit) {
+					this.$Message.warning('暂不支持更换题型!')
+				} else if (val === 'Compose') {
+					this.$router.push({
+						name: 'createCompose'
+					})
+				} else {
+					this.exersicesType = val
+					this.analysisEditor.txt.clear()
+					this.repairEditor.txt.clear()
+				}
+			},
+			
+			// 重置本页面
+			doReset(){
+				this.exerciseField = 0
+				this.exercisePoints = []
+				this.exersicesDiff = '1'
+				this.exersicesType = 'Single'
+				this.analysisEditor.txt.clear()
+				this.repairEditor.txt.clear()
+				this.editInfo = null
+			},
+
+			// 难度与背景颜色切换
+			diffChange(e, type) {
+				this.exersicesDiff = +type
+				e.preventDefault()
+				let colorArr = ['#10abe7', '#E8BE15', '#F19300', '#EB5E00', '#D30000']
+				let ac = document.getElementById(this.refId).getElementsByClassName('edit-exersices-attr-diff')[0].children[1].children
+				for (let i = 0; i < ac.length; i++) {
+					ac[i].style.background = '#fff'
+					ac[i].style.color = '#515a6e'
+				}
+				e.target.style.background = colorArr[type - 1]
+				e.target.style.color = '#fff'
+			},
+
+			// 提取富文本内容中的文本
+			getSimpleText(html) {
+				var msg = html.replace(/<(?!img).*?>/g, '') // 执行替换成空字符
+				return msg.replace(/&nbsp;/ig, '')
+			},
+
+			/* 检测数组是否有空数据 */
+			checkOptionNull(arr) {
+				let flag = true
+				for (let i = 0; i < arr.length; i++) {
+					if (this.getSimpleText(arr[i].value) === '') {
+						flag = false
+					}
+				}
+				return flag
+			},
+
+			// 排除对象空属性
+			checkContent(Obj) {
+				let flag = true
+				let whiteList = this.getWhiteListByType(Obj.type)
+				console.log('验证的')
+				console.log(Obj)
+				for (let key in Obj) {
+					if (whiteList.includes(key) && typeof Obj[key] === 'string') {
+						if (!this.getSimpleText(Obj[key])) {
+							console.log(key)
+							flag = false
+						}
+					} else if (whiteList.includes(key) && key === 'answer') {
+						if (Obj[key].length === 0) {
+							console.log(key)
+							flag = false
+						}
+					} else {
+						if (whiteList.includes(key) && !Obj[key]) {
+							console.log(key)
+							flag = false
+						}
+					}
+				}
+				return flag
+			},
+
+			// 根据不同题型 给出需要必填选项
+			getWhiteListByType(type) {
+				switch (type) {
+					case 'Single':
+						return ['question', 'option', 'answer', 'explain', 'repair']
+						break;
+					case 'Multiple':
+						return ['question', 'option', 'answer', 'explain', 'repair']
+						break;
+					case 'Complete':
+						return ['question', 'answer', 'explain', 'repair']
+						break;
+					default:
+						return ['question', 'answer', 'explain', 'repair']
+						break;
+				}
+			},
+
+
+			/**
+			 * 根据知识点id集合换取知识点对象集合
+			 * @param ids
+			 */
+			getPointsByIds(ids) {
+				return new Promise((r, j) => {
+					if (ids.length) {
+						this.$api.knowledge.FindKnowledgebyId(ids).then(res => {
+							if (!res.error && res.result.data.length) {
+								r(res.result.data)
+							} else {
+								r([])
+							}
+						}).catch(err => {
+							j(err)
+						})
+					} else {
+						r([])
+					}
+				})
+			},
+
+			// 渲染编辑习题内容回显
+			async renderExercise(editItem) {
+				console.log('render')
+				let schoolInfo = this.$store.state.schoolBaseInfo.schoolBaseInfo
+				this.isEdit = true
+				if (!editItem.options) editItem.options = editItem.option
+				this.exersicesDiff = editItem.level.toString() || '0'
+				this.exerciseScope = editItem.code === this.$store.state.userInfo.TEAMModelId ? 0 : 1
+				this.exersicesType = editItem.type
+				this.exerciseField = this.fieldList.indexOf(editItem.field)
+				this.exercisePoints = await this.getPointsByIds(editItem.points)
+
+				if (editItem.level) {
+					console.log(document.getElementById(this.refId))
+					let ac = document.getElementById(this.refId).getElementsByClassName('edit-exersices-attr-diff')[0].children[1].children
+					for (let i = 0; i < ac.length; i++) {
+						ac[i].style.background = '#fff'
+						ac[i].style.color = '#515a6e'
+					}
+					// 重新渲染题目难度
+					let diffDom = document.getElementById(this.refId).getElementsByClassName('edit-exersices-attr-diff')[0].children[
+						1].children[editItem.level - 1]
+					let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000']
+					diffDom.style.background = colorArr[editItem.level - 1]
+					diffDom.style.color = '#fff'
+				} else {
+					let ac = document.getElementById(this.refId).getElementsByClassName('edit-exersices-attr-diff')[0].children[1].children
+					for (let i = 0; i < ac.length; i++) {
+						ac[i].style.background = '#fff'
+						ac[i].style.color = '#515a6e'
+					}
+				}
+
+				this.childList = editItem.children || []
+
+				this.schoolInfo = schoolInfo
+
+				this.stemContent = editItem.question
+				this.relateFileList = editItem.repairResource || []
+				this.optionsContent = editItem.option
+				this.analysisContent = editItem.explain
+				this.repairContent = editItem.repair
+				this.analysisEditor.txt.html(editItem.explain)
+				this.repairEditor.txt.html(editItem.repair)
+
+				this.editInfo = editItem
+			}
+		},
+		mounted() {
+			let analysisEditor = new E(this.$refs.analysisEditor)
+			analysisEditor.customConfig = this.defaultConfig
+			analysisEditor.customConfig.onchange = (html) => {
+					this.analysisContent = html
+				},
+				analysisEditor.create()
+			this.analysisEditor = analysisEditor
+
+
+			let repairEditor = new E(this.$refs.repairEditor)
+			repairEditor.customConfig = this.defaultConfig
+			repairEditor.customConfig.onchange = (html) => {
+					this.repairContent = html
+				},
+				repairEditor.create()
+			this.repairEditor = repairEditor
+		},
+		watch: {
+			editItem: {
+				handler(newValue, oldValue) {
+					if (newValue) {
+						console.log("要编辑的小题")
+						console.log(newValue)
+						this.renderExercise(JSON.parse(JSON.stringify(newValue)))
+						// this.$refs.pointRef.doReset()
+					}
+				},
+				//immediate:true
+			},
+		}
+	}
+</script>
+<style src="../index/CreateExercises.less" lang="less" scoped>
+</style>
+
+<style>
+	.related-point-modal .ivu-modal-content {
+		font-family: '微軟正黑體', 'Heiti TC';
+	}
+
+	.related-point-modal .ivu-modal-header-inner {
+		font-weight: bold;
+	}
+
+
+	.exersices-attr .ivu-select-multiple .ivu-tag {
+		height: 32px;
+		line-height: 31px;
+	}
+
+	.exersices-attr .ivu-select-multiple .ivu-tag i {
+		top: 9px;
+	}
+
+	.exersices-attr .ivu-select-multiple .ivu-select-selection .ivu-select-placeholder {
+		line-height: 38px;
+	}
+
+	/* 修改iview Modal样式 */
+
+	.related-modal .ivu-modal-content {
+		background: #3c3c3c;
+		overflow: hidden;
+		color: #fff;
+		font-family: '微軟正黑體', 'Heiti TC' !important;
+	}
+
+	.related-modal .ivu-modal-body {
+		height: 400px;
+		padding: 20px;
+	}
+
+	.related-modal .ivu-modal-body {
+		height: 700px;
+	}
+
+	.related-modal .ivu-modal-header {
+		border-bottom: none;
+		font-size: 18px;
+		font-weight: bold;
+		padding: 25px;
+	}
+
+	.related-modal .modal-content {
+		padding: 0 35px 30px 35px;
+	}
+
+	.related-modal .modal-btn {
+		margin-left: 2%;
+		width: 96%;
+		height: 40px;
+		background: rgb(11, 151, 117);
+		border: none;
+		color: #fff;
+		margin-top: 30px;
+	}
+
+	.related-modal .choose-content {
+		height: 85%;
+	}
+</style>

File diff suppressed because it is too large
+ 631 - 570
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseEditExercise.vue


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

@@ -28,7 +28,7 @@
         display: flex;
         flex-direction: row;
         align-items: center;
-        justify-content:start;
+        justify-content:flex-start;
     }
 
 .ev-container .btn-back-to-bank {
@@ -260,6 +260,23 @@ exersices-attr-diff {
     font-size:16px;
 }
 
+.ev-container .child-list-wrap{
+	margin: 20px 0;
+	
+	.child-item{
+		padding: 20px 10px;
+		
+		&-question{
+			font-size: 14px;
+			
+			&-content{
+				display: inline-block;
+				margin-left: 5px;
+			}
+		}
+	}
+}
+
 
 .save-wrap {
     width:100%;

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

@@ -57,7 +57,7 @@
                     <Radio label="Judge" :disabled="isEdit">判断</Radio>
                     <Radio label="Complete" :disabled="isEdit">填空</Radio>
                     <Radio label="Subjective" :disabled="isEdit">问答</Radio>
-                    <!--<Radio label="Compose" :disabled="isEdit">综合</Radio>-->
+                    <Radio label="Compose" :disabled="isEdit">综合</Radio>
                 </RadioGroup>
             </div>
             <div class="exersices-attr-diff my-radio-style">
@@ -77,9 +77,10 @@
         <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>
+        <BaseCompose v-else-if="exersicesType==='Compose'" ref="compose" :editInfo="editInfo"></BaseCompose>
 
         <!-- 解析的富文本部分 -->
-        <div class="exersices-analysis">
+        <div class="exersices-analysis" v-show="exersicesType !== 'Compose'">
             <IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:10px;"></IconText>
             <!-- <Upload action="/api/file/uploadWangEditor" name="files" :show-upload-list="false" :on-success="handleSuccess">
                 <Button icon="ios-cloud-upload-outline" class="btn-upload" type="info">上传文件</Button>
@@ -90,7 +91,7 @@
         </div>
 
         <!-- 补救的富文本部分 -->
-        <div class="exersices-analysis">
+        <div class="exersices-analysis" v-show="exersicesType !== 'Compose'">
             <IconText :text="'补救资源'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:10px"></IconText>
             <Button type="info" class="btn-relate-content" @click="isRelatedContent = true">关联内容</Button>
             <!-- <Upload action="/api/file/uploadWangEditor" name="files" :show-upload-list="false" :on-success="handleRepairSuccess">
@@ -106,10 +107,21 @@
                 <span style="margin-left:10px">{{ item.fileName }}</span>
             </div>
         </div>
+		
+		<!-- 小题展示区域 -->
+		<div class="child-list-wrap" v-show="exersicesType === 'Compose' && childList.length">
+			<IconText :text="'小题列表'" :color="'#00b8ff'" :icon="'md-list'"></IconText>
+			<div class="child-item" v-for="(item,index) in childList" :key="index">
+				<div class="child-item-question">
+					<span>({{ index + 1}})</span>
+					<p class="child-item-question-content" v-html="item.question"></p>
+				</div>
+			</div>
+		</div>
 
         <div class="save-wrap display-flex">
+			<Button type="info" @click="onAddChild" style="margin-right:10px" v-show="exersicesType === 'Compose'">添加小题</Button>
             <Button type="success" @click="getContent(exersicesType)" :loading="saveLoading">保存</Button>
-            <!--<Button type="success" @click="reloadCreate" style="margin-left:10px" v-show="isEdit">新增习题</Button>-->
         </div>
 
         <Button type="success" @click="backToBank" class="btn-back-to-bank" style="margin-left:10px">返回题库</Button>
@@ -135,11 +147,18 @@
             <ChooseContent :showSyllabus="isFalse"
                            :showOther="isFalse"
                            :showQuestion="isFalse"
+						   v-if="isRelatedContent"
                            @on-select-file="onSelectFile"
                            @on-cancel-file="onSelectFile"></ChooseContent>
 
             <Button class="modal-btn" :loading="isLoading" @click="onConfirmRelate">确认</Button>
         </Modal>
+		
+		<!-- 添加小题弹窗 -->
+		<Modal v-model="addComposeChildModal" width="1080" footer-hide class="">
+		    <div class="modal-header" slot="header">添加小题</div>
+		    <BaseCreateChild @addFinish='onAddChildFinish' ref='createAddChild' v-if="addComposeChildModal"></BaseCreateChild>
+		</Modal>
 
     </div>
 </template>
@@ -152,7 +171,9 @@
     import BaseCompletion from '@/view/evaluation/types/BaseCompletion.vue'
     import BaseJudge from '@/view/evaluation/types/BaseJudge.vue'
     import BaseSubjective from '@/view/evaluation/types/BaseSubjective.vue'
+    import BaseCompose from '@/view/evaluation/types/BaseCompose.vue'
     import BasePoints from '@/view/evaluation/components/BasePoints'
+    import BaseCreateChild from '@/view/evaluation/components/BaseCreateChild'
     import ChooseContent from '@/components/learnactivity/ChooseContent'
     import E from 'wangeditor'
     // 默认创建题目模板
@@ -166,12 +187,13 @@
     }
     export default {
         components: {
-            IconText, BaseSingle, BaseJudge, BaseMultiple, BaseCompletion, BaseSubjective, BasePoints,ChooseContent
+            IconText, BaseSingle, BaseJudge, BaseMultiple, BaseCompletion, BaseSubjective, BaseCompose, BasePoints,ChooseContent,BaseCreateChild
         },
         data() {
             return {
                 isRelatedContent:false,
                 selectPointsModal: false,
+				addComposeChildModal:false,
                 isEdit: false,
                 isFalse: false,
                 isLoading: false,
@@ -191,6 +213,7 @@
                 periodList: [],
                 gradeList: [],
                 subjectList: [],
+				childList:[],
                 exersicesDiff: '1',
                 analysisContent: '',
                 repairContent: '',
@@ -277,6 +300,16 @@
                         exerciseItem.explain = this.analysisContent
                         exerciseItem.answer = [this.$refs.subjective.answerContent]
                         break
+					case 'Compose':
+					    exerciseItem.question = this.$refs.compose.stemContent
+					    exerciseItem.option = []
+					    exerciseItem.type = this.exersicesType
+					    exerciseItem.level = +this.exersicesDiff
+					    exerciseItem.explain = this.analysisContent
+					    exerciseItem.children = this.childList
+					    break
+					default:
+						break
                 }
                 exerciseItem.id = this.editInfo.id ? this.editInfo.id : ''
                 exerciseItem.repair = this.repairContent
@@ -289,7 +322,7 @@
                 exerciseItem.code = this.exerciseScope === 0 ? this.$store.state.userInfo.TEAMModelId : this.schoolInfo.schoolCode
 
                 // 判断获取的数据是否有空数据以及是否为空字符串
-                if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(exerciseItem.explain)) {
+                if (this.checkContent(exerciseItem)) {
 					this.saveLoading = true
 					// 首先保存新题目的JSON文件到Blob 然后返回URL链接
 					let file = new File([JSON.stringify(exerciseItem)], this.$tools.guid() + ".json", {type: ""});
@@ -315,6 +348,7 @@
 					console.log(exerciseItem)
                     this.$Message.warning('请将题目填写完整!')
                 }
+				
             },
 			
 			/* 保存单个试题 */
@@ -332,6 +366,20 @@
                 })
             },
 			
+			/* 添加小题 重置新增页面 */
+			onAddChild(){
+				this.addComposeChildModal = true
+				if(this.$refs.createAddChild) this.$refs.createAddChild.doReset()
+			},
+			
+			/* 添加小题完成 */
+			onAddChildFinish(item){
+				console.log('获取到小题')
+				console.log(item)
+				this.addComposeChildModal = false
+				this.childList.push(item)
+			},
+			
 			/* 知识点勾选变动事件 */
             onCheckChange(val, list) {
                 this.exercisePoints = []
@@ -353,12 +401,9 @@
             typeChange(val) {
                 if (this.isEdit) {
                     this.$Message.warning('暂不支持更换题型!')
-                } else if (val === 'Compose') {
-                    this.$router.push({
-                        name: 'createCompose'
-                    })
                 } else {
                     this.exersicesType = val
+					this.childList = []
                     this.analysisEditor.txt.clear()
                     this.repairEditor.txt.clear()
                 }
@@ -388,7 +433,7 @@
 
             // 提取富文本内容中的文本
             getSimpleText(html) {
-                var msg = html.replace(/<(?!video).*?>/g, '')// 执行替换成空字符
+                var msg = html.replace(/<(?!img).*?>/g, '')// 执行替换成空字符
                 return msg.replace(/&nbsp;/ig, '')
             },
 			
@@ -457,6 +502,9 @@
 					case 'Complete':
 						return ['question','answer','explain','repair']
 						break;
+					case 'Compose':
+						return ['question']
+						break;	
 					default:
 						return ['question','answer','explain','repair']
 						break;

+ 71 - 63
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -65,7 +65,7 @@
                         <TabPane label="试题预览" name="preview" :index="4" tab="createTest">
                             <!--<TeacherPreview :testPaper="evaluationInfo.testPaper[currentSubjectIndex]" :paperName="evaluationInfo.name"></TeacherPreview>-->
                             <vuescroll>
-                                <TestPaper v-if="!examAnalysisStatus" :paper="evaluationInfo" :class="examAnalysisStatus ? '':'animated fadeIn'"></TestPaper>
+                                <TestPaper v-if="!examAnalysisStatus" :paper="evaluationInfo" :class="examAnalysisStatus ? '':'animated fadeIn'" ref="testPaper"></TestPaper>
                                 <ExamPaperAnalysis :class="examAnalysisStatus ? 'animated fadeIn':''" v-show="examAnalysisStatus" ref="examPaperAnalysis" :testPaper="evaluationInfo"></ExamPaperAnalysis>
                             </vuescroll>
                         </TabPane>
@@ -261,69 +261,77 @@
            
             /** 保存当前试卷数据 */
             async saveTestPaper() {
-				
-                if (this.evaluationInfo.item.length) {
-                    let code = this.evaluationInfo.type === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
-					let isEdit = Boolean(this.evaluationInfo.id)
-					let fileName = isEdit ? this.evaluationInfo.fileName : this.$tools.guid()
-					
-                    this.isLoading = true
-                    this.evaluationInfo.item.forEach(i => { i.code = code })
-                    let requestData = {
-                        code: code,
-                        gradeCode: this.evaluationInfo.paperGrade.length ? this.evaluationInfo.paperGrade : this.gradeList.map(i => i.gradeCode),
-                        subjectCode: this.subjectList[this.evaluationInfo.paperSubject].subjectCode,
-                        periodCode: this.schoolInfo.period[this.evaluationInfo.paperPeriod].periodCode,
-                        name: this.evaluationInfo.name,
-                        item: this.evaluationInfo.item,
-						markConfig:this.evaluationInfo.markConfig,
-						answers:this.getAnswers(this.evaluationInfo.item),
-                        score: this.evaluationInfo.score
-                    }
-					console.log(requestData)
-					if(this.evaluationInfo.id){
-						requestData.id = this.evaluationInfo.id
-					}
-					// 首先保存新题目的JSON文件到Blob 然后返回URL链接
-					let file = new File([JSON.stringify(requestData)], fileName + ".json", {type: ""});
-					// 根据题目类型 传到不同容器
-					let fileType = this.evaluationInfo.type
-					// 等待上传blob的返回结果
-					try{
-						let blobFile = await uploadFile.uploadFile(file,'paper',fileType)
-						if(blobFile.blobUrl){
-							// 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
-							requestData.url = blobFile.blobUrl
-							delete requestData.item
-							delete requestData.answers
-							this.$api.learnActivity.SaveExamPaper(requestData).then(
-							    res => {
-							        if (res.error == null) {
-							            this.$Message.success( isEdit ? '编辑成功' : '保存成功')
-							            this.isLoading = false
-							            this.$router.push({
-							                name: 'testPaperList',
-							                params: {
-							                    tabName: 'paper'
-							                }
-							            })
-							        } else {
-							            this.$Message.error('API ERROR!')
-							        }
-							    },
-							    err => {
-							        this.$Message.error('API ERROR!')
-							    }
-							)
+				let hasSurplus = this.$refs.testPaper.$refs.exList.surPlusScore === 0 // 判断是否有剩余分数未分配
+				let noScoreList = this.$refs.testPaper.$refs.exList.exerciseList.filter(item => item.score === 0) // 判断是否有未配分的题目
+				if(hasSurplus){
+					if (!noScoreList.length) {
+						if (this.evaluationInfo.item.length) {
+						    let code = this.evaluationInfo.type === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
+							let isEdit = Boolean(this.evaluationInfo.id)
+							let fileName = isEdit ? this.evaluationInfo.fileName : this.$tools.guid()
+							
+						    this.isLoading = true
+						    this.evaluationInfo.item.forEach(i => { i.code = code })
+						    let requestData = {
+						        code: code,
+						        gradeCode: this.evaluationInfo.paperGrade.length ? this.evaluationInfo.paperGrade : this.gradeList.map(i => i.gradeCode),
+						        subjectCode: this.subjectList[this.evaluationInfo.paperSubject].subjectCode,
+						        periodCode: this.schoolInfo.period[this.evaluationInfo.paperPeriod].periodCode,
+						        name: this.evaluationInfo.name,
+						        item: this.evaluationInfo.item,
+								markConfig:this.evaluationInfo.markConfig,
+								answers:this.getAnswers(this.evaluationInfo.item),
+						        score: this.evaluationInfo.score
+						    }
+							console.log(requestData)
+							if(this.evaluationInfo.id){
+								requestData.id = this.evaluationInfo.id
+							}
+							// 首先保存新题目的JSON文件到Blob 然后返回URL链接
+							let file = new File([JSON.stringify(requestData)], fileName + ".json", {type: ""});
+							// 根据题目类型 传到不同容器
+							let fileType = this.evaluationInfo.type
+							// 等待上传blob的返回结果
+							try{
+								let blobFile = await uploadFile.uploadFile(file,'paper',fileType)
+								if(blobFile.blobUrl){
+									// 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
+									requestData.url = blobFile.blobUrl
+									delete requestData.item
+									delete requestData.answers
+									this.$api.learnActivity.SaveExamPaper(requestData).then(
+									    res => {
+									        if (res.error == null) {
+									            this.$Message.success( isEdit ? '编辑成功' : '保存成功')
+									            this.isLoading = false
+									            this.$router.push({
+									                name: 'testPaperList',
+									                params: {
+									                    tabName: 'paper'
+									                }
+									            })
+									        } else {
+									            this.$Message.error('API ERROR!')
+									        }
+									    },
+									    err => {
+									        this.$Message.error('API ERROR!')
+									    }
+									)
+								}
+							}catch(e){
+								this.$Message.error('上传失败!')
+							}
+						} else {
+						    this.$Message.warning('未选择任何试题!')
 						}
-					}catch(e){
-						this.$Message.error('上传失败!')
+					}else {
+						this.$Message.warning(`存在未配分的题目,请配分后再保存!`)
 					}
-					
-                    
-                } else {
-                    this.$Message.warning('未选择任何试题!')
-                }
+				}else {
+					this.$Message.warning(`试卷配分未完成!剩余 ${this.$refs.testPaper.$refs.exList.surPlusScore} 分数可分配`)
+				}
+                
             },
 			
 			/* 获取整张试卷的答案合计Answers */
@@ -353,7 +361,7 @@
 				return arr
 			},
             
-			
+			/* 渲染需要编辑的试卷信息 */
 			async doRender(paper){
 				console.log('传进来的paper')
 				console.log(paper)

+ 0 - 267
TEAMModelOS/ClientApp/src/view/evaluation/index/EditChild.vue

@@ -1,267 +0,0 @@
-<template>
-  <div class="ev-container">
-    <span class="ev-title"><Icon type="ios-paper"/>{{isEdit?'编辑习题':'新建习题'}}</span>
-    <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>
-          <Radio label="Compose" :disabled="isEdit">综合</Radio>
-        </RadioGroup>
-      </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>
-          <Radio label="3" @click.native="diffChange($event,'3')">较难</Radio>
-          <Radio label="4" @click.native="diffChange($event,'4')">困难</Radio>
-        </RadioGroup>
-      </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>
-
-    <div class="exersices-analysis">
-      <IconText :text="'解析'" :color="'#2892DD'" :icon="'md-list'" style="margin-bottom:15px;"></IconText>
-      <Upload action="/api/file/uploadWangEditor" name="files" :show-upload-list="false" :on-success="handleSuccess">
-        <Button icon="ios-cloud-upload-outline" class="btn-upload" type="info">上传文件</Button>
-      </Upload>
-      <div>
-        <div ref="analysisEditor" style="text-align:left"></div>
-      </div>
-    </div>
-    <div class="save-wrap display-flex">
-      <Button type="success" @click="getContent(exersicesType)">保存</Button>
-      <Button type="success" @click="reloadCreate" style="margin-left:10px" v-show="isEdit">新增习题</Button>
-      <Button type="success" @click="resetEditor" style="margin-left:10px">题库</Button>
-    </div>
-  </div>
-</template>
-<script>
-  import 'videojs-contrib-hls.js/src/videojs.hlsjs'
-  import IconText from '@/components/evaluation/IconText.vue'
-  import BaseSingle from '@/view/evaluation/types/BaseSingle.vue'
-  import BaseMultiple from '@/view/evaluation/types/BaseMultiple.vue'
-  import BaseCompletion from '@/view/evaluation/types/BaseCompletion.vue'
-  import BaseJudge from '@/view/evaluation/types/BaseJudge.vue'
-  import BaseSubjective from '@/view/evaluation/types/BaseSubjective.vue'
-  import E from 'wangeditor'
-  // 默认创建题目模板
-  const defaultExercise = {
-    question: '',
-    options: [],
-    difficulty: '',
-    answer: [],
-    explain: '',
-    type: ''
-  }
-  export default {
-    components: {
-      IconText, BaseSingle, BaseJudge, BaseMultiple, BaseCompletion, BaseSubjective
-    },
-    data() {
-      return {
-        isEdit: false,
-        editInfo: {},
-        exersicesType: 'Single',
-        exersicesDiff: '0',
-        analysisContent: '',
-        stemContent: '',
-        analysisEditor: null,
-        videoHtml: '',
-        playerOptions: {
-          playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度
-          autoplay: false, // 如果true,浏览器准备好时开始回放。
-          controls: true, // 控制条
-          preload: 'auto', // 视频预加载
-          muted: false, // 默认情况下将会消除任何音频。
-          loop: false, // 导致视频一结束就重新开始。
-          language: 'zh-CN',
-          aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
-          fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。
-          sources: [{
-            // type: 'application/x-mpegURL',
-            src: 'https://teammodelstorage.blob.core.chinacloudapi.cn/teammodelcontest/20190517/history/history.m3u8'
-          }],
-          // poster: "http://static.smartisanos.cn/pr/img/video/video_03_cc87ce5bdb.jpg", //你的封面地址
-          width: document.documentElement.clientWidth,
-          notSupportedMessage: '此视频暂无法播放,请稍后再试' // 允许覆盖Video.js无法播放媒体源时显示的默认信息。
-        }
-      }
-    },
-    created() {
-      let editItem = this.$route.params.item // 编辑题目
-      if (editItem) {
-        this.editInfo = editItem
-        console.log(editItem)
-      }
-    },
-    methods: {
-      getContent: function(type) {
-        let exerciseItem = Object.assign({}, defaultExercise)
-        switch (type) {
-          case 'Single':
-            exerciseItem.question = this.$refs.single._data.stemContent
-            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.difficulty = this.exersicesDiff
-            exerciseItem.explain = this.analysisContent
-            exerciseItem.answer = [String.fromCharCode(64 + parseInt(this.$refs.single._data.trueIndex + 1))]
-            break
-          case 'Multiple':
-            exerciseItem.question = this.$refs.multiple._data.stemContent
-            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.difficulty = this.exersicesDiff
-            exerciseItem.explain = this.analysisContent
-            exerciseItem.answer = this.$refs.multiple._data.transferArr
-            break
-          case 'Judge':
-            exerciseItem.question = this.$refs.judge._data.stemContent
-            exerciseItem.option = []
-            exerciseItem.type = this.exersicesType
-            exerciseItem.difficulty = this.exersicesDiff
-            exerciseItem.explain = this.analysisContent
-            exerciseItem.answer = this.$refs.judge._data.trueAnswer
-            break
-          case 'Complete':
-            exerciseItem.question = this.$refs.complete._data.stemContent
-            exerciseItem.option = []
-            exerciseItem.type = this.exersicesType
-            exerciseItem.difficulty = this.exersicesDiff
-            exerciseItem.explain = this.analysisContent
-            exerciseItem.answer = this.$refs.complete._data.optionsContent.map(item => item.value)
-            break
-          case 'Subjective':
-            exerciseItem.question = this.$refs.subjective._data.stemContent
-            exerciseItem.option = []
-            exerciseItem.type = this.exersicesType
-            exerciseItem.difficulty = this.exersicesDiff
-            exerciseItem.explain = this.analysisContent
-            exerciseItem.answer = this.$refs.subjective._data.answerContent
-            break
-        }
-
-        // 判断获取的数据是否有空数据以及是否为空字符串
-        if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(exerciseItem.explain)) {
-          this.$router.push({
-            name: 'exercisesList',
-            params: {
-              exerciseItem: exerciseItem
-            }
-          })
-        } else {
-          this.$Message.warning('请将题目填写完整!')
-        }
-
-        console.log(exerciseItem)
-      },
-
-      // 题目类型转换
-      typeChange(val) {
-        if (this.isEdit) {
-          this.$Message.warning('暂不支持更换题型!')
-        } else if (val === 'Compose') {
-          this.$router.push({
-            name: 'createCompose'
-          })
-        } else {
-          this.exersicesType = val
-          this.analysisEditor.txt.clear()
-        }
-      },
-
-      // 难度与背景颜色切换
-      diffChange(e, type) {
-        this.exersicesDiff = type
-        e.preventDefault()
-        let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000']
-        let ac = document.getElementsByClassName('exersices-attr-diff')[0].children[1].children
-        for (let i = 0; i < ac.length; i++) {
-          ac[i].style.background = '#fff'
-          ac[i].style.color = '#515a6e'
-        }
-        e.target.style.background = colorArr[type]
-        e.target.style.color = '#fff'
-      },
-
-      // 提取富文本内容中的文本
-      getSimpleText(html) {
-        var msg = html.replace(/<(?!img|video).*?>/g, '')// 执行替换成空字符
-        return msg.replace(/&nbsp;/ig, '')
-      },
-      // 排除对象空属性
-      checkContent(Obj) {
-        let flag = true
-        for (let key in Obj) {
-          if (!Obj[key]) {
-            flag = false
-          }
-        }
-        return flag
-      },
-
-      // 重置编辑器
-      resetEditor() {
-        this.$router.push({
-            name: 'exercisesList'
-          })
-      },
-
-      reloadCreate() {
-        location.reload()
-      },
-
-      // 文件上传成功回调
-      handleSuccess(res, file) {
-        this.videoHtml = "<br><iframe src='https://teammodelstorage.blob.core.chinacloudapi.cn/wechatfilescontainer/wechatfilescontainer/HilearningMobile_function_10.mp4' frameborder='0' allowfullscreen='true'></iframe><br>"
-        this.analysisContent = this.analysisContent + this.videoHtml
-        this.analysisEditor.txt.append(this.videoHtml)
-        console.log(this.analysisContent)
-      }
-
-    },
-    mounted() {
-      let analysisEditor = new E(this.$refs.analysisEditor)
-      analysisEditor.customConfig.onchange = (html) => {
-        this.analysisContent = html
-      },
-      analysisEditor.customConfig.uploadImgServer = '/api/file/uploadWangEditor'
-      analysisEditor.customConfig.showLinkImg = false
-      analysisEditor.customConfig.uploadFileName = 'files'
-      analysisEditor.create()
-      this.analysisEditor = analysisEditor
-
-      let editItem = this.$route.params.item // 编辑题目
-      if (editItem) {
-        this.isEdit = true
-        this.editInfo = editItem
-        this.exersicesDiff = editItem.difficulty || 0
-        this.exersicesType = editItem.type
-        this.stemContent = editItem.question
-        this.optionsContent = editItem.options
-        this.analysisContent = editItem.explain
-        this.analysisEditor.txt.html(editItem.explain)
-        // 重新渲染题目难度
-        let diffDom = document.getElementsByClassName('exersices-attr-diff')[0].getElementsByClassName('ivu-radio-wrapper')[editItem.difficulty]
-        let colorArr = ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000']
-        diffDom.style.background = colorArr[editItem.difficulty]
-        diffDom.style.color = '#fff'
-      }
-    }
-  }
-</script>
-<style src="../index/CreateExercises.less" lang="less" scoped>
-  /*@import"../index/CreateExercises.css";*/
-</style>

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

@@ -165,6 +165,10 @@
     cursor: pointer;
 }
 
+	.exercise-item img{
+		vertical-align: middle;
+	}
+
     .exercise-item .item-question .item-btn-toggle {
         position: absolute;
         right: 0;

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

@@ -17,8 +17,8 @@
 							<span class="base-info-item">难度:<span class="analysis-info">{{ paperInfo.item.length ? paperDiff : 0 }}</span></span>
 						</div>
 						<div>
-							<Button class="base-info-btn" type="success" v-show="isShowSave" @click="onBackToBank">返回</Button>
-							<Button class="base-info-btn" type="success" v-show="isShowSave" @click="savePaper">保存试卷</Button>
+							<!-- <Button class="base-info-btn" type="success" v-show="isShowSave" @click="onBackToBank">返回</Button> -->
+							<!-- <Button class="base-info-btn" type="success"  @click="savePaper">保存试卷</Button> -->
 							<Button class="base-info-btn" type="info" @click="onHandleToggle" v-show="paperInfo.item.length">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button>
 							<Button class="base-info-btn" type="info" @click="onSetScoreByType" v-show="paperInfo.item.length">题型配分</Button>
 							<!-- <Button class="base-info-btn" type="info" @click="isSetRules = true" v-show="paperInfo.item.length">阅卷规则</Button> -->
@@ -398,7 +398,7 @@
 
 		},
 		mounted() {
-			this.isShowSave = window.location.pathname === '/home/evaluation/testPaper'
+			// this.isShowSave = window.location.pathname === '/home/evaluation/testPaper'
 			let paper = this.paper || this.$route.params.paper || JSON.parse(localStorage.getItem('_paperInfo'))
 			if (!paper) return
 			localStorage.setItem('_paperInfo', JSON.stringify(paper))

+ 17 - 14
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompletion.vue

@@ -1,7 +1,7 @@
 <template>
     <div>
         <div class="exersices-content">
-            <span class="add-underline"><Button type="primary" @click="addOption()">添加填空横线</Button></span>
+            <span class="add-underline"><Button type="primary" @click="addOption()" v-show="isStemFocus">添加填空横线</Button></span>
             <IconText :text="'题目'" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
             <div>
                 <div ref="completionEditor" id="completionEditor" style="text-align:left"></div>
@@ -32,6 +32,7 @@
                 options: [],
                 optionsContent: [],
                 initFlag: true,
+				isStemFocus:false,
                 trueIndex: 0,
                 stemContent: '',
                 stemEditor: null,
@@ -88,8 +89,6 @@
 					let addHtml = "&nbsp;<span class='complete-line' data-index=" + newIndex + ' data-answer=' + newIndex + " contenteditable='false'>&#93" + (newLineIndex + 12) + '</span>&nbsp;'
 					this.stemEditor.cmd.do('insertHTML', addHtml)
 					this.stemContent = this.stemContent + addHtml
-					console.log(this.stemContent)
-					console.log(this.optionsIndexArr)
 					this.$nextTick(() => {
 						console.log(that.$refs)
 					    let editor = new E(that.$refs['editor' + newIndex][0])
@@ -128,10 +127,9 @@
 				
 				// 获取修改后的下划线列表与之前的内容进行对比
 				let linesArr = Array.prototype.slice.call(document.getElementById('completionEditor').getElementsByClassName('complete-line'))
-				console.log(linesArr)
 				let dataSetArr = linesArr.map((item, index) => index)
 				this.linesIndexArr = JSON.parse(JSON.stringify(this.linesIndexArr))
-				
+			
 				// 如果是删除了下划线则删除对应选项输入框
 				if (this.linesIndexArr.length > dataSetArr.length) {
 				    Array.prototype.diff = function(a) {
@@ -139,7 +137,7 @@
 				    }
 				    let deleteIndexArr = this.linesIndexArr.diff(dataSetArr) // 获取要删除的选项下标
 				    let optionsArr = Array.prototype.slice.call(document.getElementsByClassName('editor-wrap')) // 获取到所有的选项DOM
-				
+					console.log(deleteIndexArr)
 				    // 对指定选项进行删除操作
 				    this.$nextTick(() => {
 				        deleteIndexArr.forEach(item => {
@@ -148,6 +146,8 @@
 				            this.optionsContent.splice(item, 1)
 				            optionsArr.splice(item, 1)
 				        })
+						console.log('删除后的选项')
+						console.log(this.optionsContent)
 				    })
 				}
 				this.linesIndexArr = [...dataSetArr]
@@ -162,6 +162,7 @@
         },
 
         mounted() {
+			let that = this
             let completionEditor = new E(this.$refs.completionEditor)
             completionEditor.customConfig = this.defaultConfig
 
@@ -169,14 +170,16 @@
             completionEditor.customConfig.onchange = (html) => {
                 this.onStemChange(html)
             },
+			completionEditor.customConfig.onfocus = function () {
+				that.isStemFocus = true
+			}
+			completionEditor.customConfig.onblur = function () {
+				that.isStemFocus = false
+			}
             completionEditor.create()
 
             this.stemEditor = completionEditor
 
-            // 判断是否为编辑状态
-            // if (Object.keys(this.editInfo).length > 0) {
-                
-            // }
         },
 		watch:{
 			editInfo:{
@@ -185,13 +188,13 @@
 					console.log(n)
 					if(n){
 						let that = this
-						// 回显题干
-						this.stemEditor.txt.html(n.question)
-						this.stemContent = n.question
-						
 						this.stemEditor.customConfig.onchange = (html) => {
 						    this.onStemChange(html)
 						},
+						this.onStemChange(n.question)
+						// 回显题干
+						this.stemEditor.txt.html(n.question)
+						this.stemContent = n.question
 						
 						// 回显选项
 						this.optionsIndexArr = n.answer.map((i,index) => index)

+ 58 - 0
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseCompose.vue

@@ -0,0 +1,58 @@
+<template>
+	<div>
+		<div class="exersices-content">
+			<IconText :text="'题目'" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
+			<div>
+				<div ref="editor" style="text-align:left"></div>
+			</div>
+		</div>
+	</div>
+</template>
+<script>
+	import E from 'wangeditor'
+	import IconText from '@/components/evaluation/IconText.vue'
+	export default {
+		components: {
+			IconText
+		},
+		props: ['editInfo'],
+		data() {
+			return {
+				defaultConfig: {
+					uploadImgShowBase64: true,
+					menus: this.$tools.wangEditorMenu
+				},
+				stemContent: '',
+				stemEditor: null
+			}
+		},
+		methods: {
+
+		},
+		mounted() {
+			let stemEditor = new E(this.$refs.editor)
+			stemEditor.customConfig = this.defaultConfig
+			stemEditor.customConfig.onchange = (html) => {
+				this.stemContent = html
+			}
+			stemEditor.create()
+			this.stemEditor = stemEditor
+
+		},
+		watch:{
+			editInfo:{
+				handler(n){
+					console.log('主观题富文本接收到的数据')
+					console.log(n)
+					if(n){
+						this.stemContent = this.editInfo.question
+						this.stemEditor.txt.html(this.editInfo.question)
+					}
+				}
+			}
+		}
+	}
+</script>
+<style lang="less" scoped>
+	@import"../index/CreateExercises.less";
+</style>

+ 239 - 0
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSimpleCompletion.vue

@@ -0,0 +1,239 @@
+<template>
+    <div>
+        <div class="exersices-content">
+            <span class="add-underline"><Button type="primary" @click="addOption()" v-show="isStemFocus">添加填空横线</Button></span>
+            <IconText :text="'题目'" :color="'#2d8cf0'" :icon="'ios-create'" style="margin-bottom:15px;"></IconText>
+            <div>
+                <div ref="completionEditor" id="completionEditor" style="text-align:left"></div>
+            </div>
+        </div>
+        <div class="exersices-option">
+            <IconText :text="'填空选项'" :color="'#FF871C'" :icon="'md-reorder'"></IconText>
+            <div v-for="(item,index) in optionsIndexArr" :key="index" :class="['editor-wrap-'+item,'editor-wrap']" style="margin-top:10px;display:flex">
+                <span class="fl-center option-order">{{'空0'+(index+1)}}</span>
+                <div :ref="'editor'+index" style="text-align:left" class="option-editor" @click="optionClick(index)"></div>
+                <span :class="['fl-center', 'option-setting']" style="display:none;background:transparent;cursor:auto"></span>
+                <span class="fl-center option-delete" @click="deleteOption(index)"><Icon type="ios-close-circle" /></span>
+            </div>
+            <!--<p class="option-add"><span @click="addOption()">+ 添加选项 </span></p>-->
+        </div>
+    </div>
+</template>
+<script>
+    import E from 'wangeditor'
+    import IconText from '@/components/evaluation/IconText.vue'
+    export default {
+        components: {
+            IconText
+        },
+        props: ['editInfo'],
+        data() {
+            return {
+                options: [],
+                optionsContent: [],
+                initFlag: true,
+				isStemFocus:false,
+                trueIndex: 0,
+                stemContent: '',
+                stemEditor: null,
+                answerContent: [],
+                linesIndexArr: [],
+                optionsIndexArr: [],
+                defaultConfig: {
+                	uploadImgShowBase64:true,
+                    menus: this.$tools.wangEditorMenu
+                },
+            }
+        },
+        created() {
+            // 编辑状态下回显
+            
+        },
+        methods: {
+            // 设置正确答案
+            settingAnswer(index) {
+                this.trueIndex = index
+            },
+            // 下划线点击事件
+            lineClick(e) {
+                console.log(e)
+            },
+            // 删除选项
+            deleteOption(index) {
+                this.$Message.warning('请在题目编辑框内删除对应横线即可')
+            },
+            // 选项输入框点击事件
+            optionClick(index) {
+                let allToolbars = document.getElementsByClassName('option-editor')
+                let that = this
+                for (let i = 0; i < allToolbars.length; i++) {
+                    allToolbars[i].children[0].style.visibility = 'hidden'
+                }
+                setTimeout(function() {
+                    let currentToolBar = that.$refs['editor' + index][0].children[0]
+                    currentToolBar.style.visibility = 'visible'
+                }, 100)
+            },
+
+            // 添加选项
+            addOption() {
+				if(this.linesIndexArr.length > 7){
+					this.$Message.warning('最多添加8个空格!')
+				}else{
+					let that = this
+					let newIndex = this.linesIndexArr.length ? parseInt(this.linesIndexArr[this.linesIndexArr.length - 1]) + 1 : 0 // 不能重复
+					let newLineIndex = this.linesIndexArr.length // 长度即标记
+					this.optionsIndexArr.push(newIndex) // 选项集合
+					this.linesIndexArr.push(newIndex) // 题干中下划线集合
+					// 插入下划线
+					let addHtml = "&nbsp;<span class='complete-line' data-index=" + newIndex + ' data-answer=' + newIndex + " contenteditable='false'>&#93" + (newLineIndex + 12) + '</span>&nbsp;'
+					this.stemEditor.cmd.do('insertHTML', addHtml)
+					this.stemContent = this.stemContent + addHtml
+					this.$nextTick(() => {
+						console.log(that.$refs)
+					    let editor = new E(that.$refs['editor' + newIndex][0])
+					    editor.customConfig = this.defaultConfig
+					    // 每个填空选项 数据变化
+					    editor.customConfig.onchange = (html) => {
+					        let codeArr = this.optionsContent.map(item => item.code)
+					        // 如果已经编辑过则 修改选项内容
+					        if (codeArr.indexOf(newIndex) !== -1) {
+					            this.optionsContent[codeArr.indexOf(newIndex)].value = html
+					        } else { // 否则创建新选项
+					            let option = {
+					                code: newIndex,
+					                value: html
+					            }
+					            this.optionsContent.push(option)
+					        }
+					        console.log(this.optionsContent)
+					    },
+						editor.customConfig.onblur = function() {
+							let allToolbars = document.getElementsByClassName('option-editor')
+							for (let j = 0; j < allToolbars.length; j++) {
+								if (allToolbars[j].children.length) {
+									allToolbars[j].children[0].style.visibility = 'hidden'
+								}
+							}
+						},
+						editor.create()
+					})
+				}
+                
+            },
+			
+			onStemChange(html){
+				this.stemContent = html
+				
+				// 获取修改后的下划线列表与之前的内容进行对比
+				let linesArr = Array.prototype.slice.call(document.getElementById('completionEditor').getElementsByClassName('complete-line'))
+				let dataSetArr = linesArr.map((item, index) => index)
+				this.linesIndexArr = JSON.parse(JSON.stringify(this.linesIndexArr))
+			
+				// 如果是删除了下划线则删除对应选项输入框
+				if (this.linesIndexArr.length > dataSetArr.length) {
+				    Array.prototype.diff = function(a) {
+				        return this.filter(function(i) { return a.indexOf(i) < 0 })
+				    }
+				    let deleteIndexArr = this.linesIndexArr.diff(dataSetArr) // 获取要删除的选项下标
+				    let optionsArr = Array.prototype.slice.call(document.getElementsByClassName('editor-wrap')) // 获取到所有的选项DOM
+					console.log(deleteIndexArr)
+				    // 对指定选项进行删除操作
+				    this.$nextTick(() => {
+				        deleteIndexArr.forEach(item => {
+				            let deleteDom = document.getElementsByClassName('editor-wrap')[item - 1]
+				            this.optionsIndexArr.splice(this.optionsIndexArr.indexOf(deleteDom), 1)
+				            this.optionsContent.splice(item, 1)
+				            optionsArr.splice(item, 1)
+				        })
+						console.log('删除后的选项')
+						console.log(this.optionsContent)
+				    })
+				}
+				this.linesIndexArr = [...dataSetArr]
+				// 重新渲染下划线的下标
+				linesArr.forEach((item, index) => {
+				    let numCircle = '&#93' + (parseInt(index) + 12) + ''
+				    item.innerHTML = numCircle
+				    item.setAttribute('data-index', index)
+				})
+			}
+
+        },
+
+        mounted() {
+			let that = this
+            let completionEditor = new E(this.$refs.completionEditor)
+            completionEditor.customConfig = this.defaultConfig
+
+            // 当填空题型 题干部分插入下划线以及删除下划线监听
+            completionEditor.customConfig.onchange = (html) => {
+                this.onStemChange(html)
+            },
+			completionEditor.customConfig.onfocus = function () {
+				that.isStemFocus = true
+			}
+			completionEditor.customConfig.onblur = function () {
+				that.isStemFocus = false
+			}
+            completionEditor.create()
+
+            this.stemEditor = completionEditor
+
+        },
+		watch:{
+			editInfo:{
+				handler(n){
+					console.log('填空题接收到的数据')
+					console.log(n)
+					if(n){
+						let that = this
+						this.stemEditor.customConfig.onchange = (html) => {
+						    this.onStemChange(html)
+						},
+						this.onStemChange(n.question)
+						// 回显题干
+						this.stemEditor.txt.html(n.question)
+						this.stemContent = n.question
+						
+						// 回显选项
+						this.optionsIndexArr = n.answer.map((i,index) => index)
+						this.linesIndexArr = n.answer.map((i,index) => index)
+						n.answer.forEach((item, index) => {
+							this.optionsContent.push({ code: index, value: item }) // 填空答案回显
+							this.$nextTick(() => {
+								let editor = new E(that.$refs['editor' + index][0])
+								editor.customConfig = this.defaultConfig
+								// 每个填空选项 数据变化
+								editor.customConfig.onchange = (html) => {
+									let codeArr = this.optionsContent.map(item => item.code)
+									// 如果已经编辑过则 修改选项内容
+									if (codeArr.indexOf(index) !== -1) {
+										this.optionsContent[codeArr.indexOf(index)].value = html
+									} else { // 否则创建新选项
+										let option = {
+											code: index,
+											value: html
+										}
+										this.optionsContent.push(option)
+									}
+								},
+								editor.customConfig.onblur = function() {
+									let allToolbars = document.getElementsByClassName('option-editor')
+									for (let j = 0; j < allToolbars.length; j++) {
+										if (allToolbars[j].children.length) {
+											allToolbars[j].children[0].style.visibility = 'hidden'
+										}
+									}
+								},
+								editor.create()
+								editor.txt.html(item) // 填空答案回显内容
+							})
+						})
+					}
+				}
+			}
+		}
+
+    }
+</script>

+ 1 - 2
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -49,8 +49,6 @@
             initEditors() {
                 // Editor默认配置
                 if (this.options.length > 0) {
-					console.log(this.options)
-					console.log(this.$refs)
                     this.options.forEach((item, i) => {
                         let that = this
                         let editor = new E(that.$refs['singleOption' + i][0])
@@ -178,6 +176,7 @@
                         console.log('单选接收到的数据')
                         console.log(newValue)
                         this.editInfo = newValue
+						this.editInfo.options = this.editInfo.option
                         if (Object.keys(newValue).length > 0) {
 							this.stemEditor.txt.html(this.editInfo.question)
 							this.stemContent = this.editInfo.question

+ 14 - 0
TEAMModelOS/ClientApp/src/view/forgotPw/Index.less

@@ -0,0 +1,14 @@
+.forgotDiv{
+    width: 500px;
+    height: 500px;
+    display: flex;
+    justify-content: center;
+    align-content: flex-start;
+    .validForm{
+        width: 400px;
+        .formItem{
+            
+        }
+        
+    }
+}

+ 297 - 0
TEAMModelOS/ClientApp/src/view/forgotPw/Index.vue

@@ -0,0 +1,297 @@
+<style lang="less" scoped>
+  @import './Index.less';
+</style>
+
+<style lang="less">
+  .forgotBox{
+    .validForm{
+      .formItem{
+          .ivu-form-item-label {
+            color: white;
+          }
+          input, select, button{
+              border-radius: 0;
+              font-size: 12px;
+          }
+          .ivu-btn-primary{
+            background-color: #4d6b9d;
+          }
+          .ivu-select-selection{
+            border-radius: 0;
+          }
+      }
+    }
+  }
+</style>
+
+<template>
+    <div class="forgotDiv">
+        <div class="forgotBox">
+          <h3 style="text-align: center;margin-bottom: 5px;font-weight: 100;letter-spacing: 3px;font-size: 20px;color: white;">
+              {{ $t('重置密碼') }}
+          </h3>
+          <Form v-show="restPWStep == 1" class="validForm" ref="sendForm" :model="sendForm" :rules="sendRules" label-position="top" @keydown.enter.native="handleSubmit('sendForm')" style="color: white;">
+            <FormItem class="formItem">
+              <span v-if="applyType == 'email' " style="display: block;text-align: center;font-size: 13px;color: rgb(244, 67, 54);">{{ $t('regist.form.text7')}}</span>
+            </FormItem>
+            <FormItem class="formItem" prop="account" >
+              <Row type="flex" justify="center" align="top">
+                <Col v-if="applyType == 'phone'" :span="9">
+                  <CountryCode v-model="cCode"/>
+                </Col>
+                <Col :span="applyType == 'phone' ? 15 : 24">
+                  <Input :placeholder="$t('regist.form.placeholder.' + applyType)" v-model="sendForm.account"></Input>                                                                        
+                </Col>
+              </Row>
+            </FormItem>
+            <FormItem class="formItem">
+                <Button long  type="primary" @click="handleSubmit('sendForm')">
+                  <span>{{ $t('發送驗證碼') }}</span>
+                </Button>
+            </FormItem>
+            <FormItem class="formItem" style="text-align: center;">
+              <Button style="color: #409eff;" type="text" @click="chgValidType()" >{{ applyType == 'email' ? '改用手機驗證' : '改用Email驗證' }}</Button>
+            </FormItem>
+          </Form>
+          <Form v-show="restPWStep == 2" class="validForm" ref="resPwForm" :model="resPwForm" :rules="resPwRules" label-position="top" style="color: white;">
+              <FormItem class="formItem" style="text-align: center;">
+                {{'+' + cCode + '-' + sendForm.account}} <Button  type="primary" size="small" :disabled="countdown" @click="handleSubmit('sendForm')"> {{ sendBtnText }}</Button>
+              </Formitem>
+              <FormItem class="formItem">
+                  <span v-if="applyType == 'email' " style="width: 400px;display: block;text-align: center;font-size: 13px;color: rgb(244, 67, 54);">{{ $t('regist.form.text7')}}</span>
+              </FormItem>
+              <FormItem class="formItem" prop="pinCode" :label="$t('請輸入驗證碼')">
+                <Input  class="radius-left-0 input-font-size-12" v-model="resPwForm.pinCode"></Input>
+              </FormItem>
+              <FormItem class="formItem"  :label="$t('新密碼')" prop="pw" >
+                <Input   type="password" password  v-model="resPwForm.pw" ></Input>
+              </FormItem>
+              <FormItem class="formItem"  :label="$t('請再確認一次密碼')" prop="pwCheck" >
+                <Input   type="password" password v-model="resPwForm.pwCheck" ></Input>
+              </FormItem>
+              <FormItem class="formItem">
+                  <Button long  type="primary" @click="handleSubmit('resPwForm')" style="margin-top:20px;">
+                      <span>{{ $t('regist.btn.signUp') }}</span>
+                  </Button>
+              </FormItem>
+          </Form>
+        </div>
+    </div>
+</template>
+<script>
+import { User } from '@/service/User'
+import CountryCode from '@/components/public/countryCode/Index.vue'
+import { mapState, mapGetters } from 'vuex'
+
+export default {
+  components:{
+    CountryCode
+  },
+  data() {
+    const validAccount = (rule, value, callback) => {
+      if (value === '') {
+        if(this.applyType == 'phone'){
+          callback(new Error( this.$t('error.input.phone')));
+        } else {
+          callback(new Error( this.$t('error.input.email')));
+        }    
+      } else {
+        switch (this.applyType) {
+          case 'email':
+            let emailRule = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
+            if(value.search(emailRule) != -1){
+              callback();
+            } else {
+              callback(new Error( this.$t('error.format.email')));
+            }
+            break;
+          case 'phone':
+            if(this.cCode === '') {
+              callback(new Error( this.$t('error.input.countryCode')));
+            } else if(!(/^[0-9]*$/.test(value))) {
+              callback(new Error( this.$t('error.format.numeric')));
+            } else {
+              callback();
+            }
+            break;
+        }
+      }
+    };
+    const validPW = (rule, value, callback) => {
+      if (!(/^(?=.*[a-zA-Z])(?=.*\d)[\S]{8,30}$/.test(value))) {
+        callback(new Error(this.$t('error.format.pw')));
+      } else {
+        callback();
+      }
+    };
+    const validPWCheck = (rule, value, callback) => {
+      if(value == ''){
+        callback(new Error(this.$t('error.input.pwCheck')));
+      }
+      else if(value != this.registForm.pw){
+        callback(new Error(this.$t('error.input.pwCheckFail')));
+      } else {
+        callback();
+      }
+    };
+    return {
+      applyType: 'phone',
+      restPWStep: 1, // 發送驗證碼 1, 重置密碼 2
+      cCode:'',
+      teammodelID: '',
+      sendText: '',
+      lang: localStorage.getItem('local'),
+      countdownSec: 60,
+      verfTime: 0,
+      countdown: false,
+      sendForm:{
+        account: '',
+      },
+      sendRules:{
+        account: [
+          {validator: validAccount , trigger: 'blur' },
+        ],
+      },
+      resPwForm: {
+          pw: '',
+          pwCheck: '',
+          pinCode:''
+      },
+      resPwRules: {
+        pw: [
+          {required: true, message: () => this.$t('error.required') , trigger: 'blur' },
+          {validator: validPW , trigger: 'blur' }
+        ],
+        pwCheck: [
+          {required: true, message: () => this.$t('error.required') , trigger: 'blur' },
+          {validator: validPWCheck , trigger: 'blur' }
+        ],
+        pinCode: [
+          {required: true, message: () => this.$t('error.required') , trigger: 'blur' },
+        ],        
+      },
+      loading: false
+    }
+  },
+  computed: {
+    ...mapState({
+      config: state => state.config
+    }),
+    ...mapGetters({
+        loginSchooCode: 'user/getLoginSchooCode',
+        srvAdr: 'config/getSrvAdr'
+    }),
+    sendBtnText: function(){ // 發送驗證信與驗證碼字串判斷
+        let str = this.$t('regist.btn.send' + this.applyType)
+        let timeStr = ''
+        if(this.countdown) timeStr = '(' + this.verfTime + ')'
+
+        return str + timeStr
+    },
+    accFormat: function(){
+      let acc = this.sendForm.account
+      if(this.applyType == 'phone' && this.cCode == 886 && acc.indexOf(0) == 0) {
+        acc = acc.substr(1)
+      }
+
+      return acc
+    }
+  },
+  created() {
+    this.verfTime = this.countdownSec;
+    // this.teammodelID = Math.floor(new Date().getTime() / 1000)
+  },
+  methods: {
+    chgValidType: function(){
+      if(this.applyType == 'phone') {
+        this.applyType = 'email'
+      } else {
+        this.applyType = 'phone'
+      }
+    },
+    handleSubmit: function(name){
+      this.$refs[name].validate( async(valid) => {
+        if (valid) {
+          let data = {}
+          switch (name) {
+            case 'sendForm':
+              data = {
+                applyType: this.applyType,
+                to: this.accFormat,
+                lang: this.lang,
+                hasUser: true,
+                country: this.cCode
+              }
+              this.$api.SendPinCode(data).then(res => {
+                let errorFlag = false
+                if(res){
+                  errorFlag = true
+                  this.$Message.warning({
+                    content: this.applyType == 'phone' ?  this.$t('此手機號碼不存在') : this.$t('此信箱不存在'),
+                    duration: 7,
+                    closable: true
+                  })
+                } 
+
+                if(!errorFlag){
+                  this.restPWStep = 2
+                  this.countdown = true
+                  this.reciprocal()
+                }
+              })
+            break;
+            case 'resPwForm':
+              data = {
+              applyType: this.applyType,
+              account: this.accFormat,
+              pw: this.registForm.pw,
+              country: this.cCode,
+              pinCode: this.registForm.pinCode
+            }
+
+            this.$api.forgetPW.resetPW(data).then(res => {
+              if(res.error){
+                let text;
+                switch (res.error) {
+                  case 2:
+                    text = this.$t('error.coreApi.error2.default')
+                    break;
+                  case 3:
+                    text = this.$t('error.coreApi.error3')
+                    break;
+                }
+
+                this.$Message.warning({
+                    content: text,
+                    duration: 7,
+                    closable: true
+                })
+              } else {
+                console.log('登入')
+                console.log(res)
+                // 1. 登入大雲
+                // 2. 檢查是否有學校沒有則跳至schoolList
+                // 3. 有學校是否和login_schollCode 一樣
+                // 4. 沒有一樣預設第一個
+                // 5. 儲存 asscess_token, id_token, expires_in
+                // 6. 登入User.API
+              }
+            })
+              break;
+          }
+        }
+      })
+    },
+    reciprocal () { // 調整倒數時間至可控
+        this.verfTime -=1;
+        if(this.verfTime==0){
+          this.countdown = false
+          this.verfTime = this.countdownSec;
+        } else{
+          //每秒執行一次,showTime()
+          setTimeout(this.reciprocal,1000);
+        }
+    },
+  }
+}
+</script>

+ 1 - 1
TEAMModelOS/ClientApp/src/view/login/Index.vue

@@ -79,7 +79,7 @@
                 <a @click="chgLoginType()">{{ $t('login.link.QRLogin') }}</a>
               </div>
               <div class="link">
-                <router-link to="/regist">{{ $t('login.link.regist') }}</router-link> | <a>{{ $t('login.link.forgetPsw') }}</a>
+                <router-link to="/regist">{{ $t('login.link.regist') }}</router-link> | <router-link to="/forgotpw">{{ $t('login.link.forgetPsw') }}</router-link>
               </div>
             </div>
 

+ 3 - 0
TEAMModelOS/ClientApp/src/view/newcourse/CourseClassroom.vue

@@ -578,6 +578,9 @@
 
                             }
                         }
+                        if (!this.courseInfo.classes[this.curClassIndex].getStatus) {
+                            this.getClassroomStudent()
+                        }
                     }
                 },
                 deep: true

+ 9 - 0
TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.less

@@ -147,4 +147,13 @@
     height:50px;
     line-height:50px;
 
+}
+.cell-action-icon{
+    color:white;
+    font-size:22px;
+    margin:25px 5px 0px 5px;
+    &:hover{
+        color:aqua;
+    }
+
 }

+ 94 - 44
TEAMModelOS/ClientApp/src/view/newcourse/CoursePlan.vue

@@ -45,14 +45,14 @@
                     <div class="cus-table-top dark-iview-input dark-iview-select">
                         <div class="semester-filter-wrap">
                             <!--<span class="label">学期</span>
-                            <Select v-model="semester" size="small" style="width: 200px;display:inline-block;">
-                                <Option v-for="(item,index) in semesterList.semesters" :value="item.semesterCode">{{item.semesterName}}</Option>
-                            </Select>-->
+                        <Select v-model="semester" size="small" style="width: 200px;display:inline-block;">
+                            <Option v-for="(item,index) in semesterList.semesters" :value="item.semesterCode">{{item.semesterName}}</Option>
+                        </Select>-->
                         </div>
                         <h1 class="sch-title">课程表</h1>
                     </div>
                     <div v-if="this.classListShow[this.curClassIndex]">
-                        <Table :columns="timeColumns" disabled-hover :data="this.classListShow[this.curClassIndex].classPlan" border :span-method="handleSpan" class="cus-table">
+                        <Table :columns="timeColumns" disabled-hover :data="classListShow[curClassIndex].classPlan" border :span-method="handleSpan" class="cus-table">
                             <!--上午/下午-->
                             <template slot-scope="{ row, index }" slot="sub">
                                 <p style="padding:10px 0px 4px 0px;font-size: 20px;">
@@ -72,9 +72,8 @@
                             <template slot-scope="{ row, index }" slot="MON">
                                 <div :class="row.weeklies.MON.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.MON.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'MON')" type="default">
-                                            {{row.weeklies.MON.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'MON')" />
+                                        <Icon v-if="row.weeklies.MON.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'MON')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.MON.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.MON.teacher}}</p>
@@ -84,9 +83,8 @@
                             <template slot-scope="{ row, index }" slot="TUE">
                                 <div :class="row.weeklies.TUE.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.TUE.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'TUE')" type="default">
-                                            {{row.weeklies.TUE.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'TUE')" />
+                                        <Icon v-if="row.weeklies.TUE.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'TUE')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.TUE.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.TUE.teacher}}</p>
@@ -96,9 +94,8 @@
                             <template slot-scope="{ row, index }" slot="WED">
                                 <div :class="row.weeklies.WED.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.WED.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'WED')" type="default">
-                                            {{row.weeklies.WED.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'WED')" />
+                                        <Icon v-if="row.weeklies.WED.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'WED')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.WED.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.WED.teacher}}</p>
@@ -108,9 +105,8 @@
                             <template slot-scope="{ row, index }" slot="THU">
                                 <div :class="row.weeklies.THU.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div class="toggle-status-btn-wrap" v-if="row.weeklies.THU.status == 1">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'THU')" type="default">
-                                            {{row.weeklies.THU.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'THU')" />
+                                        <Icon v-if="row.weeklies.THU.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'THU')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.THU.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.THU.teacher}}</p>
@@ -120,9 +116,8 @@
                             <template slot-scope="{ row, index }" slot="FRI">
                                 <div :class="row.weeklies.FRI.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.FRI.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'FRI')" type="default">
-                                            {{row.weeklies.FRI.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'FRI')" />
+                                        <Icon v-if="row.weeklies.FRI.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'FRI')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.FRI.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.FRI.teacher}}</p>
@@ -132,9 +127,8 @@
                             <template slot-scope="{ row, index }" slot="SAT">
                                 <div :class="row.weeklies.SAT.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.SAT.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'SAT')" type="default">
-                                            {{row.weeklies.SAT.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'SAT')" />
+                                        <Icon v-if="row.weeklies.SAT.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'SAT')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.SAT.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.SAT.teacher}}</p>
@@ -144,9 +138,8 @@
                             <template slot-scope="{ row, index }" slot="SUN">
                                 <div :class="row.weeklies.SUN.status == 1 ? 'week-day-cell':'week-day-cell vact-status'">
                                     <div v-if="row.weeklies.SUN.status == 1" class="toggle-status-btn-wrap">
-                                        <Button class="toggle-status-btn" @click="showSetCus(row,'SUN')" type="default">
-                                            {{row.weeklies.SUN.status == 1 ? '设置课程':'设置课程'}}
-                                        </Button>
+                                        <Icon class="cell-action-icon" type="ios-settings" title="设置课程" @click="showSetCus(row,'SUN')" />
+                                        <Icon v-if="row.weeklies.SUN.courseName" class="cell-action-icon" type="md-trash" title="取消课程" @click="showCancelCus(row,'SUN')"/>
                                     </div>
                                     <p class="course-name">{{row.weeklies.SUN.courseName}}</p>
                                     <p class="teacher-name">{{row.weeklies.SUN.teacher}}</p>
@@ -180,7 +173,8 @@
         <Modal v-model="setCusStatus"
                title="设置课程"
                class-name="dark-iview-modal dark-iview-form"
-               @on-ok="confirmSetCus">
+               @on-ok="confirmSetCus"
+               @on-cancel="cancelSetCus">
             <Form :model="cusItem" :label-width="90">
                 <FormItem label="课程名称">
                     <Select v-model="cusItem.courseId">
@@ -194,6 +188,12 @@
                 </FormItem>
             </Form>
         </Modal>
+        <Modal v-model="cancelCusStatus"
+               title="取消课程"
+               class-name="dark-iview-modal dark-iview-form"
+               @on-ok="confirmCancelCus">
+            <p v-if="delCusInfo.row" style="color:white;font-size:16px;">确认取消当前课程?</p>
+        </Modal>
     </div>
 </template>
 <script>
@@ -212,7 +212,7 @@
                 },
                 isSearch: false,
                 isLoading: false,
-                coursePlan: {},
+                //coursePlan: {},
                 courseList: [],
                 cusItem: {
                     courseId: '',
@@ -220,6 +220,7 @@
                     row: {},
                     day: ''
                 },
+                delCusInfo: {},
                 errorClass: [],
                 errorCourse: [],
                 errorTeacher: [],
@@ -228,10 +229,11 @@
                 headerTitles: ['班级', '课程名称', '课程编码', '授课老师', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'],
                 importCusStatus: false,
                 setCusStatus: false,
-                semesterTree: [],
+                cancelCusStatus: false,
+                //semesterTree: [],
                 schoolInfo: {},
                 subIndex: 0,
-                semester: [],
+                //semester: [],
                 isListLoading: false,
                 classList: [],
                 classListShow: [],
@@ -291,6 +293,44 @@
             }
         },
         methods: {
+            showCancelCus(row, day) {
+                this.cancelCusStatus = true
+                console.log(row, day)
+                this.delCusInfo.row = row
+                this.delCusInfo.day = day
+            },
+            //确认取消课程
+            confirmCancelCus() {
+                let requestData = {
+                    id: this.delCusInfo.row.weeklies[this.delCusInfo.day].courseId,
+                    code: this.delCusInfo.row.weeklies[this.delCusInfo.day].teacherCode,
+                    classroomCode: this.classListShow[this.curClassIndex].classroomCode,
+                    time:this.delCusInfo.row.time,
+                    day:this.delCusInfo.day
+                }
+                this.isLoading = true
+                this.$api.courseMgmt.deleteTime(requestData).then(
+                    (res) => {
+                        if (!res.error) {
+                            this.$Message.success('取消成功')
+                            console.log('123456')
+                            console.log(this.classListShow[this.curClassIndex])
+                            this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].teacher = undefined
+                            this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].teacherCode = undefined
+                            this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].courseName = undefined
+                            this.classListShow[this.curClassIndex].classPlan[this.delCusInfo.row._index].weeklies[this.delCusInfo.day].courseId = undefined
+                            let tempArr = JSON.parse(JSON.stringify(this.classListShow[this.curClassIndex].classPlan))
+                            this.classListShow[this.curClassIndex].classPlan = []
+                            this.classListShow[this.curClassIndex].classPlan = [...tempArr]
+                        }
+                        this.isLoading = false
+                    },
+                    (err) => {
+                        this.$Message.error('取消失败')
+                        this.isLoading = false
+                    }
+                )
+            },
             //关键字搜索班级
             onSearchClass() {
                 this.classListShow = this.classList.filter((item) => {
@@ -317,6 +357,11 @@
                     }
                 )
             },
+            //取消设置课程
+            cancelSetCus() {
+                this.cusItem.teacher = ''
+                this.cusItem.courseId = ''
+            },
             //确认设置课程
             confirmSetCus() {
                 this.isLoading = true
@@ -327,21 +372,26 @@
                     courseTime: {
                         label: this.cusItem.row.label,
                         time: this.cusItem.row.time,
-                        day: this.cusItem.day,
-                        //type:0
+                        day: this.cusItem.day
                     }
                 }
                 this.$api.courseMgmt.upsertAllPlan([requestData]).then(
                     (res) => {
-                        this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'courseName', this.courseList.filter((item) => {
-                            return item.id == this.cusItem.courseId
-                        })[0].courseName)
+                        if (!res.error && res.result.data.length > 0) {
+                            this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'courseName', this.courseList.filter((item) => {
+                                return item.id == this.cusItem.courseId
+                            })[0].courseName)
 
-                        this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'teacher', this.cusTeaList.filter((item) => {
-                            return item.id == this.cusItem.teacher
-                        })[0].name)
+                            this.$set(this.classListShow[this.curClassIndex].classPlan[this.cusItem.row._index].weeklies[this.cusItem.day], 'teacher', this.cusTeaList.filter((item) => {
+                                return item.id == this.cusItem.teacher
+                            })[0].name)
 
-                        this.$Message.success('设置成功!')
+                            this.$Message.success('设置成功!')
+                            this.cusItem.teacher = ''
+                            this.cusItem.courseId = ''
+                        } else {
+                            this.$Message.error('设置失败!')
+                        }
                         this.isLoading = false
                     },
                     (err) => {
@@ -510,8 +560,6 @@
                                     let realClass = planItem.classes.filter((item) => {
                                         return item.classroomCode == this.classListShow[this.curClassIndex].classroomCode
                                     })
-                                    console.log('0.0.0.')
-                                    console.log(realClass)
                                     for (let timeItem of realClass[0].courseTimes) {
                                         //可优化
                                         for (let i = 0; i < this.classListShow[this.curClassIndex].classPlan.length; i++) {
@@ -519,7 +567,9 @@
                                                 //this.$set(this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day], 'courseName', courseName)
                                                 //this.$set(this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day], 'teacher', teacherName)
                                                 this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].teacher = teacherName
+                                                this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].teacherCode = planItem.code
                                                 this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].courseName = courseName
+                                                this.classListShow[this.curClassIndex].classPlan[i].weeklies[timeItem.day].courseId = planItem.id
                                                 break
                                             }
                                         }
@@ -541,10 +591,10 @@
                 }
             }
         },
-        created() {
-            this.getCourseList()
-            this.$store.dispatch('teachers/getTeacherList').then(res => { })
-            this.$store.dispatch('schoolBaseInfo/getClassroom').then(res => {
+        async created() {
+            await this.getCourseList()
+            await this.$store.dispatch('teachers/getTeacherList').then(res => { })
+            await this.$store.dispatch('schoolBaseInfo/getClassroom').then(res => {
                 this.classList = this.$store.state.schoolBaseInfo.classroomList
                 this.classListShow = [...this.classList]
                 this.findClassPlan()

+ 69 - 25
TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue

@@ -44,8 +44,8 @@
 				<div class="qn-box-header">
 					<span>问卷详情</span>
 					<div class="qn-box-header-tools">
-						<span class="qn-box-header-tools-tool" v-show="currentQn.status !== 300 && qnList.length">
-							<Icon type="md-create" size="18" title="编辑" @click="onEditQn" /></span>
+						<!-- <span class="qn-box-header-tools-tool" v-show="currentQn.status !== 300 && qnList.length">
+							<Icon type="md-create" size="18" title="编辑" @click="onEditQn" /></span> -->
 						<span class="qn-box-header-tools-tool" v-show="currentQn.status === 200 && qnList.length">
 							<Icon type="md-undo" size="18" title="取消发布" @click="onCancelQn" style="margin-left:8px;" /></span>
 					</div>
@@ -83,15 +83,25 @@
 							<Icon type="md-podium" color="#dcdcdc" />
 							<span>查看统计数据</span>
 						</div>
-						<div class="qn-box-header-tools-tool" @click="onSaveQn">
+						<div class="qn-box-header-tools-tool" @click="onEditQn" v-show="currentQn.status !== 300 && qnList.length && !editable">
+							<Icon type="md-create" color="#209460" />
+							<span>编辑问卷</span>
+						</div>
+						
+						<div class="qn-box-header-tools-tool" @click="onSaveQn" v-show="editable" style="margin-right: 20px;">
 							<Icon type="md-folder" color="#209460" />
 							<span>保存问卷</span>
 						</div>
+						
+						<div class="qn-box-header-tools-tool" @click="onCancelEditQn" v-show="editable">
+							<Icon type="md-create" color="#209460" />
+							<span>取消编辑</span>
+						</div>
 					</div>
 				</div>
 				<vuescroll>
 					<div class="qn-data-wrap">
-						<BaseQuestionnaire :editItem="currentQn" ref="qnPaper" v-if="!isEmptyData"></BaseQuestionnaire>
+						<BaseQuestionnaire :editItem="currentQn" :isEdit="editable" ref="qnPaper" v-if="!isEmptyData"></BaseQuestionnaire>
 					</div>
 				</vuescroll>
 			</div>
@@ -99,6 +109,7 @@
 	</div>
 </template>
 <script>
+	import uploadFile from '@/utils/upload.js'
 	import BaseQuestionnaire from '@/components/questionnaire/BaseQuestionnaire.vue'
 	import BaseQnForm from '@/components/questionnaire/BaseQnForm.vue'
 	export default {
@@ -196,11 +207,12 @@
 				let params = {
 					code: type === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
 				}
-				this.$api.questionnaire.FindSurveysSummary(params).then(res => {
+				this.$api.questionnaire.FindSurveysSummary(params).then(async res => {
 					if (!res.error && res.result.data) {
-						this.qnList = res.result.data
-						if (res.result.data.length){
-							this.onQnClick(res.result.data[0], 0)
+						let list = res.result.data
+						this.qnList = list
+						if (list.length){
+							this.onQnClick(list[0], 0)
 							this.isEmptyData = false
 						} else{
 							this.isEmptyData = true
@@ -213,14 +225,27 @@
 			},
 
 			/** 获取问卷列表 */
-			getQnDetails(qnId) {
+			async getQnDetails(qnId) {
 				// let params = { code : this.$store.state.userInfo.TEAMModelId }
-				return new Promise((r, j) => {
+				return new Promise(async (r, j) => {
+					let privateSas = await this.$tools.getPrivateSas()
+					let schoolSas = await this.$tools.getSchoolSas()
 					this.$api.questionnaire.FindSurveys({
 						id: qnId
-					}).then(res => {
+					}).then(async res => {
 						if (!res.error && res.result.data) {
-							r(res.result.data[0])
+							let i = res.result.data[0]
+							if (i.url) {
+								let sasString = i.code === this.$store.state.userInfo.TEAMModelId ? privateSas : schoolSas 
+								let jsonInfo = await this.$tools.getFile(i.url + sasString.sas)
+								let jsonData = JSON.parse(jsonInfo)
+								jsonData.id = i.id
+								jsonData.fileName = i.url.split('/')[i.url.split('/').length - 1].split('.json')[0]
+								r(jsonData)
+								console.log(jsonData)
+							}else{
+								r(i)
+							}
 						} else {
 							this.$Message.error('获取数据失败')
 						}
@@ -252,25 +277,38 @@
 
 			/* 保存问卷操作 */
 			async onSaveQn() {
+				console.log(this.$refs.qnForm.qnFormEdit)
 				let isQnFormEdit = this.$refs.qnForm.qnFormEdit // 判断当前表单是否为编辑状态
 				let qnBaseInfo = isQnFormEdit ? await this.$refs.qnForm.handleSubmit('qnForm') : this.currentQn
 				let qnItems = this.$refs.qnPaper.items || []
+				let fileName = (qnBaseInfo.id && qnBaseInfo.fileName) ? qnBaseInfo.fileName : this.$tools.guid()
 				// 获取到基础信息 以及 题目数据 拼接保存
 				qnBaseInfo.items = qnItems
 				qnBaseInfo.code = this.tabIndex === 0 ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelId
-				this.isLoading = true
-				this.saveorUpdataQn({
-					survey: qnBaseInfo,
-					reset: false
-				}).then(res => {
-					this.$Message.success('操作成功')
-					this.$refs.qnForm.qnFormEdit = false
-					this.isLoading = false
-					this.onAddSuccess()
-				}).catch(error => {
-					this.$Message.error(`操作失败,错误信息为${ error }`)
-				})
-
+				
+				// 首先保存新题目的JSON文件到Blob 然后返回URL链接
+				let file = new File([JSON.stringify(qnBaseInfo)], fileName + ".json", {type: ""});
+				// 根据题目类型 传到不同容器
+				let fileType = qnBaseInfo.code === this.$store.state.userInfo.TEAMModelId ? 'private' : 'school'
+				// 等待上传blob的返回结果
+				let blobFile = await uploadFile.uploadFile(file,'survey',fileType)
+				if(blobFile.blobUrl){
+					// 保存到COSMOS是不含base64图片编码的数据 避免数据量过大
+					qnBaseInfo.url = blobFile.blobUrl
+					delete qnBaseInfo.items
+					this.isLoading = true
+					this.saveorUpdataQn({
+						survey: qnBaseInfo,
+						reset: false
+					}).then(res => {
+						this.$Message.success('操作成功')
+						this.$refs.qnForm.qnFormEdit = false
+						this.isLoading = false
+						this.onAddSuccess()
+					}).catch(error => {
+						this.$Message.error(`操作失败,错误信息为${ error }`)
+					})
+				}
 			},
 
 			onShowAllAnalysis() {
@@ -344,11 +382,17 @@
 
 			/** 问卷编辑事件 */
 			onEditQn() {
+				console.log(this.currentQn)
 				this.editItem = this.currentQn
 				this.isEdit = true
 				this.editable = true
 				this.$refs.qnForm.qnFormEdit = !this.$refs.qnForm.qnFormEdit
 			},
+			
+			onCancelEditQn(){
+				this.editable = false
+				this.$refs.qnForm.qnFormEdit = false
+			},
 
 			/* 取消发布问卷 */
 			onCancelQn() {

+ 0 - 2
TEAMModelOS/ClientApp/src/view/regist/Index.vue

@@ -193,8 +193,6 @@ export default {
     }
   },
   computed: {
-    userAccess() { return this.$access.getExtendInfo('userAccess');},
-    userInfo() { return this.$access.getExtendInfo('userInfo');},
     ...mapState({
       config: state => state.config
     }),

+ 15 - 2
TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.less

@@ -226,7 +226,7 @@
 
                 &-name-line {
                     display: inline-block;
-                    .lineSpan(16px,3px,red,15px);
+                    .lineSpan(16px,3px,red,2px);
                 }
 
                 &-students-num {
@@ -382,7 +382,6 @@
                 .ivu-icon {
                     margin-top: -3px;
                     margin-right: 5px;
-                    display: none;
                 }
             }
 
@@ -514,4 +513,18 @@
             right:15px;
         }
     }
+}
+.semester-name-label {
+    display: inline-block;
+    vertical-align: super;
+}
+
+#get-width {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    font-size: 18px;
+    visibility: hidden;
+    border: 1px solid black;
+    width: fit-content;
 }

+ 135 - 129
TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.vue

@@ -1,29 +1,5 @@
-<style lang="less" scoped>
-    @import './SystemSetting.less';
-</style>
-<style>
-    .second-arrow {
-        margin-left: -16px;
-    }
-
-    .color-check {
-        color: #08d0c8;
-    }
-
-    .color-uncheck {
-        color: #FF6C6B;
-    }
-
-    .bg-color-check {
-        background-color: #08d0c8 !important;
-    }
-
-    .bg-color-uncheck {
-        background-color: #FF6C6B !important;
-    }
-</style>
 <template>
-    <div class="sm-system">
+    <div class="sm-system" @click="editSubStatus = false">
         <div class="sm-school-name">
             <div>
                 <span class="setting-title">{{$t('schoolBaseInfo.schoolNameLabel')}}</span>
@@ -54,66 +30,58 @@
                             <span class="campus-label" @click="setCampus">
                                 {{item.campusCode === null ? '请设置校区': $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]").length > 0 ? $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]")[0].campusName : '请设置校区' }}
                             </span>
-                            <!--<Icon type="md-create" class="period-btn-edit" title="编辑" @click="changePeriodEditStatus(index)" />-->
                         </p>
-
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.semesterNum') + item.semesters.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.gradeNum') + item.grades.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.periodNum') + item.subjects.length}}</p>
-                        <!--<div class="period-item-tool">
-                        <Icon type="md-trash" title="删除" @click.stop="delPeriod(index)" />
-                    </div>-->
+
                     </div>
+
                 </div>
             </div>
             <!--学期列表-->
             <div class="sm-system-center">
                 <div class="col-title">
                     <span>{{$t('schoolBaseInfo.semesterSetting')}}</span>
-                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll"  type="md-add" @click="handleAddTerm" class="action-btn-icon" />
-                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll"  type="md-trash" @click="showComfirmDelSemester()" title="删除" :class="editIconStatus ? 'action-btn-icon':'custom-label-disabeld action-btn-icon'" />
-                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll"  type="md-create" @click="changeSemesterStatus(currentSemesterIndex)" title="编辑" :class="editIconStatus ? 'action-btn-icon':'custom-label-disabeld action-btn-icon'" />
+                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll" type="md-add" @click="handleAddTerm" class="action-btn-icon" />
+                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll" type="md-trash" @click="showComfirmDelSemester()" title="删除" :class="editIconStatus ? 'action-btn-icon':'custom-label-disabeld action-btn-icon'" />
+                    <Icon v-if="$access.ability('admin','schoolSetting-upd').validateAll" type="md-create" @click="changeSemesterStatus(curSemIndex)" title="编辑" :class="editIconStatus ? 'action-btn-icon':'custom-label-disabeld action-btn-icon'" />
                 </div>
                 <div class="col-body">
+
                     <div class="no-data-text" v-if="!schoolSetting.period[currentSchoolSysIndex].semesters.length">{{$t('schoolBaseInfo.noSemester')}}</div>
-                    <div class="term-list" v-if="schoolSetting.period[currentSchoolSysIndex].semesters.length">
-                        <div v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].semesters" :key="index" :class="index == currentSemesterIndex ? 'term-item block-bg block-bg-active':'term-item block-bg'" @click="chooseSemester(index)">
+                    <div class="term-list dark-iview-input disabled-iview-input dark-iview-inputnumber disabled-iview-inputnumber" v-if="schoolSetting.period[currentSchoolSysIndex].semesters.length">
+                        <div v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].semesters" :key="index" :class="index == curSemIndex ? 'term-item block-bg block-bg-active':'term-item block-bg'" @click="chooseSemester(index)">
                             <span class="term-item-name-line" :style="{backgroundColor: colorList[index]}"></span>
-                            <EditableLabel ref="semesterName" class="term-item-name" :content="item.semesterName" @editComplete="handleEditSemester($event,index)">
-                            </EditableLabel>
-                            <!--<Icon type="md-create" class="edit-btn" :title="$t('schoolBaseInfo.editLabel')" @click="changeSemesterStatus(index)" />-->
+                            <p class="semester-name-label">
+                                <Input v-model="item.semesterName" :disabled="editSemIndex !== index" placeholder="设置学期..." style="width: 180px" />
+                            </p>
                             <div class="term-item-start">
                                 <span>{{$t('schoolBaseInfo.startDate')}}</span>
-                                <Select v-model="item.month" :disabled="!$access.ability('admin','schoolSetting-upd').validateAll" :placeholder="$t('schoolBaseInfo.monthHolder')">
-                                    <Option v-for="(item,index) in monthList" :value="item" :key="index">{{ item }}</Option>
-                                </Select>
+                                <InputNumber @on-change="countSemDays" v-model="item.month" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="12" :min="1"></InputNumber>
                                 <span> / </span>
-                                <Select v-model="item.day" :disabled="!$access.ability('admin','schoolSetting-upd').validateAll"  :placeholder="$t('schoolBaseInfo.dayHolder')">
-                                    <Option v-for="(item,index) in dayList" :value="(item+1).toString()" :key="index">{{ (item+1).toString() }}</Option>
-                                </Select>
+                                <InputNumber @on-change="countSemDays" v-model="item.day" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="31" :min="1"></InputNumber>
                             </div>
                             <p class="term-item-students-num">{{$t('schoolBaseInfo.semesterDuration')+ item.days + $t('schoolBaseInfo.dayUnit')  }}</p>
-                            <!--<div class="term-item-tool">
-                            <Icon type="md-trash" :title="$t('schoolBaseInfo.delete')" @click.stop="delSemester(index)" />
-                        </div>-->
                         </div>
                     </div>
+
                     <div class="term-item-time-line" v-if="schoolSetting.period[currentSchoolSysIndex].semesters.length">
                         <ul>
                             <li v-for="(item,index) in monthEnList" :key="index">
                                 <span class="time-label">{{item}}.</span>
                                 <span class="time-dot">
-                                    <span v-if="auto" class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].month && index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
-                                    <span v-else class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].month || index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
+                                    <span v-if="auto" class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].month && index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
+                                    <span v-else class="time-inner-dot" :class="index + 1 >= schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].month || index < endMonth ? 'bg-color-check':'bg-color-uncheck'"></span>
                                     <span class="time-line-tail"></span>
                                 </span>
                                 <div>
-                                    <Icon class="first-arrow" size="22" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].month || index + 1 == endMonth" />
+                                    <Icon class="first-arrow" size="22" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].month || index + 1 == endMonth" />
                                     <span v-if="auto">
-                                        <Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].month || index + 1 == endMonth" />
+                                        <Icon class="second-arrow" size="22" :class="index  < endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].month || index + 1 == endMonth" />
                                     </span>
                                     <span v-else>
-                                        <Icon class="second-arrow" size="22" :class="index + 1 >= endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].month || index + 1 == endMonth" />
+                                        <Icon class="second-arrow" size="22" :class="index + 1 >= endMonth ? 'color-check':'color-uncheck'" type="ios-arrow-back" v-if="index + 1 == schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].month || index + 1 == endMonth" />
                                     </span>
                                 </div>
                             </li>
@@ -137,25 +105,27 @@
                     </div>
                 </div>
                 <!--学科显示区域-->
-                <div class="col-title">
+                <div class="col-title" @click.stop>
                     <span>{{$t('schoolBaseInfo.subjectSetting')}}</span>
-                    <Icon type="md-add" @click="addSubject()" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll"/>
-                    <!--<div>
-                    <Icon type="md-trash" v-show="subjectSelectList.length" />
-                </div>-->
+                    <Icon type="md-add" @click="addSubject()" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                    <Icon type="md-trash" @click="delSubStatus = true" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                    <Icon type="md-create" @click.stop="editSubStatus = true" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
                 </div>
-                <div class="grade-body">
+                <div class="grade-body dark-iview-input disabled-iview-input" @click.stop>
                     <div class="grade-item item-active" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].subjects" :key="index">
                         <span class="grade-item-icon"></span>
-                        <EditableLabel ref="subjectName" class="grade-item-name" :content="item.subjectName" @editComplete="handleEditSubject($event,index)">
-                        </EditableLabel>
-                        <Icon type="md-create" class="period-btn-edit" :title="$t('schoolBaseInfo.editLabel')" @click="changeSubjectEditStatus(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
-                        <Icon type="md-close" @click="delSubject(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                        <!--<EditableLabel ref="subjectName" class="grade-item-name" :content="item.subjectName" @editComplete="handleEditSubject($event,index)">
+    </EditableLabel>-->
+                        <p :class="'get-width'+index" id="get-width">{{item.subjectName}}</p>
+
+                        <Input v-model="item.subjectName" :disabled="!editSubStatus" placeholder="设置学科..." :style="{width: getWidth(index)+'px'}" />
+                        <!--<Icon type="md-create" class="period-btn-edit" :title="$t('schoolBaseInfo.editLabel')" @click="changeSubjectEditStatus(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />-->
+                        <Icon type="md-close" @click="delSubject(index)" v-show="delSubStatus" />
                     </div>
                 </div>
             </div>
         </div>
-        <Modal v-model="campusStatus" class="campus-modal" :mask-closable="false" @on-cancel="cancelCampus" @on-ok="confirmCampus">
+        <Modal v-model="campusStatus" class="campus-modal dark-iview-modal" @on-cancel="cancelCampus" @on-ok="confirmCampus">
             <p slot="header" style="color:#DDDDDD;letter-spacing:2px;font-weight:400;">设置校区</p>
             <p v-for="(item,index) in schoolSetting.campuses" class="campus-name-item">
                 <Icon type="md-checkmark" size="20" style="margin-right:10px;position:absolute;left:15px;" v-if="index == selectedCampusIndex" />
@@ -173,8 +143,8 @@
         </Modal>
         <Modal v-model="delSemesterStatus"
                title="删除学期"
-               @on-ok="delSemester(currentSemesterIndex)">
-            <p>确认删除 {{schoolSetting.period[currentSchoolSysIndex].semesters[currentSemesterIndex].semesterName}} 吗?</p>
+               @on-ok="delSemester(curSemIndex)">
+            <p>确认删除 {{schoolSetting.period[currentSchoolSysIndex].semesters[curSemIndex].semesterName}} 吗?</p>
         </Modal>
     </div>
 
@@ -196,6 +166,8 @@
         },
         data() {
             return {
+                editSubStatus: false,
+                delSubStatus: false,
                 updateDays: false,
                 isSaveLoading: false,
                 delSemesterStatus: false,
@@ -204,7 +176,7 @@
                 auto: true,
                 updated: false,
                 currentSchoolSysIndex: 0,
-                currentSemesterIndex: 0,
+                curSemIndex: 0,
                 isInit: true,
                 schoolSetting: {
                     schoolCode: '',
@@ -213,43 +185,79 @@
                     campuses: []
                 },
                 tabIndex: 0,
-                periodList: [
-                    {
-                        name: '紫藤小学北区'
-                    }
-                ],
+                editSemIndex: -1,
                 termList: [],
-                gradeList: [],
-                subjectList: [],
-                monthList: [],
                 monthEnList: [],
-                dayList: [],
                 colorList: [],
                 gradeSelectList: [],
                 subjectSelectList: [],
-                termMonthVal: 1,
-                termDayVal: 1,
                 TERM_MAX_LENGTH: 3, // 学期数上限
                 campusStatus: false,
-                selectedCampusIndex: -1
+                selectedCampusIndex: -1,
+                width:[]
             }
         },
         methods: {
+            /**
+             * 动态设置input宽度
+             * */
+            getWidth(index) {
+                let width = 100
+                this.$nextTick(() => {
+                    let dom = document.getElementsByClassName('get-width' + index)
+                    console.log(dom)
+                    if (dom.length > 0) {
+                        width = dom[0].clientWidth + 25
+                        console.log(width)
+                    }
+                })
+
+                return width
+            },
+
+            /**
+             * 计算学期天数
+             * @param date1
+             * @param date2
+            */
+            countSemDays() {
+                if (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length > 0) {
+                    let count = 365
+                    let index = 0
+                    let year = new Date().getFullYear()
+                    for (let i = 0; i < this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length; i++) {
+                        if (i == (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length - 1)) {
+                            index = i
+                            break
+                        } else {
+                            let sDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].day
+                            let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].day
+                            let d = this.getDays(sDate, eDate)
+                            count -= d
+                            this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i], 'days', d)
+
+                        }
+                    }
+                    this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[index], 'days', count)
+
+                    this.updated = false
+                }
+            },
             /**
              * 计算两个日期的天数
              * @param date1
              * @param date2
              */
-            getDays(date1 , date2){
+            getDays(date1, date2) {
                 var date1Str = date1.split("-");//将日期字符串分隔为数组,数组元素分别为年.月.日
                 //根据年 . 月 . 日的值创建Date对象
-                var date1Obj = new Date(date1Str[0],(date1Str[1]-1),date1Str[2]);
+                var date1Obj = new Date(date1Str[0], (date1Str[1] - 1), date1Str[2]);
                 var date2Str = date2.split("-");
-                var date2Obj = new Date(date2Str[0],(date2Str[1]-1),date2Str[2]);
+                var date2Obj = new Date(date2Str[0], (date2Str[1] - 1), date2Str[2]);
                 var t1 = date1Obj.getTime();
                 var t2 = date2Obj.getTime();
-                var dateTime = 1000*60*60*24; //每一天的毫秒数
-                var minusDays = Math.floor(((t2-t1)/dateTime));//计算出两个日期的天数差
+                var dateTime = 1000 * 60 * 60 * 24; //每一天的毫秒数
+                var minusDays = Math.floor(((t2 - t1) / dateTime));//计算出两个日期的天数差
                 var days = Math.abs(minusDays);//取绝对值
                 return days;
             },
@@ -297,7 +305,7 @@
                 if (this.$access.ability('admin', 'schoolSetting-upd').validateAll) {
                     this.campusStatus = true
                 }
-                
+
             },
             // 删除节点
             delGrade(index) {
@@ -309,12 +317,12 @@
             //删除学段
             delPeriod(index) {
                 if (this.currentSchoolSysIndex >= index && index > 0) {
-                    this.currentSemesterIndex = 0
+                    this.curSemIndex = 0
                     this.currentSchoolSysIndex = 0
                 }
                 if (this.schoolSetting.period.length > 1) {
                     this.currentSchoolSysIndex = 0
-                    this.currentSemesterIndex = 0
+                    this.curSemIndex = 0
                     this.schoolSetting.period.splice(index, 1)
                     setTimeout(() => {
                         this.updated = false
@@ -328,8 +336,9 @@
             delSemester(index) {
                 if (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length > 1) {
                     this.currentSchoolSysIndex = 0
-                    this.currentSemesterIndex = 0
+                    this.curSemIndex = 0
                     this.schoolSetting.period[this.currentSchoolSysIndex].semesters.splice(index, 1)
+                    this.countSemDays()
                 } else {
                     this.$Message.warning(this.$t('schoolBaseInfo.ssTips2'))
                 }
@@ -391,11 +400,14 @@
             },
             //选择学期
             chooseSemester(index) {
-                this.currentSemesterIndex = index
+                if (index != this.curSemIndex) {
+                    this.editSemIndex = -1
+                    this.curSemIndex = index
+                }
             },
             //选择学段
             choosePeriod(index) {
-                this.currentSemesterIndex = 0
+                this.curSemIndex = 0
                 this.currentSchoolSysIndex = index
                 for (let item in this.schoolSetting.campuses) {
                     if (this.schoolSetting.campuses[item].campusCode === this.schoolSetting.period[this.currentSchoolSysIndex].campusCode) {
@@ -414,21 +426,21 @@
                                 break
                             } else {
                                 let sDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].day
-                                let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i+1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i+1].day
+                                let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].day
                                 let d = this.getDays(sDate, eDate)
                                 console.log(d)
                                 count -= d
                                 this.updateDays = true
-                                this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i],'days',d)
-                                
+                                this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i], 'days', d)
+
                             }
                         }
                         this.updateDays = true
                         this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[index], 'days', count)
-                        
+
                     }
                 }
-                
+
             },
             //保存数据
             saveData() {
@@ -440,6 +452,7 @@
                             this.$Message.success(this.$t('schoolBaseInfo.ssTips3'))
                             this.updated = false
                             this.isSaveLoading = false
+                            this.editSemIndex = -1
                         }
                     },
                     (err) => {
@@ -558,7 +571,9 @@
                 this.$refs.schoolName.handleEdit()
             },
             changeSemesterStatus(index) {
-                this.$refs.semesterName[index].handleEdit()
+                //this.$refs.semesterName[index].handleEdit()
+                this.editSemIndex = index
+
             },
             addSubject() {
                 if (this.termList.length < this.TERM_MAX_LENGTH) {
@@ -630,7 +645,7 @@
             handleAddTerm() {
                 if (this.termList.length < this.TERM_MAX_LENGTH) {
                     let newTerm = Object.assign({}, defaultTerm)
-                    let defMonth = this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length == 0 ? 1 : this.schoolSetting.period[this.currentSchoolSysIndex].semesters[this.currentSemesterIndex].month + 1
+                    let defMonth = this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length == 0 ? 1 : this.schoolSetting.period[this.currentSchoolSysIndex].semesters[this.curSemIndex].month + 1
                     this.schoolSetting.period[this.currentSchoolSysIndex].semesters.push({
                         semesterName: this.$t('schoolBaseInfo.persetSemester') + (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length + 1),
                         studentCount: '学生人数',
@@ -638,6 +653,7 @@
                         day: 26,
                         semesterCode: this.guid()
                     })
+                    this.countSemDays()
                 } else {
                     this.$Message.info(this.$t('schoolBaseInfo.ssTips7'))
                 }
@@ -743,11 +759,6 @@
             }
         },
         mounted() {
-            this.monthList = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
-            // this.monthList = [...Array(12).keys()];
-            this.gradeList = ['一年级', '二年级', '三年级', '四年级', '五年级']
-            this.subjectList = ['语文', '数学', '外语', '化学', '物理', '语文', '数学', '外语', '化学', '物理']
-            this.dayList = [...Array(30).keys()]
             this.monthEnList = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']
             this.colorList = ['#F16C6A', '#68CDF1', '#00796B', '#7C4DFF', '#0288D1', '#D32F2F', '#00796B', '#7C4DFF', '#0288D1', '#D32F2F', '#00796B', '#7C4DFF']
         },
@@ -757,10 +768,10 @@
                 if (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length == 1) {
                     end = 12
                     this.auto = true
-                } else if (this.currentSemesterIndex + 1 < this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length) {
-                    end = this.schoolSetting.period[this.currentSchoolSysIndex].semesters[this.currentSemesterIndex + 1].month
+                } else if (this.curSemIndex + 1 < this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length) {
+                    end = this.schoolSetting.period[this.currentSchoolSysIndex].semesters[this.curSemIndex + 1].month
                     this.auto = true
-                } else if (this.currentSemesterIndex + 1 == this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length) {
+                } else if (this.curSemIndex + 1 == this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length) {
                     end = this.schoolSetting.period[this.currentSchoolSysIndex].semesters[0].month
                     this.auto = false
                 }
@@ -772,45 +783,40 @@
                 } else {
                     return false
                 }
-            }
+            },
+            
         }
 
     }
 </script>
 
-<!-- 覆盖iview样式 -->
+<style lang="less" scoped>
+    @import './SystemSetting.less';
+</style>
 <style>
-    .term-item-start .ivu-select {
-        width: 60px;
-        color: rgb(191, 191, 191);
-        margin: 0 10px;
-    }
-
-    .term-item-start .ivu-select-selected-value {
-        font-size: 16px !important;
+    .second-arrow {
+        margin-left: -16px;
     }
 
-    .term-item-start .ivu-select-selection {
-        background: #333333;
-        border-color: rgba(196,196,196,.2);
-        border-radius: 8px;
+    .color-check {
+        color: #08d0c8;
     }
 
-    .term-item-start .ivu-select-arrow {
-        /*top:72%;*/
+    .color-uncheck {
+        color: #FF6C6B;
     }
 
-    .campus-modal .ivu-modal-content {
-        background-color: #383838 !important;
-        /*height: 750px;*/
+    .bg-color-check {
+        background-color: #08d0c8 !important;
     }
 
-    .campus-modal .ivu-modal-header {
-        border-color: #454545;
-        background-color: #383838;
+    .bg-color-uncheck {
+        background-color: #FF6C6B !important;
     }
 
-    .campus-modal .ivu-modal-footer {
-        border: none;
+    .semester-name-label .ivu-input[disabled] {
+        font-size: 20px !important;
+        font-weight: bold;
+        color: white;
     }
-</style>
+</style>

+ 0 - 1
TEAMModelOS/ClientApp/src/view/selflearning/ActivityReport.less

@@ -1 +0,0 @@
-

+ 0 - 20
TEAMModelOS/ClientApp/src/view/selflearning/ActivityReport.vue

@@ -1,20 +0,0 @@
-<template>
-    <div>
-        <h1 style="text-align:center; color:#808080;padding-top:300px;">学习活动仪表正在开发中,敬请期待!</h1>
-    </div>
-</template>
-<script>
-    export default {
-        data() {
-            return {
-
-            }
-        }
-    }
-</script>
-<style scoped lang="less">
-    @import "./ActivityReport.less";
-</style>
-<style lang="less">
-
-</style>

+ 0 - 67
TEAMModelOS/ClientApp/src/view/selflearning/CreateHomeWork.less

@@ -1,67 +0,0 @@
-@main-bgColor: rgb(40,40,40); //主背景颜色
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.create-self-container {
-    width: 100%;
-    height: 100%;
-
-    .create-self-header {
-        width: 100%;
-        height: 45px;
-        line-height: 45px;
-        padding: 0px 15px;
-        border-bottom: 1px solid @borderColor;
-    }
-
-    .create-self-main{
-        width:100%;
-        height:~"calc(100% - 45px)";
-        display:flex;
-        flex-direction:row;
-    }
-}
-.create-self-header {
-    &-label {
-        color: #fff;
-        font-size: 16px;
-    }
-}
-.btn-save {
-    color: rgb(107, 223, 195);
-    float: right;
-    cursor: pointer;
-    margin-top: 6px;
-    margin-right: 15px;
-}
-.create-self-main {
-    .self-base-info-box {
-        width: 350px;
-        height: 100%;
-        border-right: 1px solid @borderColor;
-        padding-left: 15px;
-
-        .self-base-info-header {
-            width: 100%;
-            height: 40px;
-            color: @second-textColor;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-        }
-    }
-
-    .self-content-box {
-        width: ~"calc(100% - 350px)";
-        height: 100%;
-        padding-left: 15px;
-        .self-content-box-header{
-            height:40px;
-            line-height:40px;
-            color:@second-textColor;
-            border-bottom:1px solid @borderColor;
-        }
-    }
-}

+ 0 - 43
TEAMModelOS/ClientApp/src/view/selflearning/CreateHomeWork.vue

@@ -1,43 +0,0 @@
-<template>
-    <div class="create-self-container">
-        <div class="create-self-header">
-            <span class="create-self-header-label">创建作业活动</span>
-            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveData">保存数据</Button>
-        </div>
-        <div class="create-self-main">
-            <div class="self-base-info-box">
-                <div class="self-base-info-header">
-                    <span>基础信息</span>
-                </div>
-            </div>
-            <div class="self-content-box">
-                <!--<div class="self-content-box-header">
-                    <span>自学内容</span>
-                </div>-->
-            </div>
-        </div>
-    </div>
-</template>
-<script>
-    export default {
-        data() {
-            return {
-                isLoading: false,
-
-            }
-        },
-        methods: {
-            saveData() {
-                this.isLoading = true
-                setTimeout(() => {
-                    this.isLoading = false
-                },2000)
-            }
-        }
-    }
-</script>
-<style lang="less" scoped>
-    @import "./CreateHomeWork.less";
-</style>
-<style>
-</style>

+ 0 - 137
TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.less

@@ -1,137 +0,0 @@
-@main-bgColor: rgb(40,40,40); //主背景颜色
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.create-self-container {
-    width: 100%;
-    height: 100%;
-
-    .create-self-header {
-        width: 100%;
-        height: 45px;
-        line-height: 45px;
-        padding: 0px 15px;
-        border-bottom: 1px solid @borderColor;
-    }
-
-    .create-self-main{
-        width:100%;
-        height:~"calc(100% - 45px)";
-        display:flex;
-        flex-direction:row;
-    }
-}
-.create-self-header {
-    &-label {
-        color: #fff;
-        font-size: 16px;
-    }
-}
-.btn-save {
-    color: rgb(107, 223, 195);
-    float: right;
-    cursor: pointer;
-    margin-top: 6px;
-    margin-right: 15px;
-}
-.create-self-main {
-    .self-base-info-box {
-        width: 350px;
-        height: 100%;
-        border-right: 1px solid @borderColor;
-        padding-left: 15px;
-
-        .self-base-info-header {
-            width: 100%;
-            height: 40px;
-            color: @second-textColor;
-            line-height: 40px;
-            border-bottom: 1px solid @borderColor;
-        }
-
-        .base-info-form {
-            width: 100%;
-            height: calc(100% - 45px);
-            padding-top: 30px;
-            padding-right: 15px;
-        }
-    }
-
-    .self-content-box {
-        width: ~"calc(100% - 350px)";
-        height: 100%;
-        padding-left: 15px;
-
-        .self-content-box-header {
-            height: 40px;
-            line-height: 40px;
-            color: @second-textColor;
-            border-bottom: 1px solid @borderColor;
-        }
-
-        .add-step-type-label {
-            padding: 6px 4px;
-            cursor: pointer;
-
-            &:hover {
-                color: aqua;
-            }
-        }
-    }
-}
-.learn-step-box{
-    width:100%;
-    height:100%;
-    .learn-step-header{
-        height:40px;
-        line-height:40px;
-        color:@second-textColor;
-        border-bottom:1px solid @borderColor;
-    }
-}
-.learn-step-content {
-    padding-left: 15px;
-    width:100%;
-    height:100%;
-    .learn-step-content-header {
-        height: 40px;
-        width: 100%;
-        line-height: 40px;
-        border-bottom: 1px solid @borderColor;
-        color: @second-textColor;
-    }
-}
-.edit-step-name-icon {
-    display: none;
-    cursor: pointer;
-    margin-right:16px;
-    color:white;
-}
-
-.content-type-label {
-    color: white;
-    line-height: 13px;
-    margin: 10px 0px 5px 0px;
-    padding: 5px;
-    padding-left: 8px;
-    border-left: 2px solid white;
-    background: #333333;
-}
-
-.content-file-wrap {
-    height: fit-content;
-    padding-bottom: 20px;
-    color: white;
-    margin-bottom: 10px;
-}
-
-.content-question-wrap {
-    min-height: 200px;
-    padding: 10px 0px 20px 0px;
-}
-.content-file-item {
-    margin-bottom: 4px;
-}

+ 0 - 500
TEAMModelOS/ClientApp/src/view/selflearning/CreateSelfLearn.vue

@@ -1,500 +0,0 @@
-<template>
-    <div class="create-self-container">
-        <div class="create-self-header">
-            <span class="create-self-header-label">创建自主学习</span>
-            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveData">保存数据</Button>
-        </div>
-        <div class="create-self-main">
-            <div class="self-base-info-box">
-                <div class="self-base-info-header">
-                    <span>基础信息</span>
-                </div>
-                <!--<vuescroll>  -->
-                <div class="base-info-form dark-iview-input dark-iview-select">
-                    <Form ref="selfLearnInfo" :model="selfLearnInfo" label-position="top" class="evaluation-attr-form" :rules="ruleValidate" label-colon>
-                        <FormItem label="活动名称" prop="name">
-                            <Input v-model="selfLearnInfo.name"></Input>
-                        </FormItem>
-                        <FormItem label="学段" prop="periodCode">
-                            <Select v-model="selfLearnInfo.periodCode">
-                                <Option v-for="(item,index) in $store.state.schoolBaseInfo.schoolBaseInfo.period" :value="item.periodCode" :key="index">{{ item.periodName }}</Option>
-                            </Select>
-                        </FormItem>
-                        <FormItem label="科目" prop="subjectCode">
-                            <Select v-model="selfLearnInfo.subjectCode" not-found-text="请先选择学段">
-                                <Option v-for="(item,index) in $jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo,selfLearnInfo.periodCode).subjects" :value="item.subjectCode" :key="index">{{ item.subjectName }}</Option>
-                            </Select>
-                        </FormItem>
-                        <FormItem label="学习对象" prop="target">
-                            <Select v-model="selfLearnInfo.target">
-                                <Option v-for="(item,index) in classroomList" :value="item" :key="index">{{ item }}</Option>
-                            </Select>
-                        </FormItem>
-                        <FormItem label="截止时间" prop="expire">
-                            <DatePicker type="date" placeholder="设置截止时间" style="width:100%;"></DatePicker>
-                        </FormItem>
-                        <FormItem label="闯关模式" prop="isOrder">
-                            <div slot="label" style="display:inline-block;">
-                                <span>闯关模式:</span>
-                                <Tooltip trigger="hover" content="是否必须通过阶段测试才能进入下一阶段学习" theme="light" placement="right" max-width="200">
-                                    <Icon type="md-help" color="white" style="cursor:pointer;" />
-                                </Tooltip>
-                            </div>
-                            <RadioGroup v-model="selfLearnInfo.isOrder" style="color:#aaaaaa;">
-                                <Radio label="1">是</Radio>
-                                <Radio label="0" style="margin-left:30px;">否</Radio>
-                            </RadioGroup>
-                        </FormItem>
-
-                        <FormItem label="活动说明" prop="introduce">
-                            <Input v-model="selfLearnInfo.introduce" type="textarea" :rows="6"></Input>
-                        </FormItem>
-                    </Form>
-                </div>
-
-                <!--</vuescroll>-->
-            </div>
-            <div class="self-content-box dark-iview-split">
-                <Split v-model="split1">
-                    <div slot="left" class="learn-step-box dark-iview-table">
-                        <div class="learn-step-header">
-                            <span>自学步骤</span>
-                            <Tooltip style="float:right;" placement="left">
-                                <Icon style="margin-right:15px;cursor:pointer;" type="md-add" size="20" color="white" />
-                                <div slot="content">
-                                    <p class="add-step-type-label" @click="toggleSelectUnit"><Icon type="ios-pricetag-outline" size="18" style="margin-right:5px;" />选择最小单元</p>
-                                    <p class="add-step-type-label" @click="toggleSelectOrder"><Icon type="ios-list" size="20" style="margin-right:5px;" />选择编序式教材</p>
-                                    <p class="add-step-type-label" @click="addCustomStatus = true"><Icon type="ios-hand-outline" size="18" style="margin-right:5px;" />手动选择内容</p>
-                                </div>
-                            </Tooltip>
-                        </div>
-                        <Table draggable :columns="columns" :data="selfLearnInfo.steps" @on-drag-drop="dragOrder" @on-row-click="getCurrentItem" :row-class-name="setClassName" style="width:100%;" :show-header="false">
-                            <template slot-scope="{ row, index }" slot="name">
-                                <Icon type="ios-pricetags" color="white" style="margin-right:8px;" />
-                                <span class="learn-step-name">{{row.name}}</span>
-                            </template>
-                            <template slot-scope="{ row, index }" slot="action">
-                                <Icon type="md-create" class="edit-step-name-icon" @click="editSName(index)" />
-                                <Icon type="md-trash" class="edit-step-name-icon" @click="deleteStep(index)" />
-                            </template>
-                        </Table>
-                    </div>
-                    <div slot="right" class="learn-step-content">
-                        <div class="learn-step-content-header">
-                            <span>
-                                自学资源
-                            </span>
-                        </div>
-                        <div style="height:calc(100% - 45px);" v-if="selfLearnInfo.steps.length !== 0">
-                            <vuescroll>
-                                <p class="content-type-label">内容:{{selfLearnInfo.steps[stepIndex].resource.length}}个</p>
-                                <div class="content-file-wrap">
-                                    <ContentFileList :resources="selfLearnInfo.steps[stepIndex].resource"></ContentFileList>
-                                </div>
-                                <p class="content-type-label">题目:{{selfLearnInfo.steps[stepIndex].item.length}}道</p>
-                                <div class="content-question-wrap">
-                                    <EmptyData v-if="selfLearnInfo.steps[stepIndex].item.length == 0" style="margin-top:30px;"></EmptyData>
-                                    <QuestionList v-else :questions="selfLearnInfo.steps[stepIndex].item"></QuestionList>
-                                </div>
-                            </vuescroll>
-                        </div>
-                        <EmptyData style="margin-top:30px;" v-if="selfLearnInfo.steps.length == 0"></EmptyData>
-                    </div>
-                </Split>
-            </div>
-        </div>
-        <Modal v-model="selectUnitStatus"
-               title="选择最小单元"
-               class="dark-iview-modal"
-               width="960"
-               @on-ok="confirmSelectUnit">
-            <SelectLearnUnit @selectUnit="getSelectedUnit"></SelectLearnUnit>
-        </Modal>
-        <Modal v-model="selectOrderStatus"
-               title="选择编序式教材"
-               width="960"
-               class="dark-iview-modal"
-               @on-ok="confirmSelectOrder">
-            <SelectOrderLearn @selectOrderLearn="getSelectdOrderLearn"></SelectOrderLearn>
-        </Modal>
-        <Modal v-model="addCustomStatus"
-               title="自定义选择内容"
-               width="960"
-               class="dark-iview-modal dark-iview-input"
-               @on-ok="confirmAddCustom">
-            <span>名称:</span>
-            <Input v-model="newStepName" placeholder="请输入名称..." style="width: calc(100% - 50px);" />
-            <div style="width:100%; height:660px;margin-top:15px;">
-                <ChooseContent></ChooseContent>
-            </div>
-        </Modal>
-        <Modal v-model="editStepStatus"
-               title="修改名称"
-               class="dark-iview-modal dark-iview-input"
-               @on-ok="confirmEditStep">
-            <span>名称:</span>
-            <Input v-model="editStepName" placeholder="请输入名称..." style="width: calc(100% - 50px);" />
-        </Modal>
-        <Modal v-model="goToManageStatus"
-               title="管理自学活动"
-               ok-text="是"
-               cancel-text="否"
-               @on-ok="confirmToManage">
-            <p>自学活动保存成功,是否跳转到管理页面查看?</p>
-        </Modal>
-    </div>
-</template>
-<script>
-    import ChooseContent from '@/components/learnactivity/ChooseContent.vue'
-    import QuestionList from '@/components/learnactivity/QuestionList.vue'
-    import SelectLearnUnit from '@/components/learnactivity/SelectLearnUnit.vue'
-    import SelectOrderLearn from '@/components/learnactivity/SelectOrderLearn.vue'
-    
-    import ContentFileList from '@/components/learnactivity/ContentFileList.vue'
-    export default {
-        components: {
-            ChooseContent,
-            
-            QuestionList,
-            SelectLearnUnit,
-            SelectOrderLearn,
-            ContentFileList
-        },
-        data() {
-            return {
-                goToManageStatus: false,
-                selectedOrderLearn: [],
-                selectedUnit:[],
-                editStepName: '',
-                stepIndex: 0,
-                newStepName: '',
-                ruleValidate: {
-                    name: [
-                        { required: true, message: '请完善活动名称', trigger: 'change' }
-                    ],
-                    periodCode: [
-                        { required: true, message: '请选择学段', trigger: 'change' }
-                    ],
-                    subjectCode: [
-                        { required: true, message: '请选择学科', trigger: 'change' }
-                    ],
-                    isOrder: [
-                        { required: true, message: '请选择模式', trigger: 'change' }
-                    ],
-                    //target: [
-                    //    { required: true, message: '请选择发布对象', trigger: 'change' }
-                    //],
-                    introduce: [
-                        { required: true, message: '请完善说明信息', trigger: 'change' }
-                    ]
-                },
-                editStepStatus: false,
-                selectUnitStatus: false,
-                selectOrderStatus: false,
-                addCustomStatus: false,
-                split1: 0.2,
-                isLoading: false,
-                selfLearnInfo: {
-                    name: '',
-                    periodCode: '',
-                    subjectCode: '',
-                    target: [],
-                    isOrder: '',
-                    creator: '',
-                    introduce: '',
-                    expire: 0,
-                    steps: []
-                },
-                addStepStatus: false,
-                classroomList: [],
-                isLoading: false,
-                columns: [
-                    {
-                        title: '',
-                        slot: 'name',
-                        ellipsis: true
-                    },
-                    {
-                        title: '',
-                        slot: 'action',
-                        width: 80,
-                        align: 'right'
-                    }
-                ],
-            }
-        },
-        methods: {
-            confirmToManage() {
-                this.$router.push({
-                    name: 'manageSelfLearn'
-                })
-            },
-            /**
-             * 处理SelectLearnUnit组件选择事件
-             * @param data
-             */
-            getSelectedUnit(data) {
-                this.selectedUnit = data
-            },
-            confirmSelectUnit() {
-                let itemPromise = []
-                let resourcePromise = []
-                for (let i = 0; i < this.selectedUnit.length; i++) {
-                    itemPromise.push(this.$api.learnActivity.FindQuestionById(this.selectedUnit[i].item))
-                    resourcePromise.push(this.$api.learnActivity.FindSyllabusResourceById(this.selectedUnit[i].resource))
-                }
-                Promise.all(itemPromise).then(
-                    itemRes => {
-                        console.log('itemRes')
-                        console.log(itemRes)
-                        Promise.all(resourcePromise).then(
-                            resourceRes => {
-                                console.log('resourceRes')
-                                console.log(resourceRes)
-                                for (let i = 0; i < this.selectedUnit.length; i++) {
-                                    this.selectedUnit[i].item = itemRes[i].result.data
-                                    this.selectedUnit[i].resource = resourceRes[i].result.data
-                                }
-                                this.selfLearnInfo.steps.push(...this.selectedUnit)
-                                console.log(this.selfLearnInfo)
-                                this.selectedUnit.length = 0
-                            },
-                            err => {
-                                console.log('err')
-                                console.log(err)
-                            }
-                        )
-                    },
-                    err => {
-                        console.log('err')
-                        console.log(err)
-                    }
-                )
-            },
-            /**
-             * 处理SelectOrderLearn组件选择事件
-             * @param data
-             */
-            getSelectdOrderLearn(data) {
-                this.selectedOrderLearn = data
-            },
-            confirmSelectOrder() {
-                let itemPromise = []
-                let resourcePromise = []
-                console.log(this.selectedOrderLearn)
-                for (let i = 0; i < this.selectedOrderLearn.length; i++) {
-                    for (let j = 0; j < this.selectedOrderLearn[i].steps.length; j++) {
-                        itemPromise.push(this.$api.learnActivity.FindQuestionById(this.selectedOrderLearn[i].steps[j].item))
-                        resourcePromise.push(this.$api.learnActivity.FindSyllabusResourceById(this.selectedOrderLearn[i].steps[j].resource))
-                    }
-                }
-                Promise.all(itemPromise).then(
-                    itemRes => {
-                        console.log('itemRes')
-                        console.log(itemRes)
-                        Promise.all(resourcePromise).then(
-                            resourceRes => {
-                                console.log('resourceRes')
-                                console.log(resourceRes)
-                                for (let i = 0; i < this.selectedOrderLearn.length; i++) {
-                                    for (let j = 0; j < this.selectedOrderLearn[i].steps.length; j++) {
-                                        let index = i * this.selectedOrderLearn.length + j
-                                        console.log(index)
-                                        this.selectedOrderLearn[i].steps[j].item = itemRes[index].result.data
-                                        this.selectedOrderLearn[i].steps[j].resource = resourceRes[index].result.data
-                                    }
-                                    this.selfLearnInfo.steps.push(...this.selectedOrderLearn[i].steps)
-                                }
-                                this.selectedOrderLearn.length = 0
-                            },
-                            err => {
-                                console.log('err')
-                                console.log(err)
-                            }
-                        )
-                    },
-                    err => {
-                        console.log('err')
-                        console.log(err)
-                    }
-                )
-                
-            },
-            /**
-             * 通过id查询题目信息
-             * */
-            findQuestionById(ids) {
-                if (ids.length > 0) {
-                    this.listLoading = true
-                    this.$api.learnActivity.FindQuestionById(ids).then(
-                        res => {
-                            if (res.error == null) {
-                                return res.result.data
-                            } else {
-                                this.$Message.error("API ERROR!")
-                            }
-                            setTimeout(() => {
-                                this.listLoading = false
-                            }, 500)
-                        },
-                        err => {
-                            this.$Message.error("API ERROR!")
-                            setTimeout(() => {
-                                this.listLoading = false
-                            }, 1000)
-                        }
-                    )
-                }
-            },
-            /**
-             * 通过id查询内容信息
-             * */
-            findResourceById(ids) {
-                if (ids.length > 0) {
-                    this.listLoading = true
-                    this.$api.learnActivity.FindSyllabusResourceById(ids).then(
-                        res => {
-                            if (res.error == null) {
-                                return res.result.data
-                            } else {
-                                this.$Message.error("API ERROR!")
-                            }
-                            setTimeout(() => {
-                                this.listLoading = false
-                            }, 500)
-                        },
-                        err => {
-                            this.$Message.error("API ERROR!")
-                            setTimeout(() => {
-                                this.listLoading = false
-                            }, 500)
-                        }
-                    )
-                }
-            },
-            deleteStep(index) {
-                this.$Modal.confirm({
-                    title: '删除',
-                    content: '是否确定删除此学习步骤',
-                    okText: '是',
-                    cancelText: '否',
-                    onOk: () => {
-                        this.selfLearnInfo.steps.splice(index, 1)
-                    }
-                })
-            },
-            confirmEditStep() {
-                this.selfLearnInfo.steps[this.stepIndex].name = this.editStepName
-            },
-            editSName(index) {
-                this.editStepName = this.selfLearnInfo.steps[index].name
-                this.editStepStatus = true
-            },
-            getCurrentItem(row, index) {
-                this.stepIndex = index
-            },
-            setClassName(row, index) {
-                if (index == this.stepIndex) {
-                    return 'ivu-table-row-highlight'
-                }
-            },
-            /**
-             * table拖拽调整顺序
-             * @param index1
-             * @param index2
-             */
-            dragOrder(index1, index2) {
-                if (index1 > index2) {
-                    let item = this.selfLearnInfo.steps[index1];
-                    this.selfLearnInfo.steps.splice(index1, 1);
-                    this.selfLearnInfo.steps.splice(index2, 0, item);
-                } else if (index1 < index2) {
-                    let item = this.selfLearnInfo.steps[index1];
-                    this.selfLearnInfo.steps.splice(index2, 0, item);
-                    this.selfLearnInfo.steps.splice(index1, 1);
-                }
-            },
-            
-            
-            confirmAddCustom() {
-                this.selfLearnInfo.steps.push(
-                    {
-                        name: this.newStepName,
-                        resource: [],
-                        item: []
-                    }
-                )
-                this.newStepName = ''
-            },
-            toggleSelectUnit() {
-                this.selectUnitStatus = true
-            },
-            toggleSelectOrder() {
-                this.selectOrderStatus = true
-            },
-            checkData() {
-                let flag = true
-                this.$refs.selfLearnInfo.validate((valid) => {
-                    if (!valid) {
-                        flag = false
-                    }
-                })
-                return flag
-            },
-            saveData() {
-                let check = this.checkData()
-                if (check) {
-                    this.isLoading = true
-                    this.selfLearnInfo.code = this.$store.state.userInfo.TEAMModelId
-                    this.selfLearnInfo.creator = this.$store.state.userInfo.TEAMModelId
-                    this.$api.learnActivity.SaveSelfLearn([this.selfLearnInfo]).then(
-                        res => {
-                            if (res.error == null) {
-                                this.selfLearnInfo.id = res.result.data.id
-                                this.goToManageStatus = true
-                            } else {
-                                this.$Message.error("API ERROR!")
-                            }
-                            this.isLoading = false
-                        },
-                        err => {
-                            this.isLoading = false
-                        }
-                    )   
-                } else {
-                    this.$Message.error("请先完成必填信息")
-                }
-            }
-        },
-        created() {
-            let routerData = this.$route.params.selfLearnInfo
-            if (routerData != undefined) {
-                this.selfLearnInfo = routerData
-            }
-        }
-    }
-</script>
-<style lang="less" scoped>
-    @import "./CreateSelfLearn.less";
-</style>
-<style>
-    .learn-step-header .ivu-tooltip-inner {
-        background-color: rgba(70,76,91,1);
-    }
-
-    .base-info-form .ivu-form .ivu-form-item-label {
-        color: #A5A5A5;
-    }
-
-    .learn-step-box .ivu-table-row-highlight {
-        background-image: linear-gradient(90deg, rgba(30, 30, 30, 0) 0%, rgba(110, 110, 110, 0.2) 50%, rgba(110, 110, 110, 0.4) 100%);
-    }
-
-    .learn-step-box .ivu-table-row-hover .edit-step-name-icon {
-        display: inline-block;
-    }
-
-    .learn-step-box .ivu-table-row-hover td {
-        background: none !important;
-    }
-</style>

+ 0 - 111
TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.less

@@ -1,111 +0,0 @@
-@main-bgColor: rgb(40,40,40); //主背景颜色
-@borderColor: #424242;
-@primary-textColor: #fff; //文本主颜色
-@second-textColor: #a5a5a5; //文本副级颜色
-@primary-fontSize: 14px;
-@second-fontSize: 16px;
-
-.learn-progress-container {
-    width: 100%;
-    height: 100%;
-
-    .learn-progress-main {
-        width: 100%;
-        height: ~"calc(100% - 45px)";
-        padding-right: 10px;
-
-        .whole-progress-wrap {
-            width: 100%;
-            height: 300px;
-            display: flex;
-            flex-direction: row;
-
-            .progress-histogram-wrap {
-                width: 50%;
-                height: 100%;
-            }
-
-            .progress-detail-wrap {
-                width: 22%;
-                height: 100%;
-                color: white;
-                padding-right: 20px;
-                display:table;
-                padding-top:10px;
-                .student-type-label {
-                    font-size: 16px;
-                    color: #69efef;
-                    border-left: 3px solid #69efef;
-                    line-height: 14px;
-                    padding-left:5px;
-                    display: inline-block;
-                }
-
-                .student-name-wrap {
-                    color: #aaaaaa;
-                    font-size: 14px;
-                    margin-top: 10px;
-                    line-height:30px;
-                }
-            }
-        }
-    }
-}
-.learn-progress-filter {
-    width: ~"calc(100% - 40px)";
-    height: 40px;
-    line-height: 40px;
-    background: rgba(50, 50, 50, .6);
-    padding-left: 4px;
-    border-radius: 5px;
-    margin:auto;
-    /*margin-bottom: 20px;*/
-
-    .filter-label {
-        color: white;
-    }
-
-    .right-filter-wrap {
-        display: inline-block;
-        float: right;
-    }
-}
-.radio-box-wrap {
-    display: inline-block;
-    float: right;
-    margin-right: 55px;
-    margin-left: 30px;
-
-    .active-radio-box-item {
-        background: white;
-        color: black !important;
-    }
-
-    .radio-box-item {
-        color: white;
-
-        &:first-child {
-            border-top-left-radius: 5px;
-            border-bottom-left-radius: 5px;
-        }
-
-        &:last-child {
-            border-top-right-radius: 5px;
-            border-bottom-right-radius: 5px;
-            border-left: 0px;
-        }
-
-        line-height: 10px;
-        display: inline-block;
-        padding: 2px 10px;
-        border: 1px solid white;
-        cursor: pointer;
-    }
-}
-.to-detail-info {
-    cursor: pointer;
-    text-decoration: underline;
-}
-.to-detail-info:hover {
-    color: aqua;
-}

+ 0 - 240
TEAMModelOS/ClientApp/src/view/selflearning/LearnProgress.vue

@@ -1,240 +0,0 @@
-<template>
-    <div class="learn-progress-container">
-        <div class="learn-progress-main dark-iview-table">
-            <vuescroll>
-                <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:15px;">活动进度概览</p>
-                <div class="whole-progress-wrap">
-                    <div class="progress-histogram-wrap" style="margin:auto;">
-                        <!--<ProgressHistogram @clickStep="clickStep"></ProgressHistogram>-->
-                    </div>
-                </div>
-                <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:50px;margin-bottom:30px;">
-                    学生进度概览
-                </p>
-                <div class="learn-progress-filter dark-iview-select">
-                    <span class="filter-label">搜学生:</span>
-                    <Select v-model="model11" filterable style="display: inline-block;width: 200px;" size="small">
-                        <Option v-for="item in studentList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                    </Select>
-                    <!--<span class="filter-label" style="margin-left:30px;">选班级:</span>
-                    <Select v-model="model11" filterable style="display:inline-block;width:200px;" size="small">
-                        <Option v-for="item in classroomList" :value="item.value" :key="item.value">{{ item.label }}</Option>
-                    </Select>-->
-                </div>
-                <Table :columns="studentColumns" :data="studentPageData" :show-header="true" style="margin:0px 25px;">
-                    <template slot-scope="{ row, index }" slot="isComplete">
-                        <Icon size="20" type="md-checkmark" color="aqua" v-if="row.isComplete == 1" />
-                        <span v-else>--</span>
-                    </template>
-                    <template slot-scope="{ row, index }" slot="progress">
-                        <Progress :percent="50" status="normal" />
-                    </template>
-                    <template slot-scope="{ row, index }" slot="question">
-                        <div>
-                            <span title="提问/留言 次数">
-                                <Icon type="ios-create" size="16"/>5
-                            </span>
-                            <span style="color:rgb(45, 241, 142);margin-left:10px;">
-                                <Icon type="md-thumbs-up" />32
-                            </span>
-                            <span style="color:#f90;margin-left:10px;">
-                                <Icon type="md-thumbs-down" />10
-                            </span>
-                        </div>
-                    </template>
-                    <template slot-scope="{ row, index }" slot="action">
-                        <span @click="goToAnswer" class="to-detail-info">查看详情</span>
-                    </template>
-                </Table>
-                <div style="width:100%;text-align:center;margin-top:20px;" class="dark-iview-page">
-                    <Page :total="studentData.length" size="small" :current.sync="currentPage" :page-size="pageSize" show-sizer show-total @on-change="getPageData" @on-page-size-change="getPageData($event,'size')"/>
-                </div>
-            </vuescroll>
-        </div>
-    </div>
-</template>
-<script>
-    //import ProgressHistogram from '@/components/learnactivity/ProgressHistogram.vue'
-    export default {
-        //components: {
-        //    ProgressHistogram
-        //},
-        data() {
-            return {
-                pageSize: 10,
-                currentPage:1,
-                dataIndex: 1,
-                model11: '',
-                currentView: 0,
-                studentList: [],
-                classroomList: [],
-                columns: [
-                    {
-                        title: '学习阶段',
-                        key: 'name',
-                        //align:'center'
-                    },
-                    {
-                        title: '完成进度',
-                        slot: 'progress',
-                        align: 'center'
-                    },
-                    {
-                        title: '操作',
-                        slot: 'action',
-                        width: 150
-                    }
-                ],
-                data: [
-                    {
-                        name: '一次函数基础',
-                        progress: 50
-                    },
-                    {
-                        name: '一次函数进阶',
-                        progress: 50,
-
-                    },
-                    {
-                        name: '一次函数高阶',
-                        progress: 50,
-
-                    },
-                    {
-                        name: '一次函数总结',
-                        progress: 50,
-                    },
-                ],
-                studentData: [
-                    {
-                        name: '张飞',
-                        isComplete: 1
-                    },
-                    {
-                        name: '孔子',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '柏拉图',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '苏格拉底',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '杜威',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '老夫子',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '张飞',
-                        isComplete: 1
-                    },
-                    {
-                        name: '孔子',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '柏拉图',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '苏格拉底',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '杜威',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '老夫子',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '张飞',
-                        isComplete: 1
-                    },
-                    {
-                        name: '孔子',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '柏拉图',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '苏格拉底',
-                        isComplete: 1,
-                    },
-                    {
-                        name: '杜威',
-                        isComplete: 0,
-                    },
-                    {
-                        name: '老夫子11',
-                        isComplete: 1,
-                    }
-                ],
-                studentPageData:[],
-                studentColumns: [
-                    {
-                        title: '姓名',
-                        key: 'name',
-                        width:180
-                    },
-                    {
-                        title: '学习进度',
-                        slot: 'progress',
-                        width: 200,
-                        align: 'center'
-                    },
-                    {
-                        title: '提问/留言',
-                        slot: 'question',
-                        align: 'center'
-                    },
-                    {
-                        title: '操作',
-                        slot: 'action',
-                        width: 100
-                    }
-
-                ],
-            }
-        },
-        methods: {
-            clickStep(data) {
-                this.dataIndex = data.dataIndex
-            },
-            setCurrentView(index) {
-                this.currentView = index
-            },
-            getPageData(number, type) {
-                if (type == 'size') {
-                    this.pageSize = number
-                }
-                console.log(this.pageSize)
-                console.log(this.currentPage)
-                let starIndex = this.pageSize * (this.currentPage - 1)
-                let endIndex = this.pageSize * this.currentPage > this.studentData.length ? this.studentData.length : this.pageSize * this.currentPage
-                this.studentPageData = this.studentData.slice(starIndex, endIndex)
-            },
-            goToAnswer() {
-                this.$emit('goToAnswer')
-            }
-        },
-        created() {
-            this.getPageData()
-        }
-    }
-</script>
-<style scoped lang="less">
-@import "./LearnProgress.less";
-</style>
-<style>
-
-</style>

+ 0 - 0
TEAMModelOS/ClientApp/src/view/selflearning/ManageSelfLearn.less


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