Преглед изворни кода

Merge branch 'develop5.0-tmd' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop5.0-tmd

zhouj1203@hotmail.com пре 4 година
родитељ
комит
fa4a8e1a96
67 измењених фајлова са 1200 додато и 2354 уклоњено
  1. 39 0
      TEAMModelAPI/Controllers/WeatherForecastController.cs
  2. 26 0
      TEAMModelAPI/Program.cs
  3. 31 0
      TEAMModelAPI/Properties/launchSettings.json
  4. 59 0
      TEAMModelAPI/Startup.cs
  5. 11 0
      TEAMModelAPI/TEAMModelAPI.csproj
  6. 15 0
      TEAMModelAPI/WeatherForecast.cs
  7. 9 0
      TEAMModelAPI/appsettings.Development.json
  8. 10 0
      TEAMModelAPI/appsettings.json
  9. 7 4
      TEAMModelFunction/CourseServiceBus.cs
  10. 5 5
      TEAMModelFunction/StuListServiceBus.cs
  11. 3 2
      TEAMModelFunction/TriggerStuActivity.cs
  12. 9 45
      TEAMModelFunction/TriggerSurvey.cs
  13. 1 39
      TEAMModelFunction/TriggerVote.cs
  14. 5 0
      TEAMModelOS.SDK/Models/Cosmos/Common/StuCourse.cs
  15. 6 0
      TEAMModelOS.sln
  16. 31 3
      TEAMModelOS/ClientApp/src/api/studentWeb.js
  17. 1 0
      TEAMModelOS/ClientApp/src/components/evaluation/OptionsTable.vue
  18. 152 0
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseMiniBar.vue
  19. 2 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnBar.vue
  20. 108 88
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQnForm.vue
  21. 13 1
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.less
  22. 70 41
      TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue
  23. 3 3
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContent.vue
  24. 10 2
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/LessonTestReport.vue
  25. 5 0
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue
  26. 14 14
      TEAMModelOS/ClientApp/src/components/student-web/EventView/EventList.vue
  27. 3 7
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseList.vue
  28. 13 18
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue
  29. 7 7
      TEAMModelOS/ClientApp/src/components/student-web/HomeView/MissionListCard.vue
  30. 52 52
      TEAMModelOS/ClientApp/src/components/vote/BaseVoteForm.vue
  31. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/en-US/schoolBaseInfo.js
  32. 5 0
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/schoolBaseInfo.js
  33. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-CN/survey.js
  34. 8 3
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/schoolBaseInfo.js
  35. 1 1
      TEAMModelOS/ClientApp/src/locale/lang/zh-TW/survey.js
  36. 1 0
      TEAMModelOS/ClientApp/src/utils/evTools.js
  37. 4 4
      TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.less
  38. 39 18
      TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue
  39. 9 7
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseImport.vue
  40. 6 4
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  41. 1 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/TestPaper.vue
  42. 11 9
      TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue
  43. 0 281
      TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/Index.less
  44. 0 938
      TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/Index.vue
  45. 0 175
      TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/AddBlock.vue
  46. 0 187
      TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/AddPoint.vue
  47. 0 280
      TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/ComposeBlock.vue
  48. 3 2
      TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue
  49. 6 5
      TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue
  50. 6 3
      TEAMModelOS/ClientApp/src/view/learnactivity/ManualPaper.vue
  51. 3 0
      TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue
  52. 3 0
      TEAMModelOS/ClientApp/src/view/learnactivity/MgtSchoolEva.vue
  53. 5 1
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.less
  54. 42 22
      TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue
  55. 1 1
      TEAMModelOS/ClientApp/src/view/learnactivity/PrivScoring.vue
  56. 1 3
      TEAMModelOS/ClientApp/src/view/learnactivity/Scoring.vue
  57. 6 9
      TEAMModelOS/ClientApp/src/view/newcourse/NewCusMgt.vue
  58. 7 2
      TEAMModelOS/ClientApp/src/view/newcourse/TeaTable.vue
  59. 33 24
      TEAMModelOS/ClientApp/src/view/questionnaire/ManageQuestionnaire.vue
  60. 6 7
      TEAMModelOS/ClientApp/src/view/schoolmgmt/ClassroomSetting/ClassroomSetting.vue
  61. 66 4
      TEAMModelOS/ClientApp/src/view/schoolmgmt/SystemSetting/SystemSetting.vue
  62. 2 1
      TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.less
  63. 3 3
      TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue
  64. 1 1
      TEAMModelOS/Controllers/Analysis/AnalysisController.cs
  65. 128 18
      TEAMModelOS/Controllers/School/CourseController.cs
  66. 50 0
      TEAMModelOS/Controllers/School/StudentCommonController.cs
  67. 17 7
      TEAMModelOS/Services/Common/ActivityStudentService.cs

+ 39 - 0
TEAMModelAPI/Controllers/WeatherForecastController.cs

@@ -0,0 +1,39 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelAPI.Controllers
+{
+    [ApiController]
+    [Route("[controller]")]
+    public class WeatherForecastController : ControllerBase
+    {
+        private static readonly string[] Summaries = new[]
+        {
+            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
+        };
+
+        private readonly ILogger<WeatherForecastController> _logger;
+
+        public WeatherForecastController(ILogger<WeatherForecastController> logger)
+        {
+            _logger = logger;
+        }
+
+        [HttpGet]
+        public IEnumerable<WeatherForecast> Get()
+        {
+            var rng = new Random();
+            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
+            {
+                Date = DateTime.Now.AddDays(index),
+                TemperatureC = rng.Next(-20, 55),
+                Summary = Summaries[rng.Next(Summaries.Length)]
+            })
+            .ToArray();
+        }
+    }
+}

+ 26 - 0
TEAMModelAPI/Program.cs

@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelAPI
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+    }
+}

+ 31 - 0
TEAMModelAPI/Properties/launchSettings.json

@@ -0,0 +1,31 @@
+{
+  "$schema": "http://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:47420",
+      "sslPort": 44371
+    }
+  },
+  "profiles": {
+    "IIS Express": {
+      "commandName": "IISExpress",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "TEAMModelAPI": {
+      "commandName": "Project",
+      "dotnetRunMessages": "true",
+      "launchBrowser": true,
+      "launchUrl": "swagger",
+      "applicationUrl": "https://localhost:5001;http://localhost:5000",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 59 - 0
TEAMModelAPI/Startup.cs

@@ -0,0 +1,59 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.HttpsPolicy;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using Microsoft.OpenApi.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelAPI
+{
+    public class Startup
+    {
+        public Startup(IConfiguration configuration)
+        {
+            Configuration = configuration;
+        }
+
+        public IConfiguration Configuration { get; }
+
+        // This method gets called by the runtime. Use this method to add services to the container.
+        public void ConfigureServices(IServiceCollection services)
+        {
+
+            services.AddControllers();
+            services.AddSwaggerGen(c =>
+            {
+                c.SwaggerDoc("v1", new OpenApiInfo { Title = "TEAMModelAPI", Version = "v1" });
+            });
+        }
+
+        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+                app.UseSwagger();
+                app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TEAMModelAPI v1"));
+            }
+
+            app.UseHttpsRedirection();
+
+            app.UseRouting();
+
+            app.UseAuthorization();
+
+            app.UseEndpoints(endpoints =>
+            {
+                endpoints.MapControllers();
+            });
+        }
+    }
+}

+ 11 - 0
TEAMModelAPI/TEAMModelAPI.csproj

@@ -0,0 +1,11 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>net5.0</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
+  </ItemGroup>
+
+</Project>

+ 15 - 0
TEAMModelAPI/WeatherForecast.cs

@@ -0,0 +1,15 @@
+using System;
+
+namespace TEAMModelAPI
+{
+    public class WeatherForecast
+    {
+        public DateTime Date { get; set; }
+
+        public int TemperatureC { get; set; }
+
+        public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+
+        public string Summary { get; set; }
+    }
+}

+ 9 - 0
TEAMModelAPI/appsettings.Development.json

@@ -0,0 +1,9 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  }
+}

+ 10 - 0
TEAMModelAPI/appsettings.json

@@ -0,0 +1,10 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  },
+  "AllowedHosts": "*"
+}

+ 7 - 4
TEAMModelFunction/CourseServiceBus.cs

@@ -38,6 +38,9 @@ namespace TEAMModelFunction
                 await _dingDing.SendBotMsg($"ServiceBus,CourseChange:{msg}", GroupNames.醍摩豆服務運維群組);
                 var jsonMsg = JsonDocument.Parse(msg);
                 CourseChange courseChange = msg.ToObject<CourseChange>();
+                if (courseChange == null) {
+                    return;
+                }
                 //根据新增名单获取 新增的学生id 及timdid
                 (List<string> addTmdids, List<Students> addStudents) = await TriggerStuActivity.GetStuList(client, courseChange.addList, courseChange.school);
                 //根据删除名单获取 新增的学生id 及timdid
@@ -49,11 +52,11 @@ namespace TEAMModelFunction
                         id = courseChange.id,
                         scode = courseChange.code,
                         name = courseChange.name,
-                        code = $"Course-{courseChange.school}-{addStu.id}",
+                        code = $"StuCourse-{courseChange.school}-{addStu.id}",
                         scope = courseChange.scope,
                         school = courseChange.school,
                         creatorId = courseChange.creatorId,
-                        pk = "Course"
+                        pk = "StuCourse"
                     };
                     await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(course, new PartitionKey(course.code));
                 }
@@ -64,11 +67,11 @@ namespace TEAMModelFunction
                         id = courseChange.id,
                         scode = courseChange.code,
                         name = courseChange.name,
-                        code = $"Course-{addTmd}",
+                        code = $"StuCourse-{addTmd}",
                         scope = courseChange.scope,
                         //school = courseChange.school,
                         creatorId = courseChange.creatorId,
-                        pk = "Course"
+                        pk = "StuCourse"
                     };
                     await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(course, new PartitionKey(course.code));
                 }

+ 5 - 5
TEAMModelFunction/StuListServiceBus.cs

@@ -89,7 +89,7 @@ namespace TEAMModelFunction
             }
             foreach (MQActivity activity in datas) {
                 //已经完结的不再允许加入
-                if (activity.progress.Equals("finish")) {
+                if (activity.progress.Equals("finish")||activity.progress.Equals("pending")) {
                     continue;
                 }
                 //学生新加入名单的
@@ -163,11 +163,11 @@ namespace TEAMModelFunction
                         id = course.id,
                         scode = course.code,
                         name = course.name,
-                        code = $"Course-{course.school}-{students.id}",
+                        code = $"StuCourse-{course.school}-{students.id}",
                         scope = course.scope,
                         school = course.school,
                         creatorId = course.creatorId,
-                        pk = "Course"
+                        pk = "StuCourse"
                     };
                     await client.GetContainer("TEAMModelOS", "Student").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
                 }
@@ -179,11 +179,11 @@ namespace TEAMModelFunction
                         id = course.id,
                         scode = course.code,
                         name = course.name,
-                        code = $"Course-{tmdid}",
+                        code = $"StuCourse-{tmdid}",
                         scope = course.scope,
                         school = course.school,
                         creatorId = course.creatorId,
-                        pk = "Course"
+                        pk = "StuCourse"
                     };
                     await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stucourse, new PartitionKey(stucourse.code));
                 }

+ 3 - 2
TEAMModelFunction/TriggerStuActivity.cs

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

+ 9 - 45
TEAMModelFunction/TriggerSurvey.cs

@@ -83,45 +83,6 @@ namespace TEAMModelFunction
                         }
                         break;
                     case "going":
-                        //if (survey.scope == "school")
-                        //{
-                        //    data = new ActivityData
-                        //    {
-                        //        id = survey.id,
-                        //        code = $"Activity-{survey.school}",
-                        //        type = "survey",
-                        //        name = survey.name,
-                        //        startTime = survey.startTime,
-                        //        endTime = survey.endTime,
-                        //        scode = survey.code,
-                        //        scope = survey.scope,
-                        //        classes = survey.classes.IsNotEmpty() ? survey.classes : new List<string> { "" },
-                        //        tmdids = survey.tmdids.IsNotEmpty() ? survey.tmdids : new List<string> { "" },
-                        //        progress = "going",
-                        //        subjects = new List<string> { "" }
-                        //    };
-                        //    await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
-                        //}
-                        //else if (survey.scope == "private")
-                        //{
-                        //    data = new ActivityData
-                        //    {
-                        //        id = survey.id,
-                        //        code = $"Activity-Common",
-                        //        type = "survey",
-                        //        name = survey.name,
-                        //        startTime = survey.startTime,
-                        //        endTime = survey.endTime,
-                        //        scode = survey.code,
-                        //        scope = survey.scope,
-                        //        progress = "going",
-                        //        classes = survey.classes.IsNotEmpty() ? survey.classes : new List<string> { "" },
-                        //        tmdids = new List<string> { "" },
-                        //        subjects = new List<string> { "" }
-                        //    };
-                        //    await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
-                        //}
-
                         (List<string> tmdids,List<Students> students) =   await TriggerStuActivity. GetStuList(client, survey.classes, survey.school);
                         await _dingDing.SendBotMsg($"问卷调查{tdata.id}写入学生表作为活动列表!", GroupNames.成都开发測試群組);
                         List<StuActivity> stuActivities = new List<StuActivity>();
@@ -208,12 +169,11 @@ namespace TEAMModelFunction
                             var value = submit.ToString();
                             userids.Add(value);
                         }
-                        var cods = new { records = recs, userids };
-                        //问卷整体情况
-                        await _azureStorage.UploadFileByContainer(blobcntr, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
+
+                        List<QuestionRecord> questionRecords = new List<QuestionRecord>();
                         //结算每道题的答题情况
                         var ContainerClient =  _azureStorage.GetBlobContainerClient(blobcntr);
-                        List<Task<string>> tasks = new List<Task<string>>();
+                        //List<Task<string>> tasks = new List<Task<string>>();
                         //获取
                         try {
                             List<string> items = await ContainerClient.List($"survey/{survey.id}/urecord");
@@ -264,12 +224,16 @@ namespace TEAMModelFunction
                                         }
                                     }
                                 }
-                                tasks.Add(  _azureStorage.UploadFileByContainer(blobcntr, question.ToJsonString(), "survey", url));
+                                questionRecords.Add(question);
+                                //tasks.Add(  _azureStorage.UploadFileByContainer(blobcntr, question.ToJsonString(), "survey", url));
                             }
-                            await Task.WhenAll(tasks);
+                           // await Task.WhenAll(tasks);
                         } catch (Exception ex) {
                             await _dingDing.SendBotMsg($"问卷调查问题结算异常{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
                         }
+                        var cods = new { records = recs, userids, question= questionRecords };
+                        //问卷整体情况
+                        await _azureStorage.UploadFileByContainer(blobcntr, cods.ToJsonString(), "survey", $"{survey.id}/record.json");
                         if (string.IsNullOrEmpty(survey.recordUrl))
                         {
                             survey.recordUrl = $"/survey/{survey.id}/record.json";

+ 1 - 39
TEAMModelFunction/TriggerVote.cs

@@ -86,45 +86,7 @@ namespace TEAMModelFunction
                         }
                         break;
                     case "going":
-                        //if (vote.scope == "school")
-                        //{
-                        //    data = new ActivityData
-                        //    {
-                        //        id = vote.id,
-                        //        code = $"Activity-{vote.school}",
-                        //        type = "vote",
-                        //        name = vote.name,
-                        //        startTime = vote.startTime,
-                        //        endTime = vote.endTime,
-                        //        scode = vote.code,
-                        //        scope = vote.scope,
-                        //        classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
-                        //        tmdids = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string> { "" },
-                        //        progress = "going",
-                        //        subjects = new List<string> { "" }
-                        //    };
-                        //    await client.GetContainer("TEAMModelOS", "School").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
-                        //}
-                        //else if (vote.scope == "private")
-                        //{
-                        //    data = new ActivityData
-                        //    {
-                        //        id = vote.id,
-                        //        code = $"Activity-Common",
-                        //        type = "vote",
-                        //        name = vote.name,
-                        //        startTime = vote.startTime,
-                        //        endTime = vote.endTime,
-                        //        scode = vote.code,
-                        //        scope = vote.scope,
-                        //        progress = "going",
-                        //        classes = vote.classes.IsNotEmpty() ? vote.classes : new List<string> { "" },
-                        //        tmdids = new List<string> { "" },
-                        //        subjects = new List<string> { "" }
-                        //    };
-                        //    await client.GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<ActivityData>(data, new Azure.Cosmos.PartitionKey(data.code));
-                        //}
-
+                        
                         (List<string> tmdids, List<Students> students) = await TriggerStuActivity.GetStuList(client, vote.classes, vote.school);
                         List<string> tmds = vote.tmdids.IsNotEmpty() ? vote.tmdids : new List<string>() ;
                         if (tmdids.IsNotEmpty()) {

+ 5 - 0
TEAMModelOS.SDK/Models/Cosmos/Common/StuCourse.cs

@@ -4,6 +4,11 @@ using System.Text;
 
 namespace TEAMModelOS.SDK.Models.Cosmos.Common
 {
+    /// <summary>
+    /*
+     * 
+     */
+    /// </summary>
     public class StuCourse :CosmosEntity
     {
         /// <summary>

+ 6 - 0
TEAMModelOS.sln

@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelGrpc", "TEAMModelG
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelFunction", "TEAMModelFunction\TEAMModelFunction.csproj", "{78470113-6261-4F9A-9EF3-E315F060813D}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelAPI", "TEAMModelAPI\TEAMModelAPI.csproj", "{DE4FED83-02BE-40B5-9F81-910DCFD00C61}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -33,6 +35,10 @@ Global
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{78470113-6261-4F9A-9EF3-E315F060813D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DE4FED83-02BE-40B5-9F81-910DCFD00C61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DE4FED83-02BE-40B5-9F81-910DCFD00C61}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DE4FED83-02BE-40B5-9F81-910DCFD00C61}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DE4FED83-02BE-40B5-9F81-910DCFD00C61}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 31 - 3
TEAMModelOS/ClientApp/src/api/studentWeb.js

@@ -13,8 +13,8 @@ var mocktime = [];
 var mockStudydata = [];
 var mockStudydata2 = [];
 var mockQASheet = [];
-
-
+var courseList = [];
+var students = [];
 for (var i = 1; i <= 30; i++) {
     var data = Mock.mock({
 
@@ -38,6 +38,34 @@ for (var i = 1; i <= 30; i++) {
 
 
     });
+    for (let p = 1; p <= 38; p++) {
+        let studentsData = Mock.mock({
+            name: Random.cname(),
+            group: Random.integer(1, 5),
+            "isUploadHomework|1": true, //一個是否有交作業的參數,同學互評使用
+            "isGivenComment|1": true, //一個是否有被給評的參數,同學互評使用
+        });
+        students.push(studentsData); //學生名單資料
+    }
+    var courseItem = Mock.mock({
+        "courseType|1": ["表定", "臨時"],
+        courseName: Random.ctitle(12, 20),
+        courseID: Random.id(), //課程代碼
+        courseAddDate: Random.date('2020.01.dd'), //加入課程的日期
+        "courseSubject|1": ["國文", "英文", "數學"],
+        //tab1 基本資料
+        attendTime: "每星期三 " + Random.time("HH:00"), //上課時間
+        classroom: "classroom A" + Random.integer(60, 70), //上課地點
+        teacher: Random.cname(), //授課教師
+        assistantTeachers: [Random.cname(), Random.cname(), Random.cname()], //授課教師
+
+        //tab2 課程概述
+        courseDesc: Random.cparagraph(17, 27), //課程描述
+
+        //tab3 學生名單
+        students: students,
+    });
+    courseList.push(courseItem);
     var data2 = Mock.mock({
 
         "string|1-5": "★",//隨意產生1-10個星星
@@ -139,7 +167,7 @@ export default {
     mockStudydata,
     mockStudydata2,
     mockQASheet,
-
+    courseList,
     //查询学生参与评量数据
     FindExamPaper: function (data) {
         return post('/common/exam/find-all-by-student', data)

+ 1 - 0
TEAMModelOS/ClientApp/src/components/evaluation/OptionsTable.vue

@@ -79,6 +79,7 @@
 					if (Object.keys(n).length) {
 						let total = this.$store.state.totalAnalysis.analysisJson.all.total // 取总人数
 						let phCount = Math.floor(total * 0.27) //取高分组人数
+						console.log(n)
 						this.options.forEach(key => {
 							this.optionsData.push({
 								option: key,

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

@@ -0,0 +1,152 @@
+<template>
+	<div :id="barId" class="myBar"></div>
+</template>
+
+<script>
+	export default {
+		name: 'BaseBar',
+		props: ['barId', 'barData'],
+		data() {
+			return {
+			}
+		},
+		methods: {
+
+			drawLine(data) {
+				let that = this
+				// 基于准备好的dom,初始化echarts实例
+				let myBar = this.$echarts.init(document.getElementById(this.barId), 'chalk')
+				
+				
+
+				let option = {
+					tooltip: {
+						trigger: "item",
+						padding: [4, 12],
+						backgroundColor: "white",
+						textStyle: {
+							color: "black",
+							fontFamily: "Ariel",
+							fontWeight: "bolder",
+						},
+						formatter: function(params) {
+							var curCode = String.fromCharCode(64 + parseInt(params.dataIndex + 1))
+							var students = data.details[curCode] || []
+							var results = ''
+							if(students.length){
+								for (var i = 0; i < students.length; i++) {
+									results += students[i] + '<br>'
+								}
+								return results
+							}else{
+								return that.$t('totalAnalysis.text9')
+							}
+							
+						}
+					},
+					grid: {
+						containLabel: true,
+					},
+					xAxis: {
+						type: "category",
+						data: data.count.map(i => i.code),
+						splitLine: {
+							lineStyle: {
+								color: "transparent",
+							},
+						},
+						//座標軸線的設置
+						axisLine: {
+							show:false,
+							lineStyle: {
+								color: "gray",
+								width: 2,
+							},
+						},
+						//座標軸的刻度顏色
+						axisLabel: {
+							show:false,
+							color: "black",
+						},
+					},
+					yAxis: {
+						type: "value",
+						show: false,
+						axisLine: {
+							show:false,
+							lineStyle: {
+								color: "gray",
+								width: 2,
+							},
+						},
+						//座標軸的刻度顏色
+						axisLabel: {
+							show:false,
+							color: "black",
+						},
+					},
+					emphasis: {
+						itemStyle: {
+							color: "#FA6400", //高亮
+						},
+					},
+					series: [{
+						label: {
+							show: true,
+							position: 'top',
+							fontSize: 10,
+							color: '#3DC3F0',
+							fontWeight: 'bold'
+						},
+						data: data.count.map(item => {
+							return {
+								value:item.value,
+								itemStyle:{
+									color:item.value === Math.max(...data.count.map(i => i.value)) ? 'rgb(31, 218, 59)' : 'rgb(190, 211, 218)'
+								}
+							}
+							
+						}),
+						barWidth:20,
+						type: "bar",
+					}],
+				}
+
+				// 绘制图表
+				myBar.setOption(option)
+
+				window.addEventListener('resize', function() {
+					myBar.resize()
+				})
+			}
+		},
+		mounted() {
+			if (!this.barData.count.length) return
+			console.log('mini接受到的',this.barData)
+			this.drawLine(this.barData)
+		},
+		watch: {
+			barData: {
+				
+				handler(val) {
+					console.log('mini接受到的',val)
+					if(val.count && val.count.length){
+						this.drawLine(val)
+					}
+				},
+				deep: true,
+			}
+		}
+
+	}
+</script>
+
+<!-- Add "scoped" attribute to limit CSS to this component only -->
+<style scoped>
+	.myBar {
+		width: 100%;
+		height: 100%;
+		margin: 0 auto;
+		display: block;
+	}
+</style>

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

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

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

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

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

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

+ 70 - 41
TEAMModelOS/ClientApp/src/components/questionnaire/BaseQuestionnaire.vue

@@ -12,45 +12,52 @@
 			<draggable class="list-group" tag="div" v-model="items" v-bind="dragOptions" @start="drag = true" @end="onDragEnd" v-else>
 				<transition-group type="transition" :name="!drag ? 'flip-list' : null">
 					<div class="qn-item animated fadeInUp" v-for="(item,index) in items" :key="index">
-						<!-- 题干 -->
-						<p class="qn-stem">
-							<span style="color: red;" v-show="item.required">* </span>
-							<span>{{ index + 1 }}. </span>
-							<span v-html="item.question"></span>
-							<span>( {{ typeList[item.type] }} )</span>
-						</p>
-						<!-- 单选题-选项 -->
-						<RadioGroup v-model="radioModel" v-if="item.type === 'single' || item.type === 'judge'">
-							<Radio v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled></Radio>
-						</RadioGroup>
-						<!-- 多选题-选项 -->
-						<CheckboxGroup v-model="multipleModel" v-if="item.type === 'multiple'">
-							<Checkbox v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled>
-							</Checkbox>
-						</CheckboxGroup>
-						<!-- 数据分析 -->
-						<transition name="indexFade">
-						      <div>
-								  <BaseQnBar :barId="'bar' + index" :barData="item.result || []" v-if="curIndexList.includes(index) && item.type !== 'subjective'"></BaseQnBar>
-								  <BaseAnsList v-if="curIndexList.includes(index) && item.type === 'subjective'" :ansList="item.result.details"></BaseAnsList>
-							  </div>
-						</transition>
-						<!-- 工具栏 -->
-						<div class="qn-tools">
-							<div class="qn-tools-item" @click="onItemEdit(item,index)" v-if="editable">
-								<Icon type="md-create" />
-								<span>{{ $t('survey.questionaire.edit') }}</span>
-							</div>
-							<div class="qn-tools-item" @click="onItemDelete(index)"  v-if="editable">
-								<Icon type="md-trash" />
-								<span>{{ $t('survey.questionaire.remove') }}</span>
-							</div>
-							<!-- <div class="qn-tools-item" @click="onItemAnalysis(index)"> -->
-							<div class="qn-tools-item" @click="onItemAnalysis(index,item)" v-if="currentQn.progress === 'finish'">
-								<Icon type="md-podium" />
-								<span>{{ $t('survey.questionaire.analysisData') }}</span>
+						<div class="qn-item-content">
+							<!-- 题干 -->
+							<p class="qn-stem">
+								<span style="color: red;" v-show="item.required">* </span>
+								<span>{{ index + 1 }}. </span>
+								<span v-html="item.question"></span>
+								<span>( {{ typeList[item.type] }} )</span>
+							</p>
+							<!-- 单选题-选项 -->
+							<RadioGroup v-model="radioModel" v-if="item.type === 'single' || item.type === 'judge'">
+								<Radio v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled></Radio>
+							</RadioGroup>
+							<!-- 多选题-选项 -->
+							<CheckboxGroup v-model="multipleModel" v-if="item.type === 'multiple'">
+								<Checkbox v-for="(option,optionIndex) in item.option" :key="optionIndex" :label="getSimpleText(option.value)" disabled>
+								</Checkbox>
+							</CheckboxGroup>
+							
+							
+							<!-- 数据分析 -->
+							<transition name="indexFade">
+							      <div>
+									  <!-- <BaseQnBar :barId="'bar' + index" :barData="item.result || []" v-if="curIndexList.includes(index) && item.type !== 'subjective'"></BaseQnBar> -->
+									  <BaseAnsList v-if="curIndexList.includes(index) && item.type === 'subjective'" :ansList="item.result.details"></BaseAnsList>
+								  </div>
+							</transition>
+							<!-- 工具栏 -->
+							<div class="qn-tools">
+								<div class="qn-tools-item" @click="onItemEdit(item,index)" v-if="editable">
+									<Icon type="md-create" />
+									<span>{{ $t('survey.questionaire.edit') }}</span>
+								</div>
+								<div class="qn-tools-item" @click="onItemDelete(index)"  v-if="editable">
+									<Icon type="md-trash" />
+									<span>{{ $t('survey.questionaire.remove') }}</span>
+								</div>
+								<!-- <div class="qn-tools-item" @click="onItemAnalysis(index)"> -->
+								<div class="qn-tools-item" @click="onItemAnalysis(index,item)" v-if="currentQn.progress === 'finish' && item.type === 'subjective'">
+									<Icon type="md-podium" />
+									<span>{{ $t('survey.questionaire.analysisData') }}</span>
+								</div>
 							</div>
 						</div>
+						<div class="qn-item-charts" v-if="currentQn.progress === 'finish' && item.type !== 'subjective'">
+							<BaseMiniBar :barId="'minibar' + index" :barData="item.result || []"></BaseMiniBar>
+						</div>
 					</div>
 				</transition-group>
 			</draggable>
@@ -79,12 +86,14 @@
 	import BaseJudge from "./BaseJudge.vue"
 	import BaseSubjective from "./BaseSubjective.vue"
 	import BaseQnBar from "./BaseQnBar.vue"
+	import BaseMiniBar from "./BaseMiniBar.vue"
 	import BaseAnsList from "@/components/questionnaire/BaseAnsList.vue";
 	
 	export default {
 		components: {
 			draggable,
 			BaseQnBar,
+			BaseMiniBar,
 			BaseSingle,
 			BaseMultiple,
 			BaseJudge,
@@ -305,11 +314,30 @@
 					item.option.forEach((opt,optIndex) => {
 						obj.key = opt.code,
 						obj.code = this.getSimpleText(opt.value);
-						obj.value = this.getSelectNum(result, index, opt.code);
+						obj.value = this.getSelectNum(result.records, index, opt.code);
 						resultArr.push(obj);
 						obj = {};
 					});
 					item.result.count = resultArr;
+					let curItemRecord = result.question[index]
+					if(item.type === 'subjective'){
+						let result = []
+						for(let key in curItemRecord.other){
+							result.push({
+								id:key,
+								name:this.students.filter(i => i.id === key)[0].name,
+								value:curItemRecord.other[key]
+								
+							})
+						}
+						item.result.details = result
+					}else{
+						console.log(this.students)
+						for(let key in curItemRecord.opt){
+							curItemRecord.opt[key] = curItemRecord.opt[key].map(id => this.students.filter(i => i.id === id)[0].name) 
+						}
+						item.result.details = curItemRecord.opt
+					}
 				});
 				this.items = items
 			},
@@ -338,7 +366,7 @@
 					if(item.progress === 'finish' && item.recordUrl){
 						try{
 							let finishRecord = await this.getBlobJsonFile(item.scope,item.recordUrl)
-							r(finishRecord.records)
+							r(finishRecord)
 						}catch(e){
 							j(e)
 						}
@@ -349,8 +377,8 @@
 								code: item.code
 							})
 							.then((res) => {
-								if (!res.error && res.records) {
-									r(res.records);
+								if (!res.error) {
+									r(res);
 								} else {
 									j(500);
 								}
@@ -386,6 +414,7 @@
 								let items = await this.getBlobItems(newValue)
 								this.makeItemResult(records,items)
 							}catch(e){
+								console.log(e)
 								this.$Message.error(this.$t('survey.getFileFailTip'))
 							}
 							

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

@@ -9,13 +9,13 @@
             <div v-if="this.$store.getters.getItemTitle.eventType=='homeWork'">
               <Homework/>
             </div>-->
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'exam'">
+            <div v-if="this.$store.getters.getItemTitle.eventType == 'Exam'">
                 <PaperView />
             </div>
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'vote'">
+            <div v-if="this.$store.getters.getItemTitle.eventType == 'Vote'">
                 <Vote />
             </div>
-            <div v-if="this.$store.getters.getItemTitle.eventType == 'survey'">
+            <div v-if="this.$store.getters.getItemTitle.eventType == 'Survey'">
                 <QuesNaire />
             </div>
         </div>

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

@@ -335,6 +335,7 @@
                     this.Message.warning(this.$t('studentWeb.exam.report.pdfErr'))
                 })
             },
+            //获取文件授权
             async getFileSas(data) {
                 if (data) {
                     let req = {
@@ -347,6 +348,7 @@
                     return curFile
                 }
             },
+            //下载补救文件资源
             async downloadFile(data) {
                 let blobData = await this.getFileSas(data)
                 const downloadRes = async () => {
@@ -419,7 +421,8 @@
                     }
                 }
             },
-            async getItem(data) { //获取学生作答数据
+            //获取学生作答数据
+            async getItem(data) {
                 let datas = []
                 if (data !== undefined) {
                     let codes = this.$store.getters.getItemTitle
@@ -436,7 +439,8 @@
                     return []
                 }
             },
-            formUrl(data) {  //处理学生作答数据blob地址
+            //处理学生作答数据blob地址
+            formUrl(data) { 
                 let container = data.code
                 let a = ""
                 if (data.blob.indexOf('https://teammodelstorage') > -1) {
@@ -481,6 +485,10 @@
                if (this.paperData.length) {
                    this.ansData = await this.getItem(this.examInfo.stuAns[0])
                }
+               console.log('5456465456456')
+               console.log(this.paperData)
+               console.log(this.ansData)
+               console.log(this.examInfo)
             },
             closeDetail() {
                 this.closeAnsDetail = !this.closeAnsDetail;

+ 5 - 0
TEAMModelOS/ClientApp/src/components/student-web/EventView/EventContentTypeTemplate/QuesNaire.vue

@@ -239,12 +239,17 @@
 								})
 								this.$forceUpdate()
 							}
+						}).catch(err => {
+							console.log(err)
 						})
 					}else{
 						this.alreadyAnswered = true
 					}
 					
 				}
+				
+				console.log(this.alreadyAnswered)
+				console.log(this.surveyInfo)
 			},
 
 			// 获取blob里的试题数据

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

@@ -75,14 +75,14 @@
                     :key="index">
                     <ul>
                         <li class="list-item-icon">
-                            <svg-icon v-if="item.eventType == 'homeWork'" icon-class="doc" />
-                            <svg-icon v-if="item.eventType == 'preview'"  icon-class="selflearninginTime" />
-                            <svg-icon v-if="item.eventType == 'exam'"     icon-class="multiTest" />
-                            <svg-icon v-if="item.eventType == 'vote'"     icon-class="vote" />
-                            <svg-icon v-if="item.eventType == 'survey'"   icon-class="quesnaire" />
+                            <svg-icon v-if="item.eventType == 'HomeWork'" icon-class="doc" />
+                            <svg-icon v-if="item.eventType == 'Preview'"  icon-class="selflearninginTime" />
+                            <svg-icon v-if="item.eventType == 'Exam'"     icon-class="multiTest" />
+                            <svg-icon v-if="item.eventType == 'Vote'"     icon-class="vote" />
+                            <svg-icon v-if="item.eventType == 'Survey'"   icon-class="quesnaire" />
                         </li>
                         <li class="list-item-info"
-                            v-if="item.eventType == 'exam'">
+                            v-if="item.eventType == 'Exam'">
                             <p class="list-item-title">
                                 <span class="list-item-typeMark">{{item.scope == 'school' ? $t('studentWeb.public.schoolExam'):$t('studentWeb.public.privateExam')}}</span>
                                 <span>{{ item.name }}</span>
@@ -92,7 +92,7 @@
                             </p>
                         </li>             
                         <li class="list-item-info"
-                            v-if="item.eventType == 'vote'">
+                            v-if="item.eventType == 'Vote'">
                             <p class="list-item-title">
                                 <span class="list-item-typeMark">{{item.scope == 'school' ? $t('studentWeb.public.schoolVote'):$t('studentWeb.public.privateVote')}}</span>
                                 <span>{{ item.name }}</span>
@@ -102,7 +102,7 @@
                             </p>
                         </li>       
                         <li class="list-item-info"
-                            v-if="item.eventType == 'survey'">
+                            v-if="item.eventType == 'Survey'">
                             <p class="list-item-title">
                                 <span class="list-item-typeMark">{{item.scope == 'school' ? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span>
                                 <span>{{ item.name }}</span>
@@ -149,29 +149,29 @@
                 havejustfinishedItem: false, //無剛完成的數據情況,清單項目變動將會影響空白狀態之呈現
                 typeNametoIcon: [
                     {
-                        eventType: "preview",
+                        eventType: "Hreview",
                         iconClass: "selflearninginTime",
                     },
                     {
-                        eventType: "exam",
+                        eventType: "Exam",
                         iconClass: "test",
                     },
                     {
-                        eventType: "homeWork",
+                        eventType: "HomeWork",
                         iconClass: "doc",
                     },
                     {
-                        eventType: "vote",
+                        eventType: "Vote",
                         iconClass: "vote",
                     },
                     {
-                        eventType: "survey",
+                        eventType: "Survey",
                         iconClass: "quesnaire",
                     },
                 ],
                 activityType: this.$t('studentWeb.state'),
                 mockdata: "",
-                eventPageType: ["preview", "exam", "homeWork", "vote", "survey"], //本頁出現的類型
+                eventPageType: ["Preview", "Exam", "HomeWork", "Vote", "Survey"], //本頁出現的類型
                 openSearch: false, //打開搜尋器
                 search: "",
                 alreadyScrolltimes: 0,

+ 3 - 7
TEAMModelOS/ClientApp/src/components/student-web/HomeView/CourseList.vue

@@ -291,8 +291,6 @@
 </template>
 
 <script>
-import Mockdata from "@/api/newData";
-import MockdataEn from "@/api/newDataEn";
 export default {
   name: "CourseList",
   data() {
@@ -303,10 +301,7 @@ export default {
         localStorage.getItem("lang") == "tw"
           ? ["時間", "一", "二", "三", "四", "五"]
           : ["time", "Mon", "Tue", "Wed", "Thu", "Fri"],
-      courseList:
-        localStorage.getItem("lang") == "tw"
-          ? Mockdata.courseList
-          : MockdataEn.courseList,
+        courseList: this.$api.studentWeb.courseList
     };
   },
   created() {
@@ -319,7 +314,8 @@ export default {
       this.currentView=type
     },
     sentFirstItemActive() {
-      let tempArr = [];
+        let tempArr = [];
+        console.log(this.$api.studentWeb.courseList)
       for (let i = 0; i < this.courseList.length; i++) {
         if (this.courseList[i].courseType != "臨時") {
           tempArr.push(this.courseList[i]);

+ 13 - 18
TEAMModelOS/ClientApp/src/components/student-web/HomeView/HomeView.vue

@@ -48,8 +48,7 @@
                                         </li>
                                         <li class="list-item-info">
                                             <p class="list-item-title"
-                                               :class="{ 'list-item-titleEn': getCurrentLang() == 'en', }"
-                                               >
+                                               :class="{ 'list-item-titleEn': getCurrentLang() == 'en', }">
                                                 <span class="list-item-typeMark">{{ item.eventType }}</span>
                                                 <span>{{ item.eventName }}</span>
                                             </p>
@@ -60,25 +59,23 @@
                                         <li class="list-item-unDone"></li>
                                     </ul>
                                     <!--<router-link :to="`/studentWeb/eventView#${item.eventID}`">
-                                    </router-link>-->
+                        </router-link>-->
                                 </li>
                             </div>
                         </div>
                     </div>
                 </Card>
                 <br />
-                <!--<router-link to="/courseList">
-                </router-link>-->
-                <Card style="overflow: hidden" @click.native="noData">
-                    <h3 style="color: #575757; font-weight: 700">
-                        <svg-icon class="titleIcon" icon-class="course" />
-                        {{ $t("studentWeb.coursesCardTitle") }}
-                        <Icon type="ios-arrow-forward" />
-                    </h3>
-
-                    <p class="course-new">{{ $t("studentWeb.newAddCourse") }}</p>
-                </Card>
-
+                <router-link to="/studentWeb/courseList">
+                    <Card style="overflow: hidden">
+                        <h3 style="color: #575757; font-weight: 700">
+                            <svg-icon class="titleIcon" icon-class="course" />
+                            {{ $t("studentWeb.coursesCardTitle") }}
+                            <Icon type="ios-arrow-forward" />
+                        </h3>
+                        <p class="course-new">{{ $t("studentWeb.newAddCourse") }}</p>
+                    </Card>
+                </router-link>
                 <br />
             </i-col>
             <i-col :xs="24" :sm="24" :md="12" :lg="8">
@@ -239,9 +236,7 @@
                         "eventType": "問卷"
                     }
                 ],
-                MyEventData: parseFloat(
-                    this.$store.getters.getCountedIsDonePercent
-                ).toFixed(0),
+                MyEventData: parseFloat(this.$store.getters.getCountedIsDonePercent).toFixed(0),
                 spanCharts: false,
                 todaydaylineListHeight: 0,
             };

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

@@ -16,20 +16,20 @@
                     v-for="(item, index) in testData" :key="index">
                     <ul>
                         <li class="list-item-icon">
-                            <svg-icon v-if="item.eventType == 'homework'" icon-class="doc" />
-                            <svg-icon v-if="item.eventType == 'preview'"
+                            <svg-icon v-if="item.eventType == 'Homework'" icon-class="doc" />
+                            <svg-icon v-if="item.eventType == 'Learn'"
                                       icon-class="selflearninginTime" />
                             <svg-icon v-if="  item.eventType == 'exam'"
                                       icon-class="test"
                                       class="reset-testIcon" />
-                            <svg-icon v-if="item.eventType == 'vote'" icon-class="vote" />
-                            <svg-icon v-if="item.eventType == 'survey'" icon-class="quesnaire" />
+                            <svg-icon v-if="item.eventType == 'Vote'" icon-class="vote" />
+                            <svg-icon v-if="item.eventType == 'Survey'" icon-class="quesnaire" />
                         </li>
                         <li class="list-item-info">
                             <p class="list-item-title">
-                                <span v-show="item.eventType == 'exam'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolExam'):$t('studentWeb.public.privateExam')}}</span>
-                                <span v-show="item.eventType == 'vote'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolVote'):$t('studentWeb.public.privateVote')}}</span>
-                                <span v-show="item.eventType == 'survey'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span>
+                                <span v-show="item.eventType == 'Exam'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolExam'):$t('studentWeb.public.privateExam')}}</span>
+                                <span v-show="item.eventType == 'Vote'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolVote'):$t('studentWeb.public.privateVote')}}</span>
+                                <span v-show="item.eventType == 'Survey'" class="list-item-typeMark">{{item.scope == 'school'? $t('studentWeb.public.schoolSurvey'):$t('studentWeb.public.privateSurvey')}}</span>
                                 <span>{{ item.name }}</span>
                                 <div style="float:right;margin-top:-20px">
                                     <div class="list-item-unDone" v-show="item.progress == 'going'">

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

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

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

@@ -67,6 +67,11 @@ export default {
   saveErr: '保存失败!',
   saveWarning: '保存提醒',
   leaveText: '离开',
+  pdWarning: '學段名稱不能重複',
+  semWarning: '學期名稱不能重複',
+  gdNameWarning: '年級名稱不能重複',
+  subWarning: '學科名稱不能重複',
+  exWarning:'考試名稱不能重複',
 
   // ClassroomSetting.vue
   classroomList: '教室列表',

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

@@ -67,6 +67,11 @@ export default {
   saveErr: '保存失败!',
   saveWarning: '保存提醒',
   leaveText: '离开',
+  pdWarning:'学段名称不能重复',
+  semWarning:'学期名称不能重复',
+  gdNameWarning:'年级名称不能重复',
+  subWarning:'学科名称不能重复',
+  exWarning:'考试名称不能重复',
 
   // ClassroomSetting.vue
   classroomList: '教室列表',

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

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

+ 8 - 3
TEAMModelOS/ClientApp/src/locale/lang/zh-TW/schoolBaseInfo.js

@@ -67,6 +67,11 @@ export default {
   saveErr: '保存失敗!',
   saveWarning: '保存提醒',
   leaveText: '離開',
+  pdWarning: '學段名稱不能重複',
+  semWarning: '學期名稱不能重複',
+  gdNameWarning: '年級名稱不能重複',
+  subWarning: '學科名稱不能重複',
+  exWarning:'考試名稱不能重複',
 
   //ClassroomSetting.vue
   classroomList: '教室清單',
@@ -160,8 +165,8 @@ export default {
   removeErr: '移除失敗',
   deLink: '解除關聯',
   link: '關聯',
-  confirmDelink:'請問您確定要解除關聯',
+  confirmDelink: '請問您確定要解除關聯',
   noStu: '暫無學生',
-  addOk:'添加成功',
-  addErr:'添加失敗'
+  addOk: '添加成功',
+  addErr: '添加失敗'
 }

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

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

+ 1 - 0
TEAMModelOS/ClientApp/src/utils/evTools.js

@@ -450,6 +450,7 @@ export default {
 			try {
 				let jsonInfo = await $tools.getFile(paper.blob + sasString.sas)
 				let jsonData = JSON.parse(jsonInfo)
+				console.log(jsonData)
 				// 获取试卷包含的试题数据并包装好
 				if (jsonData.length) {
 					r(jsonData)

+ 4 - 4
TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.less

@@ -2,8 +2,8 @@
 @second-bgColor: #1b1b1b;
 @third-bgColor: #222222;
 @borderColor: #424242;
-@primary-textColor: #fff; //文本主颜
-@second-textColor: #a5a5a5; //文本副级颜
+@primary-textColor: #fff; //锟侥憋拷锟斤拷锟斤拷
+@second-textColor: #a5a5a5; //锟侥憋拷锟斤拷锟斤拷锟斤拷
 @primary-fontSize: 14px;
 @second-fontSize: 16px;
 
@@ -128,8 +128,8 @@
 
     &:hover {
         background: rgba(28,192,243,1);
-        transform: translateY(-2px);
-        transition: all .2s ease 0s;
+        // transform: translateY(-2px);
+        // transition: all .2s ease 0s;
     }
 }
 .list-group {

+ 39 - 18
TEAMModelOS/ClientApp/src/view/classmgt/ManageClass.vue

@@ -1,5 +1,6 @@
 <template>
     <div class="mgt-class-container dark-iview-select dark-iview-checkbox custom-scroll-bar common-save-btn" @click="nameEdStatus = true">
+        <!-- 头部 -->
         <div class="mgt-class-header">
             <span class="text-label">{{$t('cusMgt.classLabel')}}</span>
             <Select v-model="curClassCode" style="width:200px">
@@ -24,6 +25,7 @@
                 {{viewType ? $t('cusMgt.viewport1'):$t('cusMgt.viewport2') }}
             </span>
         </div>
+        <!-- 表格模式 -->
         <div class="mgt-class-body dark-iview-table animated fadeIn" id="table-wrap" v-if="viewType == 1">
             <vuescroll>
                 <Table :columns="columns" v-if="classList[curClassIndex]" :data="classList[curClassIndex].students" :loading="tableLoading" ref="students" :height="tableHeight" :no-data-text="$t('cusMgt.noStu')">
@@ -46,11 +48,12 @@
                 <EmptyData v-else :textContent="$t('cusMgt.noMgtClass')" :top="150"></EmptyData>
             </vuescroll>
         </div>
+        <!-- 分组模式 -->
         <div class="mgt-class-body dark-iview-table animated fadeIn dark-iview-input disabled-iview-input" id="table-wrap" v-else>
             <vuescroll>
                 <div class="group-wrap-item" v-for="(item,index) in groupData" :key="index">
                     <div class="group-title-wrap">
-                        <span class="group-num-tag">{{parseInt(item.groupId)}}</span>
+                        <span class="group-num-tag">{{item.groupId ? parseInt(item.groupId) : 1}}</span>
                         <Input v-model="item.groupName" class="group-name-tag" :placeholder="$t('cusMgt.groupNameHolder')" :disabled="nameEdStatus" @click.native.stop="nameEdStatus = false" :title="$t('cusMgt.edtiGroupName')" @on-change="$jsFn.debounce(setGroupName,1000)(index)" />
                         <Icon type="md-close" class="close-group-icon" @click="delGroup(index)" />
                     </div>
@@ -69,6 +72,7 @@
                 </div>
             </vuescroll>
         </div>
+        <!-- 分组设置 -->
         <Modal v-model="customGroupStatus" :title="$t('cusMgt.autoGroup')" @on-ok="comfirmCustomRules" class="custom-group" class-name="dark-iview-modal dark-iview-form">
             <Form :label-width="80" :label-colon="true" style="color:white;">
                 <FormItem :label="$t('cusMgt.studentCountLabel')">
@@ -196,11 +200,11 @@ export default {
             if (row != -1) {
                 this.$Modal.confirm({
                     title: this.$t('cusMgt.resetPw'),
-                    content: '<p>' + this.$t('cusMgt.resetPwContent1') + " <strong style='color:red;'>" + row.name + '</strong>'+ this.$t('cusMgt.resetPwContent1') +'?</p>',
+                    content: '<p>' + this.$t('cusMgt.resetPwContent1') + " <strong style='color:red;'>" + row.name + '</strong>' + this.$t('cusMgt.resetPwContent1') + '?</p>',
                     onOk: () => {
                         let ids = []
                         row.pw = row.id
-                        row.year = row.year ? row.year.toString() :''
+                        row.year = row.year ? row.year.toString() : ''
                         delete row.no
                         ids.push(row)
                         this.tableLoading = true
@@ -221,13 +225,13 @@ export default {
                 if (this.selections.length > 0) {
                     this.$Modal.confirm({
                         title: this.$t('cusMgt.resetPw'),
-                        content: '<p>' + this.$t('cusMgt.resetPwContent3') + " <strong style='color:red;'>" + this.selections.length + '</strong>'+ this.$t('cusMgt.resetPwContent4') +'</p>',
+                        content: '<p>' + this.$t('cusMgt.resetPwContent3') + " <strong style='color:red;'>" + this.selections.length + '</strong>' + this.$t('cusMgt.resetPwContent4') + '</p>',
                         onOk: () => {
                             this.tableLoading = true
-                            let apiData = this.selections.map( (item) =>{
+                            let apiData = this.selections.map((item) => {
                                 let d = item
                                 d.pw = d.id
-                                delete d.no                                
+                                delete d.no
                                 return d
                             })
 
@@ -335,8 +339,26 @@ export default {
         },
         saveGroup() {
             this.tableLoading = true
+            // this.$api.schoolSetting.upsertGroup({
+            //     classroom: this.classList[this.curClassIndex]
+            // }).then(
+            //     (res) => {
+            //         if (!res.error) {
+            //             this.$Message.success(this.$t('cusMgt.saveOk'))
+            //         } else {
+            //             this.$Message.error('API error!')
+            //         }
+            //     },
+            //     (err) => {
+            //         this.$Message.error('API error!')
+            //     }
+            // ).finally(() => {
+            //     setTimeout(() => {
+            //         this.tableLoading = false
+            //     }, 500)
+            // })
             this.$api.schoolSetting.upsertGroup({
-                classroom: this.classList[this.curClassIndex]
+                students: this.classList[this.curClassIndex].students
             }).then(
                 (res) => {
                     if (!res.error) {
@@ -353,12 +375,11 @@ export default {
                     this.tableLoading = false
                 }, 500)
             })
-
         },
         comfirmCustomRules() {
             if (this.groupNum === 0) {
                 this.$Message.warning(this.$t('cusMgt.groupCount'))
-            } else if (this.groupType == 0) {
+            } else if (!this.groupType) {
                 this.$Message.warning(this.$t('cusMgt.groupTypeTips'))
             } else {
                 switch (this.groupType) {
@@ -379,6 +400,7 @@ export default {
                 this.handelGroup()
             }
         },
+        // 依座顺序S形分组
         orderGroupS() {
             let stuLen = this.classList[this.curClassIndex].students.length
             let surplus = stuLen % this.groupNum// 余数
@@ -386,21 +408,19 @@ export default {
             this.classList[this.curClassIndex].students = this.classList[this.curClassIndex].students.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 < stuLen) {
-                        this.$set(this.classList[this.curClassIndex].students[startIndex + j], 'groupId', i + 1)
-                        this.$set(this.classList[this.curClassIndex].students[startIndex + j], 'groupName', (i + 1) + this.$t('cusMgt.groupUnit'))
-                    } else {
-                        break
-                    }
+            for (let i = 0; i < this.groupNum; i++) {
+                let num = surplus == 0 ? maxCount : i < surplus ? maxCount : maxCount - 1 //每组实际人数
+                for (let j = 0; j < num; j++) {
+                    let startIndex = i + (j * this.groupNum)
+                    this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupId', (i + 1)+'')
+                    this.$set(this.classList[this.curClassIndex].students[startIndex], 'groupName', (i + 1) + this.$t('cusMgt.groupUnit'))
                 }
             }
             setTimeout(() => {
                 this.tableLoading = false
             }, 500)
         },
+        // 依座号分组
         orderGroup() {
             let stuLen = this.classList[this.curClassIndex].students.length
             let surplus = stuLen % this.groupNum// 余数
@@ -429,6 +449,7 @@ export default {
                 this.tableLoading = false
             }, 500)
         },
+        // 随机分组
         randomGroup() {
             let stuLen = this.classList[this.curClassIndex].students.length
             let surplus = stuLen % this.groupNum// 余数

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

@@ -297,13 +297,15 @@
 				var regex = /(\<math.*?<\/math\>)/g;
 				var html = res.html
 				var arr = html.match(regex);
-				// 对所有的mathml进行转换成svg操作
-				arr.forEach(math => {
-					let svgHtml = window.MathJax.mathml2svg(math, { em: 12, ex: 6 })
-					var regex2 = /\<svg .*\>.*\<\/svg\>/;
-					var arr2 = svgHtml.outerHTML.match(regex2);
-					html = html.replace(math, `<span>&nbsp;</span>${arr2[0]}<span>&nbsp;</span>`)
-				})
+				if(arr.length){
+					// 对所有的mathml进行转换成svg操作
+					arr.forEach(math => {
+						let svgHtml = window.MathJax.mathml2svg(math, { em: 12, ex: 6 })
+						var regex2 = /\<svg .*\>.*\<\/svg\>/;
+						var arr2 = svgHtml.outerHTML.match(regex2);
+						html = html.replace(math, `<span>&nbsp;</span>${arr2[0]}<span>&nbsp;</span>`)
+					})
+				}
 				// 解析成题目列表
 				this.$api.SaveAnalyzeHtml({ html : html }).then(response => {
 					if(response.tests.length && !response.emferror.length){

+ 6 - 4
TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue

@@ -639,8 +639,9 @@
 									if (isContainerFull) {
 										this.$Message.warning(this.$t('evaluation.paperList.noSpaceTip'))
 									} else {
-										let saveArr = this.viewModel === 'type' ? arr : list
-										this.doSavePaper(saveArr)
+										// 只按照默认顺序保存
+										// let saveArr = this.viewModel === 'type' ? arr : list
+										this.doSavePaper(list)
 									}
 								} else {
 									this.$Message.warning(this.$t('evaluation.paperList.noItemTip'))
@@ -663,8 +664,9 @@
 											if (isContainerFull) {
 												this.$Message.warning(this.$t('evaluation.paperList.noSpaceTip'))
 											} else {
-												let saveArr = this.viewModel === 'type' ? arr : list
-												this.doSavePaper(saveArr)
+												// 只按照默认顺序保存
+												// let saveArr = this.viewModel === 'type' ? arr : list
+												this.doSavePaper(list)
 											}
 										})
 									},

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

@@ -268,7 +268,7 @@
 				this.viewModel = this.viewModel === 'type' ? 'list' : 'type'
 				this.$refs.exList.viewModel = this.viewModel
 				this.$refs.exList.collapseList = []
-				this.$refs.exList.doRenderMathJax()
+				// this.$refs.exList.doRenderMathJax()
 				this.$emit('onViewModelChange',this.viewModel)
 			},
 

+ 11 - 9
TEAMModelOS/ClientApp/src/view/knowledge-point/index/Index.vue

@@ -357,7 +357,7 @@ import { json } from 'd3'
 
 			// 获取当前册别数量(每次都获取最新的数据)
 			initBlockCount() {
-				this.setCount = false
+				
 				let params = {}
 					for (let data of this.subjectList) {
                         params[this.$store.state.userInfo.schoolCode + "-" + data.id] = this.periodList[this.currentPeriodIndex].id
@@ -365,7 +365,7 @@ import { json } from 'd3'
 					this.$api.syllabus.FindBlockCount(params).then(res => {
 						if (res.datas.length) {
 							this.$nextTick(() => {
-								this.setCount = true  //开始监听数据
+								
 								this.blockCounts = res.datas
                                 this.schoolBlockCount = res.datas.map(i => i.countBlock)
 								this.privateBlockCount = res.datas.map(i => i.countBlock)
@@ -375,12 +375,13 @@ import { json } from 'd3'
 			},
 
 			// 根据学科获取所有知识块信息
-			getBlocksData() {
-                let that = this
+			async getBlocksData() {
+				let that = this
+                that.setCount = false
                 that.pointDatas = []
                 let params = JSON.parse(JSON.stringify(this.currentParams))
                 params.type = 0
-				this.$api.knowledge.GetSchoolPoints(params).then(res => {
+				await this.$api.knowledge.GetSchoolPoints(params).then(res => {
                     if (res.length > 0) {
                         that.pointDatas = res
                         let list = res[0].blocks
@@ -406,11 +407,12 @@ import { json } from 'd3'
                         let list = params[0].blocks
                         this.blockList = list
                         this.originBlockList = JSON.parse(JSON.stringify(list))
-                    } 
+					}
 				}).catch(err => {
                     this.$Message.error(this.$t('knowledge.warn'))
 					this.isLoadBlocks = false
 				})
+                that.setCount = true  //开始监听数据
 			},
 
 			// 根据学科获取学科下所有知识点数据
@@ -813,21 +815,21 @@ import { json } from 'd3'
 		},
 		watch: {
             originBlockList: {
-				handler(newValue, oldValue) {
+				handler() {
 					if (this.setCount) {
 						this.updated = true
                     }
                 }
 			},
             originPointList: {
-				handler(newValue, oldValue) {
+				handler() {
 					if (this.setCount) {
 						this.updated = true
                     }
                 }
             },
 		},
-        beforeRouteLeave(to, from, next) {
+		beforeRouteLeave(to, from, next) {
             if (this.updated) {
                 let config = {
                     title: this.$t('schoolBaseInfo.saveWarning'),

+ 0 - 281
TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/Index.less

@@ -1,281 +0,0 @@
-@main-bgColor:rgb(43,43,46); //主背景颜色
-@borderColor: #444444;
-@primary-textColor:#e0e0e0; //文本主颜色
-@second-textColor:#a5a5a5; //文本副级颜色
-@primary-fontSize:16px;
-@second-fontSize:14px;
-@title-fontSize:18px;
-
-.new-syllabus {
-
-
-    &-container {
-        height: 100%;
-        background: @main-bgColor;
-    }
-
-    &-header {
-        height: 60px;
-        border-bottom: 1px solid @borderColor;
-        // box-shadow: 0px 4px 9px 0px #010101;
-        .fl-row-center;
-        justify-content: space-between;
-        padding: 0 20px;
-        z-index: 1;
-
-
-        span {
-            margin-right: 10px;
-            color: @second-textColor;
-            border-bottom: 2px solid transparent;
-            font-size: @second-fontSize;
-            font-weight: bold;
-            padding: 5px 0;
-            cursor: pointer;
-        }
-
-        .tab-active {
-            border-color: @primary-textColor;
-            color: @primary-textColor;
-            font-size: @primary-fontSize;
-        }
-    }
-
-    &-content {
-        height: calc(100% - 70px);
-        width: 100%;
-        .fl-row-center;
-		
-		.drag-active{
-			 background-color: rgba(149, 149, 149, 0.2);
-		}
-		
-		.gl-new-area{
-			text-align: center;
-			color:@primary-textColor;
-			background: #3e3e3e;
-			padding: 35px 0 !important;
-		}
-
-        .ns-col {
-            position: relative;
-            height: 100%;
-            overflow: hidden;
-            border-right: 1px solid @borderColor;
-
-
-
-            .ns-header {
-                padding: 0 15px;
-                height: 50px;
-                font-size: @primary-fontSize;
-                font-weight: bold;
-                color: @primary-textColor;
-                border-bottom: 1px solid #353535;
-
-                &-content {
-                    height: 50px;
-                    .fl-row-center;
-                    justify-content: space-between;
-                }
-            }
-
-
-            .gl {
-                width: 100%;
-                height: 100%;
-                // padding: 0 0 0 10px;
-                overflow: hidden;
-                padding-bottom: 50px;
-
-
-                &-item {
-                    position: relative;
-                    width: 100%;
-                    padding: 20px 25px;
-                    border-bottom: 1px solid @borderColor;
-                    cursor: pointer;
-
-
-                    &:hover {
-                        .item-active;
-                    }
-
-                    &-name {
-                        font-size: @title-fontSize;
-                        color: @primary-textColor;
-                        font-weight: bold;
-                    }
-
-                    &-info {
-                        padding: 1px 0;
-                        font-size: @second-fontSize;
-                        color: @second-textColor;
-
-                        span {
-                            display: inline-block;
-                            width: 3px;
-                            height: 10px;
-                            margin-right: 5px;
-                            background: @second-textColor;
-                        }
-                    }
-                }
-            }
-
-            .vl {
-                .gl-item {
-                    padding: 20px 15px
-                }
-
-                .gl-item-name {
-                    width: 70%;
-                    overflow: hidden;
-                    text-overflow: ellipsis;
-                    white-space: nowrap;
-					pointer-events: none;
-                }
-
-                .gl-item-info {
-					pointer-events: none;
-                    span {
-                        margin-top: 15px
-                    }
-                }
-
-                .gl-item:hover {
-                    .btn-delete, .btn-edit {
-                        display: unset;
-                    }
-                }
-
-                .btn-delete {
-                    position: absolute;
-                    right: 30px;
-                    top: 44px;
-                    display: none;
-                }
-
-                .btn-edit {
-                    position: absolute;
-                    right: 60px;
-                    top: 44px;
-                    display: none;
-                }
-            }
-        }
-
-        .ns-col {
-            width: 15%;
-            // box-shadow: 6px 6px 9px 0px #000000;
-            z-index: 2;
-            // background: #171717;
-            user-select: none;
-        }
-
-        .ns-col2 {
-            width: 19%;
-            // background: #202020;
-            // box-shadow: 6px 6px 9px 0px #000000;
-            z-index: 1;
-
-            .funnel-box {
-                .fl-col-center;
-                align-items: flex-start;
-                padding-bottom: 10px;
-
-                p {
-                    margin: 10px 5px;
-                }
-            }
-        }
-
-        .ns-col3 {
-            width: 66%;
-            background: #2c2c2cd6;
-
-
-            .btn-compose-block {
-                background: #0f9272;
-                border: none;
-                color: #fff;
-                margin-left:20px;
-            }
-
-            .points-wrap {
-                display: flex;
-                flex-wrap: wrap;
-                padding-top: 20px;
-
-                .point-item {
-					position:relative;
-                    margin: 10px;
-                    padding: 5px 30px;
-                    border-radius: 50px;
-                    background: #545454;
-                    box-shadow: 1px 4px 0px 0px #000000;
-                    cursor: pointer;
-
-                    &-tools {
-                        margin-left: 10px;
-                        // display: none;
-
-                        .btn-delete {
-                            margin-left: 4px;
-                        }
-                    }
-                }
-
-                .point-item-active {
-                    background: #0f9272 !important;
-                }
-				
-				// .block-point-item:before{
-				// 	content:'';
-				// 	display:block;
-				// 	width:8px;
-				// 	height:14px;
-				// 	border-right:#fff solid 2px;
-				// 	border-bottom:#fff solid 2px;
-				// 	transform:rotate(35deg);
-				// 	position:absolute;
-				// 	bottom:12px;
-				// 	left:12px;
-				// 	z-index:2;
-				// }
-				
-				.block-point-item{
-					background-color: #006988;
-				}
-
-                .point-item:hover {
-                    .point-item-tools {
-                        display: unset;
-                    }
-                }
-            }
-        }
-    }
-}
-
-.fl-row-center{
-    display:flex;
-    align-items:center;
-}
-
-.fl-col-center {
-    display: flex;
-    flex-direction:column;
-    align-items: center;
-}
-
-.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%);
-}
-
-
-
-

+ 0 - 938
TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/Index.vue

@@ -1,938 +0,0 @@
-<style lang="less" scoped>
-	@import './Index.less';
-</style>
-
-<template>
-	<div class="new-syllabus-container">
-		<Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-if="isLoading"></Loading>
-		<!-- 课纲头部 切换来源以及选择学段 -->
-		<div class="new-syllabus-header">
-
-			<div class="new-syllabus-select">
-				<span>当前学段:</span>
-				<Select ref="periodSelect" v-model="currentPeriodIndex" style="width:100px;" @on-change="onPeriodChange">
-					<Option v-for="(item,index) in periodList" :value="index" :key="index">{{ item.name }}</Option>
-				</Select>
-			</div>
-		</div>
-		<!-- 主体内容 -->
-		<div class="new-syllabus-content">
-			<!-- 选择学科 -->
-			<div class="ns-col ns-col">
-				<Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadSubject"></Loading>
-				<div class="ns-header">
-					<!-- 切换头部以及搜索框 -->
-					<div class="ns-header-content" v-if="!isSearchSubject">
-						<span>
-							<Icon type="md-bookmark" color="#fff" size="20" />
-							<span style="margin-left:5px">学科</span>
-						</span>
-						<Icon type="ios-search" color="#fff" size="18" v-show="subjectList.length" style="cursor:pointer" @click="isSearchSubject = true" />
-					</div>
-					<div class="ns-header-search" v-else>
-						<Input icon="ios-close" v-model="searchSubject" placeholder="搜索学科..." autofocus style="width: 100%" @on-click="onSearchSubjectClose"
-						 @on-change="onSearchSubjectChange" @on-enter="onSearchSubjectChange" />
-					</div>
-				</div>
-				<vuescroll>
-					<div v-if="subjectList.length === 0">
-						<EmptyData :top="100"></EmptyData>
-					</div>
-					<div class="gl" v-else>
-						<div :class='["gl-item",index == activeSubjectIndex ? "item-active":""]' v-for="(item,index) in subjectList" :key="index"
-						 @click="hasModify ? handleConfirmSave({index},'2') : handleSubjectTap(index)">
-							<p class="gl-item-name">{{item.name}}</p>
-							<p class="gl-item-info"><span></span>知识块数:{{ tabIndex === 0  ? schoolBlockCount[index] : privateBlockCount[index]}}</p>
-						</div>
-					</div>
-				</vuescroll>
-			</div>
-
-			<!-- 展示知识点部分 -->
-			<div class="ns-col ns-col3" ref="colRef3">
-				<Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadPoints"></Loading>
-				<div class="ns-header">
-					<!-- 切换头部以及搜索框 -->
-					<div class="ns-header-content" v-if="!isSearchPoint">
-						<span>
-							<Icon type="md-cube" color="#fff" size="20" />
-							<span style="margin-left:5px">知识点 ( {{ originPointList.length }} )</span>
-							<Input icon="ios-close" v-model="searchPoint" v-show="originPointList.length" placeholder="搜索知识点..." autofocus style="width: 300px;margin-left: 20px;"
-							 @on-click="onSearchClear" @on-blur="isSearchPoint = false" @on-change="onSearchPointChange" @on-enter="onSearchPointChange"
-							 @on-clear="onSearchClear" />
-						</span>
-						<div>
-							<Icon type="md-add" v-if="($access.can('admin.*|Point_Add')) && subjectList.length" color="#fff" size="18" style="cursor:pointer;margin-right:10px"
-							 @click="onAddPoint" />
-							<Button class="btn-compose-block" v-if="checkedPointList.length" @click="onComposeBlock">组成知识块</Button>
-						</div>
-					</div>
-					<div class="ns-header-search" v-else>
-					</div>
-					<div>
-						<div v-if="pointList.length === 0">
-							<EmptyData :top="100"></EmptyData>
-						</div>
-						<div v-else>
-							<draggable class="points-wrap" tag="div" v-model="pointList" v-bind="dragOptions">
-								<transition-group type="transition" :name="!drag ? 'flip-list' : null" class="points-wrap">
-									<div v-for="(item,index) in pointList" :key="index" :class="['point-item', isBlockPoint(item) ? 'block-point-item' : '' , isChecked(item) ? 'point-item-active' : '']"
-									 @click="onPointCheck(item)" draggable="true" @dragstart="onDragStart(item)" @dragend="isDragging = false">
-										<span>{{item.name}}</span>
-										<span class="point-item-tools">
-											<span class="btn-edit" v-if="$access.can('admin.*|Point_Edit') || tabIndex === 1" title="编辑" @click.stop="onEditPoint(index,item)">
-												<Icon type="md-create" size="18" color="#d2d2d2" /></span>
-											<span class="btn-delete" v-if="$access.can('admin.*|Point_Delete') || tabIndex === 1" title="删除" @click.stop="onDeletePoint(index,item)">
-												<Icon type="md-trash" size="20" color="#d2d2d2" /></span>
-											<span class="btn-delete" v-if="$access.can('admin.*|Point_Remove') && isBlockPoint(item)" title="移出知识块"
-											 @click.stop="onRemovePoint(index,item)">
-												<Icon type="md-remove-circle" size="20" color="#d2d2d2" /></span>
-										</span>
-									</div>
-								</transition-group>
-							</draggable>
-							<!-- <Page :total="originPointList.length || 0" show-sizer show-total :page-size-opts="pageSizeOpt" :current="currentPage"
-							 :page-size="pageSize" @on-page-size-change="pageSizeChange" @on-change="pageChange" /> -->
-						</div>
-					</div>
-				</div>
-			</div>
-
-			<!-- 选择知识块 -->
-			<div class="ns-col ns-col2" ref="colRef2">
-				<Loading :top="200" bgColor="rgba(103, 103, 103, 0.27)" type="1" v-show="isLoadBlocks"></Loading>
-				<div class="ns-header">
-					<!-- 切换头部以及 搜索框 -->
-					<div class="ns-header-content" v-if="!isSearchBlock">
-						<span>
-							<Icon type="ios-photos" color="#fff" size="20" />
-							<span style="margin-left:5px">知识块</span>
-						</span>
-						<div>
-							<Icon type="md-add" v-if="($access.can('admin.*|Block_Add') || tabIndex === 1)  && subjectList.length" color="#fff" size="18" style="cursor:pointer;margin-right:10px"
-							 @click="onAddBlock" />
-							<Icon type="ios-search" color="#fff" size="18" style="cursor:pointer" v-show="subjectList.length && blockList.length" @click="isSearchBlock = true" />
-						</div>
-					</div>
-					<div class="ns-header-search" v-else>
-						<!-- 搜索知识块部分 -->
-						<Input icon="ios-close" v-model="searchBlock" placeholder="搜索知识块..." autofocus style="width: 100%" @on-click="onSearchBlockClose"
-						 @on-change="onSearchBlockChange" @on-enter="onSearchBlockChange" />
-					</div>
-				</div>
-				<vuescroll>
-					<!-- 知识块列表 -->
-					<div class="vl gl">
-						<div v-if="blockList.length === 0">
-							<div class="gl-item gl-new-area" v-show="isDragging" @drop="onDragNewEnd" @dragover.prevent>
-								<Icon type="md-add" size="18" />
-								<span style="margin-left: 10px;">新建知识块</span>
-							</div>
-							<EmptyData :top="50"></EmptyData>
-						</div>
-						<div v-else>
-							<div class="gl-item gl-new-area" v-show="isDragging" @drop="onDragNewEnd" @dragover.prevent>
-								<Icon type="md-add" size="18" />
-								<span style="margin-left: 10px;">新建知识块</span>
-							</div>
-							<div :class='["gl-item","drag-block-item",index == activeBlockIndex ? "item-active":""]' v-for="(item,index) in blockList"
-							 :key="index" @click="handleBlockTap(index,item)" @drop="onDragEnd(item,index,$event)" @dragover.prevent
-							 @dragend="onDragEnd(item,index)" @dragenter="onDragEnter" @dragleave="onDragLeave">
-								<p class="gl-item-name" :title="item.name">{{item.name}}</p>
-								<p class="gl-item-info"><span></span>知识点数:{{item.points ? item.points.length : 0}}</p>
-								<span class="btn-edit" v-if="$access.can('admin.*|Block_Edit') || tabIndex === 1" title="编辑" @click.stop="onEditBlock(item)">
-									<Icon type="md-create" size="20" color="#d2d2d2" /></span>
-								<span class="btn-delete" v-if="$access.can('admin.*|Block_Delete') || tabIndex === 1" title="删除" @click.stop="onDeleteBlock(item)">
-									<Icon type="md-trash" size="22" color="#d2d2d2" /></span>
-							</div>
-						</div>
-					</div>
-				</vuescroll>
-			</div>
-		</div>
-
-		<!-- 新增知识块弹窗 -->
-		<Modal v-model="isAddBlock" width="560" footer-hide class="add-volume-modal">
-			<div class="modal-header" slot="header">{{ isEditBlock ? '编辑知识块' : '新增知识块'}}</div>
-			<div class="modal-content">
-				<AddBlock :originData="originSchoolData" :periodIndex="currentPeriodIndex" :subjectIndex="currentSubjectIndex"
-				 :editBlock="editBlock" :addType="pointOwn" @addFinish="onFinishAddBlock">
-				</AddBlock>
-			</div>
-		</Modal>
-
-		<!-- 新增知识点弹窗 -->
-		<Modal v-model="isAddPoint" width="560" footer-hide class="add-volume-modal">
-			<div class="modal-header" slot="header">{{ isEditPoint ? '编辑知识点' : '新增知识点'}}</div>
-			<div class="modal-content">
-				<AddPoint :hideBlock="isShowPoints" :schoolParams="schoolParams" :blockData="parentBlock" :pointData="currentPoint"
-				 :addType="pointOwn" @addFinish="onFinishAddPoint">
-				</AddPoint>
-			</div>
-		</Modal>
-
-		<!-- 组成知识块弹窗 -->
-		<Modal v-model="isComposeBlock" width="680" footer-hide class="add-volume-modal compose-modal">
-			<div class="modal-header" slot="header">组成知识块</div>
-			<ComposeBlock :list="checkedPointList" :params="currentParams" :blockList="originBlockList" @onFinish="onComposeFinish"></ComposeBlock>
-		</Modal>
-	</div>
-</template>
-
-<script>
-	import Tree from '@/components/syllabus/DragTree'
-	import AddBlock from './operation/AddBlock'
-	import AddPoint from './operation/AddPoint'
-	import ComposeBlock from './operation/ComposeBlock'
-	import draggable from "vuedraggable"
-
-	export default {
-		data() {
-			return {
-				schoolInfo: {
-					code: ''
-				},
-				currentParams: {
-					code: '',
-					subjectId: '',
-					school_code: '',
-					periodId: '',
-					type: 0
-				},
-				drag: false,
-				isDragging: false,
-				isLoadSubject: false,
-				isLoadBlocks: false,
-				isLoadPoints: false,
-				isLoading: false,
-				schoolParams: null,
-				currentPeriodIndex: null,
-				currentSubjectIndex: null,
-				currentBlock: null,
-				currentPoint: null,
-				tabIndex: 0,
-				originData: {},
-				originSchoolData: {},
-				periodList: [],
-				subjectList: [],
-				originSubjectList: [],
-				blockList: [],
-				originBlockList: [],
-				pointList: [],
-				originPointList: [],
-				activePeriodIndex: 0,
-				activeSubjectIndex: 0,
-				activeBlockIndex: null,
-				blockCounts: [],
-				schoolBlockCount: [],
-				privateBlockCount: [],
-				isSearchSubject: false,
-				isSearchBlock: false,
-				isSearchPoint: false,
-				isAddBlock: false,
-				isEditBlock: false,
-				isAddPoint: false,
-				isEditPoint: false,
-				isComposeBlock: false,
-				searchBlock: '',
-				searchPoint: '',
-				searchSubject: '',
-				editBlock: null,
-				editPointIndex: null,
-				hasModify: false,
-				preSelectVal: null,
-				pageSize: 20,
-				currentPage: 1,
-				pageSizeOpt: [5, 10, 15, 20],
-				pointOwn: 'school',
-				isShowPoints: true,
-				parentBlock: null,
-				checkedPointList: [],
-				curBlockPoints: [],
-				curDragPoint: null
-			}
-		},
-		components: {
-			Tree,
-			AddBlock,
-			AddPoint,
-			ComposeBlock,
-			draggable
-		},
-		created() {
-			this.initSchoolData()
-
-			this.initBlockCount()
-		},
-		methods: {
-
-			/* 知识点拖动开始 */
-			onDragStart(item) {
-				this.curDragPoint = item
-				this.isDragging = true
-			},
-
-			/* 知识点移入到知识块 */
-			onDragEnter(e) {
-				e.target.classList.add('drag-active')
-			},
-
-			/* 知识点拖拽离开知识块 */
-			onDragLeave(e) {
-				e.target.classList.remove('drag-active')
-			},
-
-			// 知识点拖拽到知识块后
-			onDragEnd(blockItem, blockIndex, e) {
-				e.target.classList.remove('drag-active')
-				// 判断是单个拖拽还是选择了多个进行拖拽
-				let checkPointIds = new Set(this.checkedPointList.map(i => i.id))
-				let blockPointIds = new Set(blockItem.points)
-				if (checkPointIds.has(this.curDragPoint.id) && checkPointIds.size > 1) {
-					// 如果是选中的元素 则获取选中的和知识块包含的 差集 即为需要添加的知识点ID
-					let addPointIds = new Set([...checkPointIds].filter(x => !blockPointIds.has(x)))
-					if (addPointIds.size > 0) {
-						this.$Modal.confirm({
-							title: '提示',
-							content: `确定将 ${ this.curDragPoint.name } 等 ${ addPointIds.size } 个知识点移入到知识块 ${ blockItem.name } 中 (已存在的知识点会自动忽略)?`,
-							okText: '确认',
-							cancelText: '取消',
-							onOk: () => {
-								this.isLoading = true
-								blockItem.points.push(...addPointIds)
-								this.savePointAndBlock(blockItem)
-								this.initBlockCount()
-							}
-						})
-					} else {
-						this.$Message.warning('所选知识点已存在于该知识块中!')
-					}
-
-				} else {
-					if (blockItem.points.includes(this.curDragPoint.id)) {
-						this.$Message.warning('该知识块已存在当前知识点!')
-					} else {
-						this.$Modal.confirm({
-							title: '提示',
-							content: `确定将知识点 ${ this.curDragPoint.name } 移入到知识块 ${ blockItem.name } 中?`,
-							okText: '确认',
-							cancelText: '取消',
-							onOk: () => {
-								this.isLoading = true
-								blockItem.points.push(this.curDragPoint.id)
-								this.savePointAndBlock(blockItem)
-								this.initBlockCount()
-							}
-						})
-					}
-				}
-			},
-
-			/* 拖拽知识点组成新知识块 */
-			onDragNewEnd(e) {
-				if (!this.checkedPointList.length) {
-					let list = this.checkedPointList
-					let item = this.curDragPoint
-					let isExistIndex = list.indexOf(item)
-					if (isExistIndex > -1) {
-						this.checkedPointList.splice(isExistIndex, 1)
-					} else {
-						this.checkedPointList.push(item)
-					}
-				}
-
-				this.isComposeBlock = true
-			},
-
-			/* 保存最新知识块内容 */
-			savePointAndBlock(pointItem) {
-				return new Promise((r, j) => {
-					console.log(pointItem)
-					pointItem.code =  pointItem.code.replace('Knowledge-','')
-					this.$api.knowledge.SaveOrUpdateKnowledge([pointItem]).then(res => {
-						if (!res.error && res.knowledges) {
-							this.curDragPoint = null
-							this.isLoading = false
-							this.checkedPointList = []
-							this.$Message.success('操作成功!')
-							r(200)
-						} else {
-							this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-						}
-					}).catch(err => {
-						j(err)
-						this.$Message.warning('操作失败')
-					})
-				})
-
-			},
-
-			// 获取当前学校学段学科等基本信息
-			initSchoolData() {
-				this.$store.dispatch('user/getSchoolProfile').then(res => {
-						let schoolBaseInfo = res.school_base
-						if(schoolBaseInfo){
-						this.schoolInfo = schoolBaseInfo
-						this.originSchoolData = schoolBaseInfo // 默认选择第一个
-						this.originData = schoolBaseInfo // 默认选择第一个
-						if(schoolBaseInfo.period.length){
-							this.periodList = schoolBaseInfo.period
-							this.currentParams.code = schoolBaseInfo.id
-							this.currentParams.school_code = schoolBaseInfo.id
-							this.currentParams.periodId = schoolBaseInfo.period[0].id
-							this.currentPeriodIndex = 0 // 默认选择第一个学段
-							this.onPeriodChange(0)
-						}
-					}
-				})
-			},
-
-			// 获取当前册别数量(每次都获取最新的数据)
-			initBlockCount() {
-				// if (this.blockCounts.length) {
-				// 	this.schoolBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[0])
-				// 	this.privateBlockCount = this.blockCounts[this.currentPeriodIndex].map(i => i[1])
-				// } else {
-					this.$api.syllabus.FindBlockCount({
-						code: this.$store.state.userInfo.schoolCode
-					}).then(res => {
-						if (!res.error) {
-							this.$nextTick(() => {
-								this.blockCounts = res
-								this.schoolBlockCount = res[this.currentPeriodIndex || 0].map(i => i[0])
-								this.privateBlockCount = res[this.currentPeriodIndex || 0].map(i => i[1])
-							})
-						} else {
-							this.$Message.warning('获取数据失败')
-						}
-					})
-				// }
-			},
-
-			// 根据学科获取所有知识块信息
-			getBlocksData() {
-				let that = this
-				let params = JSON.parse(JSON.stringify(this.currentParams))
-				params.type = 0
-				this.$api.knowledge.GetSchoolPoints(params).then(res => {
-					if (!res.error && res.knowledges) {
-						let list = res.knowledges
-						this.blockList = list
-						this.originBlockList = JSON.parse(JSON.stringify(list))
-						// this.handleBlockTap(0, list.length ? list[0] : null)
-						setTimeout(function() {
-							that.isLoadBlocks = false
-						}, 400)
-					} else {
-						this.$Message.warning('获取数据失败')
-					}
-				}).catch(err => {
-					this.$Message.error('知识块数据获取失败')
-					this.isLoadBlocks = false
-				})
-			},
-
-			// 根据学科获取学科下所有知识点数据
-			getPointsData() {
-				let that = this
-				this.currentParams.type = 1
-				this.$api.knowledge.GetSchoolPoints(this.currentParams).then(res => {
-					if (!res.error && res.knowledges) {
-						this.pointList = res.knowledges
-						this.originPointList = JSON.parse(JSON.stringify(res.knowledges))
-						setTimeout(function() {
-							that.isLoadPoints = false
-						}, 800)
-					} else {
-						this.$Message.warning('获取数据失败')
-					}
-				})
-			},
-
-			// 校本知识块与个人切换
-			handleTabClick(index) {
-				this.checkedPointList = []
-				this.tabIndex = index
-				switch (index) {
-					case 0:
-						this.currentParams.code = this.originData.schoolCode
-						//this.isShowPoints ? this.getPointsData() : this.getBlocksData()
-						this.getPointsData()
-						this.getBlocksData()
-						this.pointOwn = 'school'
-						break
-					case 1:
-						this.currentParams.code = this.$store.state.userInfo.TEAMModelId
-						this.getPointsData()
-						this.getBlocksData()
-						//this.isShowPoints ? this.getPointsData() : this.getBlocksData()
-						this.pointOwn = 'personal'
-						break
-					default:
-						break
-				}
-
-				this.handleSubjectTap(0)
-			},
-
-			// 学段切换处理
-			onPeriodChange(index) {
-				this.$nextTick(() => {
-					this.preSelectVal = this.$refs.periodSelect.value
-					if (this.hasModify) {
-						this.handleConfirmSave({}, '3')
-					} else {
-						let that = this
-						this.isLoadSubject = true
-						this.activePeriodIndex = index
-						this.currentParams.periodId = this.originData.period[index].id
-						this.subjectList = this.periodList[index].subjects // 切换学段后更新 学科 列表
-						this.originSubjectList = this.periodList[index].subjects // 筛选学科源数据
-						if(this.subjectList.length){
-							this.handleSubjectTap(0)
-							this.initBlockCount()
-						}else{
-							this.pointList = []
-							this.originBlockList = []
-							this.blockList = []
-							this.originPointList = []
-						}
-						setTimeout(function() {
-							that.isLoadSubject = false
-						}, 400)
-					}
-				})
-			},
-
-			// 学科点击事件
-			handleSubjectTap(index) {
-				this.checkedPointList = []
-				this.blockList = []
-				this.originBlockList = []
-				this.pointList = []
-				this.originPointList = []
-				this.schoolParams = {
-					schoolCode: this.originData.id,
-					subjectId: this.subjectList[index].id,
-					period: this.currentParams.periodId
-				}
-				this.currentSubjectIndex = index
-				this.currentParams.subjectId = this.subjectList[index].id
-				// this.currentParams.type = this.isShowPoints ? 1 : 0
-				this.activeSubjectIndex = index
-				this.isLoadBlocks = true
-				this.getBlocksData()
-				this.getPointsData()
-
-			},
-
-			// 知识块点击事件
-			handleBlockTap(index, item) {
-				if (index === this.activeBlockIndex) {
-					this.activeBlockIndex = null
-					this.curBlockPoints = []
-				} else {
-					let that = this
-					let blockPoints = []
-					this.activeBlockIndex = index
-					this.currentBlock = item
-					if (item && item.points.length) {
-						this.curBlockPoints = item.points
-						this.toStartPosition(item.points)
-					} else { // 没有则置空
-						this.curBlockPoints = []
-					}
-				}
-			},
-
-			// 把当前知识块的知识点排到最前面
-			toStartPosition(points) {
-				points.forEach(i => {
-					let pointIds = this.pointList.map(i => i.id)
-					if (pointIds.includes(i)) {
-						let index = pointIds.indexOf(i)
-						let item = this.pointList[index]
-						this.pointList.splice(index, 1)
-						this.pointList.unshift(item)
-					}
-				})
-			},
-
-			// 添加知识块完成
-			onFinishAddBlock(val) {
-				this.$Message.success('操作成功!')
-				this.handleSubjectTap(this.currentSubjectIndex) // 获取最新知识块数据
-				this.isAddBlock = false // 关闭窗口
-				this.blockCounts = []
-				this.initBlockCount()
-			},
-
-			// 添加知识点完成
-			onFinishAddPoint(val) {
-				if(!val) return
-				let that = this
-				this.isLoadPoints = true
-				if (this.isEditPoint) {
-					this.pointList[this.editPointIndex] = val
-				} else {
-					if (!this.isShowPoints) this.currentBlock.points.push(val.id)
-					this.originPointList.push(val)
-					this.pageChange(this.currentPage)
-				}
-				this.$Message.success('操作成功!')
-				this.isAddPoint = false // 关闭窗口
-				this.isEditPoint = false
-				setTimeout(function() {
-					that.isLoadPoints = false
-					that.initBlockCount()
-				}, 400)
-			},
-
-			// 删除知识块事件
-			onDeleteBlock(data) {
-				this.$Modal.confirm({
-					title: '提示',
-					content: '<p>确认删除该知识块?</p>',
-					okText: '确认',
-					cancelText: '取消',
-					onOk: () => {
-						let that = this
-						this.isLoading = true
-						this.$api.knowledge.DeleteSchoolPoint({
-							code:data.code.replace('Knowledge-',''),
-							id: data.id
-						}).then(res => {
-							if (!res.error) {
-								console.log(this.blockList)
-								console.log(this.originBlockList)
-								console.log(data)
-								this.blockList.splice(this.blockList.indexOf(data), 1)
-								this.originBlockList.splice(this.originBlockList.indexOf(data), 1)
-								console.log(this.blockList)
-								console.log(this.originBlockList)
-								this.handleBlockTap(0, this.blockList.length ? this.blockList[0] : null)
-								setTimeout(() => {
-									that.blockCounts = []
-									that.initBlockCount()
-									that.isLoading = false
-									that.$Message.success('删除成功')
-								}, 1000)
-
-
-							} else {
-								this.$Message.success('删除失败')
-							}
-						})
-					}
-				})
-			},
-
-			// 删除知识点事件
-			onDeletePoint(data) {
-				this.$Modal.confirm({
-					title: '提示',
-					content: '<p>确认删除该知识点?</p>',
-					okText: '确认',
-					cancelText: '取消',
-					onOk: () => {
-						this.isLoadPoints = true
-						this.$api.knowledge.DeleteSchoolPoint({
-							code:data.code.replace('Knowledge-',''),
-							id: data.id
-						}).then(res => {
-							if (!res.error) {
-								this.$Message.success('删除成功')
-								this.originPointList.splice(this.originPointList.indexOf(data), 1)
-								if (!this.isShowPoints) this.currentBlock.points.splice(this.currentBlock.points.indexOf(data.id), 1)
-								this.pageChange(this.currentPage)
-								this.isLoadPoints = false
-							} else {
-								this.$Message.warning('删除失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-							}
-						}).catch(err => {
-							console.log(err)
-							this.$Message.warning('删除失败')
-						})
-					}
-				})
-			},
-
-			// 移除知识点事件
-			onRemovePoint(data) {
-				this.$Modal.confirm({
-					title: '提示',
-					content: `确定将知识点 ${ data.name } 从知识块 ${ this.currentBlock.name } 中移除?`,
-					okText: '确认',
-					cancelText: '取消',
-					onOk: () => {
-						if (this.currentBlock.points.includes(data.id)) {
-							let that = this
-							this.currentBlock.points.splice(this.currentBlock.points.indexOf(data.id), 1)
-							this.savePointAndBlock(this.currentBlock).then(r => {
-								this.curBlockPoints = []
-								this.currentBlock = null
-								this.activeBlockIndex = null
-								that.handleSubjectTap(that.currentSubjectIndex)
-							})
-
-						} else {
-							this.$Message.error('移除失败')
-						}
-					}
-				})
-			},
-
-			// 编辑知识块事件
-			onEditBlock(data) {
-				this.isAddBlock = true // 打开新增窗口
-				this.isEditBlock = true // 设置成编辑状态
-				this.editBlock = data
-			},
-
-			// 新增知识块事件
-			onAddBlock() {
-				this.isAddBlock = true
-				this.isEditBlock = false
-				this.editBlock = null
-			},
-
-			// 新增知识点事件
-			onAddPoint() {
-				this.isAddPoint = true
-				this.isEditPoint = false
-				this.currentPoint = null
-				// this.parentBlock = this.isShowPoints ? null : this.currentBlock
-				this.parentBlock = null
-				this.onSearchClear()
-			},
-
-			// 编辑知识点事件
-			onEditPoint(index, data) {
-				this.isAddPoint = true // 打开新增窗口
-				this.isEditPoint = true // 设置成编辑状态
-				this.currentPoint = data
-				this.editPointIndex = index
-				console.log('87878787878787878')
-				console.log(this.parentBlock)
-				this.parentBlock = this.isShowPoints ? null : this.currentBlock
-			},
-
-			// 知识点点击事件
-			onPointCheck(item) {
-				if (this.isShowPoints) {
-					let list = this.checkedPointList
-					let isExistIndex = list.indexOf(item)
-					if (isExistIndex > -1) {
-						this.checkedPointList.splice(isExistIndex, 1)
-					} else {
-						this.checkedPointList.push(item)
-					}
-				}
-			},
-
-			// 点击组成知识块
-			onComposeBlock() {
-				this.isComposeBlock = true
-			},
-
-			// 组成知识块结束
-			onComposeFinish() {
-				this.isComposeBlock = false
-				this.checkedPointList = []
-				this.activeBlockIndex = null
-				this.curBlockPoints = []
-				this.handleSubjectTap(this.currentSubjectIndex)
-				this.$Message.success('操作成功')
-				this.initBlockCount()
-			},
-
-			// 搜索知识块输入框onchange事件
-			onSearchBlockChange() {
-				this.blockList = this.originBlockList.filter(item => item.name.indexOf(this.searchBlock) > -1)
-				if (this.blockList.length) this.handleBlockTap(0, this.blockList[0])
-			},
-
-			// 搜索知识点输入框onchange事件
-			onSearchPointChange() {
-				this.pointList = this.originPointList.filter(item => item.name.indexOf(this.searchPoint) > -1)
-			},
-
-			// 清空科目搜索框
-			onSearchSubjectClose() {
-				this.searchSubject = ''
-				this.isSearchSubject = false
-				this.subjectList = this.originSubjectList
-				this.handleSubjectTap(0)
-			},
-
-			onSearchClear() {
-				this.searchPoint = ''
-				this.isSearchPoint = false
-				this.pointList = this.originPointList
-			},
-
-			// 清空科目搜索框
-			onSearchBlockClose() {
-				this.searchBlock = ''
-				this.isSearchBlock = false
-				this.blockList = this.originBlockList
-				if (this.blockList.length) this.handleBlockTap(0, this.blockList[0])
-			},
-
-			// 搜索学科输入框onchange事件
-			onSearchSubjectChange() {
-				this.subjectList = this.originSubjectList.filter(item => item.name.indexOf(this.searchSubject) > -1)
-				this.handleSubjectTap(0)
-			},
-
-			// 切换页码返回截取数据
-			pageChange(page) {
-				this.currentPage = page
-				let start = this.pageSize * (page - 1)
-				let end = this.pageSize * page
-				this.pointList = this.originPointList ? this.originPointList.slice(start, end) : []
-				// 如果删除的是仅剩的一个元素 则往前翻页
-				if (this.pointList.length === 0 && page > 1) {
-					this.pageChange(page - 1)
-				}
-			},
-
-			// 切换每页显示页数
-			pageSizeChange(val) {
-				this.pageSize = val
-				this.currentPage = 1
-				this.pageChange(1)
-			},
-
-		},
-		mounted() {
-
-
-		},
-		computed: {
-			dragOptions() {
-				return {
-					animation: 200,
-					group: "description",
-					disabled: false,
-					ghostClass: "ghost"
-				};
-			},
-			isChecked() {
-				return item => {
-					return this.checkedPointList.map(item => item.id).indexOf(item.id) > -1
-				}
-			},
-			isBlockPoint() {
-				return item => {
-					return this.curBlockPoints.indexOf(item.id) > -1
-				}
-			}
-
-		},
-	}
-</script>
-
-<style>
-	.new-syllabus-header .ivu-select-single .ivu-select-selection,
-	.funnel-box .ivu-select-single .ivu-select-selection {
-		background: transparent;
-		color: #fbfbfb;
-		border: 1px solid #424242;
-	}
-
-	.new-syllabus-header .ivu-select-single .ivu-select-arrow,
-	.funnel-box .ivu-select-single .ivu-select-arrow {
-		color: #fbfbfb;
-	}
-
-	.ns-header .ivu-input {
-		background: #3c3c3c;
-		color: #fff;
-		border: none;
-		height: 35px;
-	}
-
-	.ns-header .ivu-input-icon {
-		font-size: 20px;
-		color: #cfc7c7;
-		line-height: 32px;
-		cursor: pointer;
-	}
-
-	/* 修改iview Modal样式 */
-
-	.add-volume-modal .ivu-modal-content {
-		background: #3c3c3c;
-		color: #fff;
-	}
-
-	.add-volume-modal .ivu-modal-header {
-		border-bottom: none;
-		font-size: 18px;
-		font-weight: bold;
-		padding: 25px;
-	}
-
-	.add-volume-modal .modal-content {
-		padding: 10px 35px 30px 35px;
-	}
-
-	/* 修改iview popper样式 */
-
-	.ns-col .ivu-poptip-inner {
-		background: #3c3c3c;
-	}
-
-	.ns-col .ivu-poptip-title:after {
-		background: #656565;
-		left: 16px;
-		right: 20px;
-	}
-
-	.ns-col .ivu-poptip-title-inner {
-		color: #fff;
-	}
-
-	.ns-col .ivu-poptip-popper[x-placement^=bottom] .ivu-poptip-arrow:after {
-		border-bottom-color: #494949;
-	}
-
-	.ns-col .points-wrap .ivu-page {
-		position: absolute;
-		bottom: 40px;
-		left: 0;
-		width: 100%;
-		text-align: center;
-	}
-
-	.ns-col .points-wrap .ivu-page .ivu-page-item,
-	.ns-col .points-wrap .ivu-page .ivu-page-next,
-	.ns-col .points-wrap .ivu-page .ivu-page-prev {
-		background: none;
-		border: none;
-		line-height: 32px;
-	}
-
-	.ns-col .points-wrap .ivu-page .ivu-page-item a,
-	.ns-col .points-wrap .ivu-page .ivu-page-next a,
-	.ns-col .points-wrap .ivu-page .ivu-page-prev a {
-		color: #fff;
-	}
-
-	.ns-col .points-wrap .ivu-page-item-active {
-		border: none;
-		background: rgb(11, 151, 117) !important;
-	}
-
-	.ns-col .points-wrap .ivu-select-selection,
-	.ns-col .points-wrap .ivu-page-options-elevator input {
-		border: none;
-		background: #605f5f;
-	}
-
-	.ns-col .points-wrap .ivu-select,
-	.ns-col .points-wrap .ivu-page-options-elevator input {
-		color: #fff;
-	}
-</style>

+ 0 - 175
TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/AddBlock.vue

@@ -1,175 +0,0 @@
-
-<template>
-    <div class="form-container">
-        <Form :model="formTop" label-position="top">
-            <FormItem label="科目">
-                <Select v-model="formTop.subject">
-                    <Option v-for="(item,index) in currentPeriod.subjects" :value="item.id" :key="index">{{ item.name }}</Option>
-                </Select>
-            </FormItem>
-            <FormItem label="名称">
-                <Input v-model="formTop.name" placeholder="请输入知识块名称,必填项"></Input>
-            </FormItem>
-            <FormItem>
-                <Button @click="handleSubmit" :loading="isLoading">确认</Button>
-            </FormItem>
-        </Form>
-    </div>
-</template>
-
-<script>
-    import '@/utils/Math.uuid'
-    export default {
-        props: ['originData', 'periodIndex', 'subjectIndex', 'addType', 'editBlock'],
-        data() {
-            return {
-                originDatas: {},
-                currentPeriod: {},
-                editItem: null,
-                addPointType: 'school',
-                isLoading: false,
-                uuid: '',
-                formTop: {
-                    subject: '',
-                    grade: '',
-                    semester: '',
-                    name: ''
-                }
-            }
-        },
-
-        created() {
-			if(this.originData && this.originData.period){
-				this.currentPeriod = this.originData.period[this.periodIndex]
-				this.originDatas = this.originData
-			}
-        },
-        methods: {
-            // 提交添加
-            handleSubmit() {
-                let newName = this.formTop.name
-                if (!newName) {
-                    this.$Message.warning('知识块名称不能为空!')
-                } else {
-                    this.isLoading = true
-                    this.uuid = Math.uuid()
-                    let params = {
-                        type: 0,
-                        name: this.formTop.name,
-                        alias: this.formTop.name,
-                        subjectId: this.formTop.subject,
-                        code: this.addPointType === 'school' ? this.$store.state.userInfo.schoolCode : this.$store.state.userInfo.TEAMModelID,
-                        order: 706,
-                        status: 1,
-                        knowledgeId: this.uuid,
-                        periodId: this.currentPeriod.id,
-                        points: [],
-                        source: 1
-                    }
-                    if (this.editItem && this.editItem.code) {
-                        params.knowledgeId = this.editItem.knowledgeId
-                        params.points = this.editItem.points
-                        params.id = this.editItem.id
-                    }
-                    this.$api.knowledge.SaveOrUpdateKnowledge([params]).then(res => {
-                        if (!res.error && res.knowledges) {
-                            this.$emit('addFinish', false)
-                        } else {
-                            this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-                        }
-                        this.closeModal()
-                        this.editItem = null
-                        this.isLoading = false
-                    }).catch(err => {
-                        console.log(err)
-                        this.$Message.warning('操作失败')
-                        this.isLoading = false
-                    })
-                }
-            },
-
-            // 添加完成 关闭窗口
-            closeModal() {
-                this.formTop.name = ''
-            }
-        },
-        watch: {
-            addType: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.addPointType = newValue
-                    }
-                }
-            },
-            originData: {
-                handler(newValue, oldValue) {
-                    this.originDatas = newValue
-                }
-            },
-            periodIndex: {
-                handler(newValue, oldValue) {
-                    this.currentPeriod = this.originDatas.period[newValue]
-                    this.formTop.subject = this.currentPeriod.subjects.length ? this.currentPeriod.subjects[0].id : ''
-                    this.formTop.name = ''
-                }
-            },
-            subjectIndex: {
-                handler(newValue, oldValue) {
-                    this.formTop.subject = this.currentPeriod.subjects ? this.currentPeriod.subjects[newValue].id : ''
-                }
-            },
-            editBlock: {
-                handler(newValue, oldValue) {
-                    if (newValue) { // 有编辑册别传过来则为编辑状态
-                        this.editItem = newValue
-                        this.formTop.subject = this.formTop.subject || newValue.subjectId
-                        this.formTop.name = newValue.name
-                    } else { // 否则为新增状态
-                        this.formTop.subject = this.formTop.subject || this.currentPeriod.subjects[0].id
-                        this.formTop.name = ''
-                        this.editItem = newValue
-                    }
-                }
-            }
-        }
-
-    }
-</script>
-
-<style>
-    .form-container .ivu-form .ivu-form-item-label {
-        color: #fff;
-        margin: 10px 0;
-        font-size: 16px;
-    }
-
-    .form-container .ivu-input {
-        background: #575757;
-        border-color: transparent;
-        height: 35px;
-        color: #fff;
-    }
-
-        .form-container .ivu-input::-webkit-input-placeholder {
-            color: #808080;
-        }
-
-    .form-container .ivu-select-single .ivu-select-selection {
-        background: #575757;
-        color: #fbfbfb;
-        border-color: transparent;
-        height: 35px;
-    }
-
-    .form-container .ivu-select-single .ivu-select-arrow {
-        color: #fbfbfb;
-    }
-
-    .form-container .ivu-btn {
-        width: 100%;
-        height: 40px;
-        background: rgb(11, 151, 117);
-        border: none;
-        color: #fff;
-    }
-</style>

+ 0 - 187
TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/AddPoint.vue

@@ -1,187 +0,0 @@
-
-<template>
-    <div class="form-container">
-        <Form :model="formTop" label-position="top">
-            <FormItem label="知识块" v-show="!hideBlock">
-                <Input v-model="formTop.blockName" disabled></Input>
-            </FormItem>
-            <FormItem label="名称">
-                <Input v-model="formTop.name" placeholder="请输入知识点名称,必填项"></Input>
-            </FormItem>
-            <FormItem>
-                <Button @click="handleAddPointSubmit()" :loading="isLoading">确认</Button>
-            </FormItem>
-        </Form>
-    </div>
-</template>
-
-<script>
-    import '@/utils/Math.uuid'
-    export default {
-        props: ['blockData', 'pointData', 'hideBlock', 'addType', 'schoolParams'],
-        data() {
-            return {
-                blockDatas: null,
-                currentPeriod: {},
-                currentPoint: null,
-                schoolInfos: {},
-                addPointType: 'school',
-                isHideBlock: false,
-                isLoading: false,
-                uuid: '',
-                formTop: {
-                    blockName: '',
-                    name: ''
-                }
-            }
-        },
-
-        created() {
-            this.isHideBlock = this.hideBlock
-        },
-        methods: {
-            // 提交添加
-            handleAddPointSubmit() {
-                let newName = this.formTop.name
-                if (!newName) {
-                    this.$Message.warning('知识点名称不能为空!')
-                } else {
-                    let editPointItem = this.currentPoint
-                    this.isLoading = true
-                    this.uuid = Math.uuid()
-					console.log(this.schoolInfos)
-                    let params = {
-                        type: 1,
-                        name: newName,
-                        alias: newName,
-                        subjectId: editPointItem ? editPointItem.subjectId : this.schoolInfos.subjectId,
-                        code: this.addPointType === 'school' ? this.schoolInfos.schoolCode : this.$store.state.userInfo.TEAMModelID, // //判断当前添加为校本或者个人知识点
-                        order: 706,
-                        status: 1,
-                        knowledgeId: editPointItem ? editPointItem.knowledgeId : this.uuid,
-                        periodId: editPointItem ? editPointItem.periodId : this.schoolInfos.period,
-                        source: 1,
-                        points: this.blockDatas ? [this.blockDatas.id] : [],
-                        id: editPointItem ? editPointItem.id : null,
-                    }
-					console.log(params)
-                    this.savePointAndBlock(params)
-                }
-            },
-
-            /**
-             * 保存知识点
-             * @param pointItem
-             * @param BlockItem
-             */
-            savePointAndBlock(pointItem) {
-                this.$api.knowledge.SaveOrUpdateKnowledge([pointItem]).then(res => {
-                    if (!res.error && res.knowledges.length) {
-                        this.$emit('addFinish', res.knowledges[0])
-                        this.closeModal()
-                        this.currentPoint = null
-                        this.formTop.name = ''
-                        this.isLoading = false
-                    } else {
-                        this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-                    }
-                }).catch(err => {
-                    console.log(err)
-                    this.$Message.warning('操作失败')
-                })
-				this.isLoading = false
-            },
-
-            // 添加完成 关闭窗口
-            closeModal() {
-                this.formTop.name = ''
-            }
-        },
-        mounted() {
-        },
-        watch: {
-            addType: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.addPointType = newValue
-                    }
-                }
-            },
-
-            hideBlock: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.isHideBlock = newValue
-                    }
-                }
-            },
-
-            blockData: {
-                handler(newValue, oldValue) {
-                    this.blockDatas = newValue
-                    console.log(newValue)
-                    if (newValue) {
-                        this.formTop.blockName = newValue.name
-                    }
-                }
-            },
-
-            pointData: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.currentPoint = newValue
-                        this.formTop.name = newValue.name
-                    }
-                }
-            },
-
-            schoolParams: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-						console.log(newValue)
-                        this.schoolInfos = newValue
-                    }
-                }
-            }
-        }
-
-    }
-</script>
-
-<style>
-    .form-container .ivu-form .ivu-form-item-label {
-        color: #fff;
-        margin: 10px 0;
-        font-size: 16px;
-    }
-
-    .form-container .ivu-input {
-        background: #575757;
-        border-color: transparent;
-        height: 35px;
-        color: #fff;
-    }
-
-        .form-container .ivu-input::-webkit-input-placeholder {
-            color: #808080;
-        }
-
-    .form-container .ivu-select-single .ivu-select-selection {
-        background: #575757;
-        color: #fbfbfb;
-        border-color: transparent;
-        height: 35px;
-    }
-
-    .form-container .ivu-select-single .ivu-select-arrow {
-        color: #fbfbfb;
-    }
-
-    .form-container .ivu-btn {
-        width: 100%;
-        height: 40px;
-        background: rgb(11, 151, 117);
-        border: none;
-        color: #fff;
-    }
-</style>

+ 0 - 280
TEAMModelOS/ClientApp/src/view/knowledge-pointBankup/index/operation/ComposeBlock.vue

@@ -1,280 +0,0 @@
-
-<template>
-    <div class="compose-container">
-        <Tabs value="0" @on-click="onTabChange">
-            <TabPane label="新增知识块" icon="md-folder" name="0">
-                <div class="tab-content">
-                    <p class="tab-title">添加知识块</p>
-                    <Input v-model="newBlockName" placeholder="输入知识块名称" style="width: 98%;margin-left:1%" />
-                </div>
-            </TabPane>
-            <TabPane label="现有知识块" icon="md-cube" name="1">
-                <div class="tab-content">
-                    <p class="tab-title">选择知识块 ( *若所选知识块内已存在添加的知识点则会覆盖 )</p>
-                    <Select v-model="selectBlock" transfer style="width: 98%;margin-left:1%">
-                        <Option v-for="item in existBlockList" :value="item.id" :key="item.id">{{ item.name }}</Option>
-                    </Select>
-                </div>
-            </TabPane>
-        </Tabs>
-
-        <div class="show-wrap">
-            <p class="tab-title">已选知识点</p>
-            <div class="show-list">
-                <span class="point-item" v-for="(item,index) in checkedList" :key="index">
-                {{ item.name }}
-                    <span class="btn-delete"><Icon type="ios-close" size="20" style="vertical-align:bottom;margin-left:5px" @click="onSplicePoint(item)" /></span>
-                </span>
-            </div>
-        </div>
-
-        <Button @click="currentTab === '0' ? handleSubmitNew() : handleSubmit()" :loading="isLoading">确认</Button>
-    </div>
-</template>
-
-<script>
-    import '@/utils/Math.uuid'
-    export default {
-        props: ['list', 'params', 'blockList'],
-        data() {
-            return {
-                existBlockList: [],
-                checkedList: [],
-                currentParams: null,
-                newBlockName: '',
-                isLoading: false,
-                selectBlock: '',
-                currentTab: '0'
-            }
-        },
-
-        created() {
-            this.currentParams = this.params
-        },
-        methods: {
-
-            // 面板切换事件
-            onTabChange(name) {
-                this.currentTab = name
-            },
-
-            // 提交新增知识块
-            handleSubmitNew() {
-                this.isLoading = true
-                if (this.newBlockName) {
-                    let list = this.existBlockList.map(item => item.name)
-                    let isExistIndex = list.indexOf(this.newBlockName)
-                    if (isExistIndex > -1) {
-                        this.$Message.warning('已存在同名知识块,请修改名称!')
-                        this.isLoading = false
-                    } else {
-                        let params = {
-                            type: 0,
-                            name: this.newBlockName,
-                            alias: this.newBlockName,
-                            subjectId: this.currentParams.subjectId,
-                            code: this.currentParams.code.replace('Knowledge-',''),
-                            order: 706,
-                            status: 1,
-                            knowledgeId: Math.uuid(),
-                            periodId: this.currentParams.periodId,
-                            points: this.checkedList.map(item => item.id),
-                            TEAMModelId: this.$store.state.userInfo.TEAMModelID,
-                            source: 1
-                        }
-
-                        this.$api.knowledge.SaveOrUpdateKnowledge([params]).then(res => {
-                            if (!res.error && res.knowledges) {
-                                this.$emit('onFinish', false)
-                            } else {
-                                this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-                            }
-                            this.isLoading = false
-                        }).catch(err => {
-                            console.log(err)
-                            this.$Message.warning('操作失败')
-                            this.isLoading = false
-                        })
-                    }
-                } else {
-                    this.$Message.warning('知识块名称不能为空')
-                    this.isLoading = false
-                }
-            },
-
-            // 提交新增知识块
-            handleSubmit() {
-				if(this.existBlockList.length){
-					this.isLoading = true
-					let selectBlockItem = this.existBlockList.filter(item => item.id === this.selectBlock)[0]
-					let pointList = selectBlockItem.points
-					pointList = Array.from(new Set(pointList.concat(this.checkedList.map(item => item.id)))) // 知识点合并去重
-					selectBlockItem.points = pointList
-					
-					this.$api.knowledge.SaveOrUpdateKnowledge([selectBlockItem]).then(res => {
-					    if (!res.error && res.knowledges) {
-					        this.$emit('onFinish', false)
-					    } else {
-					        this.$Message.warning('操作失败,错误代码:' + res.error.code + ',错误信息:' + res.error.message)
-					    }
-					    this.isLoading = false
-					}).catch(err => {
-					    console.log(err)
-					    this.$Message.warning('操作失败')
-					    this.isLoading = false
-					})
-				}else{
-					this.$Message.warning('无现有知识块选择!')
-				}
-                
-            },
-
-            onSplicePoint(item) {
-                this.checkedList.splice(this.checkedList.indexOf(item), 1)
-            }
-        },
-        mounted() {
-
-        },
-        watch: {
-            list: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.checkedList = []
-                        this.checkedList = newValue
-                    }
-                }
-            },
-
-            params: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.currentParams = newValue
-                    }
-                }
-            },
-
-            blockList: {
-                handler(newValue, oldValue) {
-                    if (newValue) {
-                        this.newBlockName = ''
-                        this.existBlockList = newValue
-                        this.selectBlock = newValue.length ? newValue[0].id : ''
-                    }
-                }
-            }
-        }
-
-    }
-</script>
-
-<style>
-
-    /*修改iview Tab标签页样式重写*/
-    .compose-container .ivu-tabs-nav {
-        width:100%;
-    }
-
-     .compose-container .ivu-tabs {
-        height:100%;
-    }
-
-        .compose-container .ivu-tabs-nav .ivu-icon {
-            font-size:20px;
-            margin-right:15px;
-        }
-
-    .compose-container .ivu-tabs-nav .ivu-tabs-tab {
-        width:50%;
-        text-align:center;
-        color:#fff;
-        margin:0;
-        padding-bottom:20px;
-    }
-
-    .compose-container .ivu-tabs-bar {
-        border-bottom:none;
-    }
-
-    .compose-container .ivu-tabs-nav-container:focus .ivu-tabs-tab-focused {
-        border-color:rgb(11, 151, 117) !important;
-    }
-
-    .compose-container .ivu-tabs-ink-bar {
-        background:rgb(11, 151, 117) !important;
-        height:4px;
-        bottom:0;
-    }
-
-    .compose-container .ivu-tabs-content {
-        height:100%;
-    }
-
-    .compose-container .tab-content {
-        padding:30px;
-    }
-
-    .compose-container .tab-title {
-        color:#fff;
-        margin:10px 0 20px 5px;
-    }
-
-    .compose-container .tab-title::before {
-        content:"";
-        width:4px;
-        height:14px;
-        background:rgb(11, 151, 117);
-        margin:-2px 10px -2px 0;
-        display:inline-block;
-     }
-
-    .compose-container .ivu-input {
-        background: #575757;
-        border-color: transparent;
-        height: 35px;
-        color: #fff;
-    }
-
-    .compose-container .ivu-input::-webkit-input-placeholder {
-            color: #808080;
-    }
-
-    .compose-container .show-wrap{
-        padding:30px;
-    }
-
-    .compose-container .show-list {
-       display:flex;
-       flex-wrap:wrap;
-    }
-
-        .compose-container .show-list .point-item {
-            margin: 10px;
-            padding: 5px 30px;
-            border-radius: 50px;
-            background: #828282;
-            box-shadow: 1px 4px 0px 0px #313131;
-            cursor: pointer;
-        }
-
-    .compose-container .ivu-btn {
-        width: 92%;
-        margin-left:4%;
-        margin-bottom:20px;
-        height: 40px;
-        background: rgb(11, 151, 117);
-        border: none;
-        color: #fff;
-    }
-
-    .compose-container .ivu-select-single .ivu-select-selection {
-        background: #575757;
-        color: #fbfbfb;
-        border-color: transparent;
-        height: 35px;
-    }
-
-    .compose-container .ivu-select-single .ivu-select-arrow {
-        color: #fbfbfb;
-    }
-</style>

+ 3 - 2
TEAMModelOS/ClientApp/src/view/learnactivity/CreatePrivEva.vue

@@ -230,7 +230,8 @@ export default {
             },
             dateOpt1: {
                 disabledDate(date) {
-                    return _this.evaluationInfo.startTime && _this.evaluationInfo.startTime > date.valueOf() + 86400000
+                    let  d = _this.evaluationInfo.startTime ? _this.evaluationInfo.startTime : Date.now()
+                    return d && d > date.valueOf() + 86400000
                 }
             },
             courseList: [],
@@ -595,7 +596,7 @@ export default {
             if (flag == 0) {
                 this.startTime = value
                 this.evaluationInfo.startTime = new Date(value).getTime()
-                if (this.evaluationInfo.startTime > this.evaluationInfo.endTime) {
+                if (this.evaluationInfo.startTime >= this.evaluationInfo.endTime) {
                     this.endTime = undefined
                     this.evaluationInfo.endTime = undefined
                 }

+ 6 - 5
TEAMModelOS/ClientApp/src/view/learnactivity/CreateSchoolEva.vue

@@ -135,7 +135,8 @@ export default {
             },
             dateOpt1: {
                 disabledDate(date) {
-                    return _this.evaluationInfo.startTime && _this.evaluationInfo.startTime > date.valueOf() + 86400000
+                    let  d = _this.evaluationInfo.startTime ? _this.evaluationInfo.startTime : Date.now()
+                    return d && d > date.valueOf() + 86400000
                 }
             },
             startTime: '',
@@ -165,9 +166,9 @@ export default {
                 'examType.id': [
                     { required: true, message: this.$t('learnActivity.createEv.errTips5'), trigger: 'change' }
                 ],
-                // targets: [
-                //     { required: true, message: this.$t('learnActivity.createEv.errTips6'), trigger: 'change' }
-                // ],
+                targets: [
+                    { required: true, message: this.$t('learnActivity.createEv.errTips6'), type: 'array', trigger: 'change' }
+                ],
                 publish: [
                     { required: true, message: this.$t('learnActivity.createEv.errTips7'), trigger: 'change' }
                 ],
@@ -178,7 +179,7 @@ export default {
                     { required: true, type: 'number', message: this.$t('learnActivity.createEv.errTips9'), trigger: 'change' }
                 ]
             },
-            activeTab: 'preview',
+            activeTab: 'manualPaper', //默认到试卷库
             curSubIndex: 0,
             evaluationInfo: {
                 name: '',

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

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

+ 3 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/MgtPrivEva.vue

@@ -461,4 +461,7 @@ export default {
         }
     }
 }
+.test-paper-detail .paper-container{
+    padding-bottom: 30px;
+}
 </style>

+ 3 - 0
TEAMModelOS/ClientApp/src/view/learnactivity/MgtSchoolEva.vue

@@ -503,4 +503,7 @@ export default {
         }
     }
 }
+.test-paper-detail .paper-container{
+    padding-bottom: 30px;
+}
 </style>

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

@@ -106,7 +106,7 @@
     margin-top: 10px;
     font-size: 14px;
     padding: 0px;
-    min-height: 85px;
+    min-height: 90px;
 }
 
 .scoring-exercise-wrap .exercise-item p {
@@ -381,3 +381,7 @@
         }
     }
 
+
+    .paper-score-container .item-option-content, .item-question-flex, .child-item-question-flex {
+        display: flex;
+    }

+ 42 - 22
TEAMModelOS/ClientApp/src/view/learnactivity/PaperScore.vue

@@ -27,17 +27,22 @@
                     <Icon :type="showQu ? 'md-eye-off':'md-eye'" />
                     {{ showQu ? $t('learnActivity.score.hideQu') : $t('learnActivity.score.showQu')}}
                 </span>
+                <!-- <span class="base-info-btn" @click="isDefOrder = !isDefOrder">
+                    <Icon :type="isDefOrder ? 'md-reorder':'ios-keypad'" />
+                    {{isDefOrder ? '默认顺序' : '题型排序'}}
+                </span> -->
             </div>
+            <!-- 题号 -->
             <div class="question-index-box" v-if="studentAnswer.scores">
                 <div class="base-info-item" style="white-space: nowrap;">{{$t('learnActivity.score.quIndex')}}</div>
                 <div>
                     <span v-for="(typeItem,typeIndex) in groupList" :key="typeIndex">
                         <span v-for="(item,index) in typeItem.list" :key="index">
-                            <span @click="goToQuestion(getScoreIndex(typeIndex,index))" :class="studentAnswer.scores[getScoreIndex(typeIndex,index)] >= 0 ? 'qu-order-tag':'qu-order-tag-def'" v-if="typeItem.type !== 'compose'">
+                            <span @click="goToQuestion(getScoreIndex(typeIndex,index))" :class="studentAnswer.scores[item.index] >= 0 ? 'qu-order-tag':'qu-order-tag-def'" v-if="typeItem.type !== 'compose'">
                                 {{getQuIndex(typeIndex,index)}}
                             </span>
                             <span v-else>
-                                <span @click="goToQuestion(getScoreIndex(typeIndex,index,childIndex))" v-for="(childItem,childIndex) in item.children" :key="childIndex" :class="studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)] >= 0 ? 'qu-order-tag':'qu-order-tag-def'">
+                                <span @click="goToQuestion(getScoreIndex(typeIndex,index,childIndex))" v-for="(childItem,childIndex) in item.children" :key="childIndex" :class="studentAnswer.scores[childItem.index] >= 0 ? 'qu-order-tag':'qu-order-tag-def'">
                                     {{getQuIndex(typeIndex,index) + '-' + (childIndex + 1)}}
                                 </span>
                             </span>
@@ -48,6 +53,7 @@
         </div>
         <div class="qu-list-wrap scoring-exercise-wrap" ref="mathJaxContainer" v-show="!dataLoading">
             <!-- <vuescroll ref="question-scrool" > -->
+            <!-- 按题型排序 -->
             <div v-show="!isComplete" class="list-view" :key="'group'+ typeIndex" v-for="(typeItem,typeIndex) in groupList">
                 <p class="type-name">
                     {{ numberConvertToUppercase(getLatestTypeIndex(typeItem.type) + 1) }}
@@ -58,7 +64,7 @@
                     <!-- 非综合题-->
                     <div v-if="item.type != 'compose'" style="display:flex;width:100%;padding-top:15px;" :class="['not-compose-box', activeIndex == getScoreIndex(typeIndex,index) ? 'active-qu-wrap' : '']" :id="'qustion'+ getScoreIndex(typeIndex,index)" @click="activeIndex = getScoreIndex(typeIndex,index)">
                         <div class="scoring-input-box" @click.stop v-if="studentAnswer.scores && studentAnswer.scores.length">
-                            <InputNumber v-model="studentAnswer.scores[getScoreIndex(typeIndex,index)]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="item.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
+                            <InputNumber v-model="studentAnswer.scores[item.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="item.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                             <!-- 快速打分 满分 零分 -->
                             <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
                                 <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore((getScoreIndex(typeIndex,index)),item.score)">
@@ -89,7 +95,7 @@
                         </div>
                         <div class="qu-info-box">
                             <!-- 题干部分 -->
-                            <div class="item-question" v-show="showQu">
+                            <div class="item-question item-question-flex" v-show="showQu">
                                 <div class="item-question-order">{{ getQuIndex(typeIndex,index) }} .</div>
                                 <div class="item-question-text" v-html="item.question"></div>
                             </div>
@@ -111,19 +117,21 @@
                                 <!--学生作答答案显示区域-->
                                 <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">
                                     <!-- 批注 主观题才会有批注功能 -->
-                                    <div class="mark-btn-box" @click="markStuAnswer(getScoreIndex(typeIndex,index))" v-if="item.type !== 'single' && item.type !== 'multiple' && item.type !== 'judge'">
+                                    <div class="mark-btn-box" @click="markStuAnswer(item.index)" v-if="item.type !== 'single' && item.type !== 'multiple' && item.type !== 'judge'">
                                         <Icon type="md-create" />
                                         <span style="margin-left:5px;">{{$t('learnActivity.score.mark')}}</span>
                                     </div>
                                     <!--多选题答案-->
                                     <div v-if="item.type === 'multiple'" :id="'answer'+ getScoreIndex(typeIndex,index)">
-                                        <span v-for="(answerItem,answerIndex) in studentAnswer.answers[getScoreIndex(typeIndex,index)]" :key="'an'+ (answerIndex+index)" v-html="answerItem" style="display:inline;">
+                                        <!-- <span v-for="(answerItem,answerIndex) in studentAnswer.answers[getScoreIndex(typeIndex,index)]" :key="'an'+ (answerIndex+index)" v-html="answerItem" style="display:inline;">
+                                        </span> -->
+                                        <span v-for="(answerItem,answerIndex) in studentAnswer.answers[item.index]" :key="'an'+ (answerIndex+index)" v-html="answerItem" style="display:inline;">
                                         </span>
                                     </div>
                                     <!--其余题型答案-->
-                                    <div v-else-if="studentAnswer.answers[getScoreIndex(typeIndex,index)]" :id="'answer'+ getScoreIndex(typeIndex,index)">
+                                    <div v-else-if="studentAnswer.answers[item.index]" :id="'answer'+ getScoreIndex(typeIndex,index)">
                                         <div>
-                                            <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index)].join(',')"></span>
+                                            <span v-html="studentAnswer.answers[item.index].toString()"></span>
                                         </div>
                                     </div>
                                 </div>
@@ -176,13 +184,13 @@
                     </div>
                     <!-- 综合题 -->
                     <div v-else style="width:100%;" class="compose-box">
-                        <div class="item-question" style="margin-left:90px; margin-bottom:10px;" v-show="showQu">
-                            <div class="item-question-order">{{ getQuIndex(typeIndex,index)}} .</div>
+                        <div class="item-question item-question-flex" style="margin-left:90px; margin-top:20px;" v-show="showQu">
+                            <div class="item-question-order">{{ getQuIndex(typeIndex,index)}}.</div>
                             <div class="item-question-text" v-html="item.question"></div>
                         </div>
                         <div :class="['child-item', activeIndex == getScoreIndex(typeIndex,index,childIndex) ? 'active-qu-wrap' : '']" v-for="(childItem,childIndex) in item.children" :key="childIndex" style="padding-top:15px;" :id="'qustion'+getScoreIndex(typeIndex,index,childIndex)" @click="activeIndex = getScoreIndex(typeIndex,index,childIndex)">
                             <div class="scoring-input-box" @click.stop v-if="studentAnswer.scores && studentAnswer.scores.length">
-                                <InputNumber v-model="studentAnswer.scores[getScoreIndex(typeIndex,index,childIndex)]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="childItem.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
+                                <InputNumber v-model="studentAnswer.scores[childItem.index]" size="small" :formatter="value => value < 0 ? '' : `${value}${$t('learnActivity.score.scoreUnit')}`" :parser="value => value.replace($t('learnActivity.score.scoreUnit'), '')" :min="0" :max="childItem.score" :placeholder="$t('learnActivity.score.zeroScore1')" class="score-input" />
                                 <!-- 快速打分 满分 零分 -->
                                 <div style="display:flex;justify-content: space-evenly;margin-top:5px;">
                                     <span class="fast-score-tag" :title="$t('learnActivity.score.fullScore')" @click="fastSetScore((getScoreIndex(typeIndex,index,childIndex)),childItem.score)">
@@ -212,7 +220,7 @@
                                     </div> -->
                             </div>
                             <div class="qu-info-box">
-                                <div class="child-item-question" v-show="showQu">
+                                <div class="child-item-question child-item-question-flex" v-show="showQu">
                                     <span class="child-item-question-order">{{$t('learnActivity.score.sQuLabel1')}}{{ childIndex + 1 }}{{$t('learnActivity.score.sQuLabel2')}}</span>
                                     <p class="child-item-question-content" v-html="childItem.question"></p>
                                 </div>
@@ -234,18 +242,18 @@
                                     <!--学生作答答案显示区域-->
                                     <div class="stu-answer-box item-explain-details" v-if="studentAnswer.answers && studentAnswer.answers.length">
                                         <!-- 批注 主观题才会有批注功能 -->
-                                        <div class="mark-btn-box" @click="markStuAnswer(getScoreIndex(typeIndex,index,childIndex))" v-if="childItem.type !== 'single' && childItem.type !== 'multiple' && childItem.type !== 'judge'">
+                                        <div class="mark-btn-box" @click="markStuAnswer(childItem.index)" v-if="childItem.type !== 'single' && childItem.type !== 'multiple' && childItem.type !== 'judge'">
                                             <Icon type="md-create" />
                                             <span style="margin-left:5px;">{{$t('learnActivity.score.mark')}}</span>
                                         </div>
                                         <!--多选题答案-->
                                         <div v-if="childItem.type === 'multiple'" :id="'answer'+ getScoreIndex(typeIndex,index,childIndex)">
-                                            <span v-for="(answerItem,answerIndex) in studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)]" :key="'an'+ (index+answerIndex+childIndex)" v-html="answerItem" style="display:inline-block;"></span>
+                                            <span v-for="(answerItem,answerIndex) in studentAnswer.answers[childItem.index]" :key="'an'+ (index+answerIndex+childIndex)" v-html="answerItem" style="display:inline-block;"></span>
                                         </div>
                                         <!--其余题型答案-->
-                                        <div v-else-if="studentAnswer.answers[typeIndex + index + childIndex]" :id="'answer'+ getScoreIndex(typeIndex,index,childIndex)">
+                                        <div v-else-if="studentAnswer.answers[childItem.index]" :id="'answer'+ getScoreIndex(typeIndex,index,childIndex)">
                                             <div>
-                                                <span v-html="studentAnswer.answers[getScoreIndex(typeIndex,index,childIndex)].join(',')"></span><br />
+                                                <span v-html="studentAnswer.answers[childItem.index].toString()"></span><br />
                                             </div>
                                         </div>
                                     </div>
@@ -292,6 +300,8 @@
                     </div>
                 </div>
             </div>
+            <!-- 默认排序 -->
+            
             <!-- </vuescroll> -->
             <div v-show="isComplete" class="complete-score-box">
                 <Icon class="complete-icon" type="md-checkmark-circle" />
@@ -343,6 +353,7 @@ export default {
     },
     data() {
         return {
+            isDefOrder: false, //是否默认排序  默认/题型
             activeIndex: 0,
             curAnIndex: -1,
             markStatus: false,
@@ -465,7 +476,6 @@ export default {
         //快速定位题目
         goToQuestion(index) {
             this.activeIndex = index
-            console.log(index)
             this.$el.querySelector('#qustion' + index).scrollIntoView({
                 behavior: "smooth",  // 平滑过渡
                 block: "center"  // 上边框与视窗顶部平齐。默认值
@@ -585,14 +595,25 @@ export default {
         },
         paperInfo: {
             handler(newPaper) {
-                console.log('newPaper', newPaper)
+                console.log('试卷数据', newPaper)
                 if (newPaper && newPaper.item) {
                     this.dataLoading = true
                     let that = this
                     this.groupList = []
                     this.exerciseList = []
                     if (newPaper.item.length) {
-                        newPaper.item.forEach(i => {
+                        let index = 0
+                        newPaper.item.forEach((i) => {
+                            //记录题目原始位置
+                            if (i.type == 'compose') {
+                                i.children.forEach((cItem) => {
+                                    cItem.index = index
+                                    index++
+                                })
+                            } else {
+                                i.index = index
+                                index++
+                            }
                             if (!i.score) i.score = 0
                         })
                         /* 处理试卷内题目按照题型排序 */
@@ -607,7 +628,8 @@ export default {
                                     that.exerciseList = that.exerciseList.concat(value)
                                 }
                             })
-                        });
+                        })
+                        console.log('题型顺序', this.groupList)
                     }
                     this.dataLoading = false
                 }
@@ -616,7 +638,6 @@ export default {
         },
         studentAnswer: {
             async handler(newValue, oldValue) {
-                console.log('获取答案', JSON.stringify(newValue))
                 if (!this.studentAnswer.status) {
                     if (newValue.answers.length) {
                         try {
@@ -644,7 +665,6 @@ export default {
                             } else {
                                 this.$set(this.studentAnswer, 'answers', [])
                             }
-                            console.log(this.studentAnswer)
                         } catch (e) {
                             console.log('error', e)
                         }

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

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

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

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

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

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

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

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

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

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

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

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

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

@@ -9,12 +9,11 @@
             </div>
             <div class="editable time-zone-select" style="margin-left:100px;" @click.stop>
                 <span class="setting-title">{{$t('schoolBaseInfo.tmzLabel')}}</span>
-                <Select filterable v-model="schoolSetting.timeZone.value" label-in-value :style="{width: tzWidth+'px', verticalAlign:'baseline'}" :placeholder="$t('schoolBaseInfo.tmzHolder')">
-                    <Option v-for="(item,index) in timeZoneList" :value="item.value" :key="index" @click.native="setTimeZone(item)">{{ item.label }}</Option>
+                <Select filterable v-model="schoolSetting.timeZone.label" label-in-value :style="{width: tzWidth+'px', verticalAlign:'baseline'}" :placeholder="$t('schoolBaseInfo.tmzHolder')">
+                    <Option v-for="(item,index) in timeZoneList" :value="item.label" :key="index" @click.native="setTimeZone(item)">{{ item.label }}</Option>
                 </Select>
             </div>
             <Button v-if="$access.ability('admin','schoolSetting-upd').validateAll" class="school-tools" :loading="isLoading" :disabled="!updated" icon="ios-albums-outline" @click="saveData()">{{$t('schoolBaseInfo.saveInfo')}}</Button>
-
         </div>
         <div class="sm-system-body dark-iview-split disabled-iview-select text-cursor-disabled">
             <Split v-model="split1">
@@ -264,6 +263,69 @@ export default {
          * 初始化状态
          */
         initStatus() {
+            let isRep = false
+            let pdName = this.schoolSetting.period.map(item => {
+                return item.name
+            })
+            console.log(pdName)
+            // 检查学段名称
+            pdName.forEach((item, index) => {
+                if (pdName.indexOf(item) != index) {
+                    isRep = true
+                    this.$Message.warning(this.$t('schoolBaseInfo.pdWarning'))
+                }
+            })
+            if (isRep) return
+            let curPd = this.schoolSetting.period[this.curPriodIndex]
+
+            // 检查学期名称
+            let semName = curPd.semesters.map(item => {
+                return item.name
+            })
+            semName.forEach((item, index) => {
+                if (semName.indexOf(item) != index) {
+                    isRep = true
+                    this.$Message.warning(this.$t('schoolBaseInfo.semWarning'))
+                }
+            })
+            if (isRep) return
+
+            // 检查年级名称
+            let gradeName = curPd.grades.map(item => {
+                return item.name
+            })
+            gradeName.forEach((item, index) => {
+                if (gradeName.indexOf(item) != index) {
+                    isRep = true
+                    this.$Message.warning(this.$t('schoolBaseInfo.gdNameWarning'))
+                }
+            })
+            if (isRep) return
+
+            // 检查学科名称
+            let subName = curPd.subjects.map(item => {
+                return item.name
+            })
+            subName.forEach((item, index) => {
+                if (subName.indexOf(item) != index) {
+                    isRep = true
+                    this.$Message.warning(this.$t('schoolBaseInfo.subWarning'))
+                }
+            })
+            if (isRep) return
+
+            // 检查考试名称
+            let exName = curPd.analysis.type.map(item => {
+                return item.name
+            })
+            exName.forEach((item, index) => {
+                if (exName.indexOf(item) != index) {
+                    isRep = true
+                    this.$Message.warning(this.$t('schoolBaseInfo.exWarning'))
+                }
+            })
+            if (isRep) return
+
             this.delGraStatus = false
             this.delSubStatus = false
             this.delAnaStatus = false
@@ -393,7 +455,7 @@ export default {
         },
         //设置学校时区
         setTimeZone(item) {
-            this.schoolSetting.timeZone.label = item.label
+            this.schoolSetting.timeZone.value = item.value
             this.editTZStatsu = true
         },
 

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

@@ -304,6 +304,7 @@
 
             .el-filter-item {
                 margin-top: 10px;
+				display: flex;
 				
 				.ivu-radio-wrapper{
 					font-size: 12px !important;
@@ -313,7 +314,7 @@
                     font-size: 14px;
                     font-weight: 400;
                     margin-right: 20px;
-                    width: 70px;
+                    min-width: 70px;
                     text-align: end;
                     display: inline-block;
                     color: #e4eadb;

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

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

+ 1 - 1
TEAMModelOS/Controllers/Analysis/AnalysisController.cs

@@ -572,7 +572,7 @@ namespace TEAMModelOS.Controllers.Analysis
                 average = examResults.FirstOrDefault(c => c.id == x.id).average,
                 standard = examResults.FirstOrDefault(c => c.id == x.id).standard
             });
-            var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard };
+            var subAll = new { sRate = info.sRate, average = info.average, standard = info.standard,total = info.stuCount };
             return Ok(new
             {
                 students,

+ 128 - 18
TEAMModelOS/Controllers/School/CourseController.cs

@@ -22,6 +22,7 @@ using TEAMModelOS.SDK.Helper.Common.StringHelper;
 using System.Dynamic;
 using Azure;
 using TEAMModelOS.SDK.Models.Cosmos.Common;
+using Azure.Messaging.ServiceBus;
 
 namespace TEAMModelOS.Controllers
 {
@@ -35,12 +36,13 @@ namespace TEAMModelOS.Controllers
         private AzureCosmosFactory _azureCosmos;
         private readonly DingDing _dingDing;
         private readonly Option _option;
-
-        public CourseController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
+        private readonly AzureServiceBusFactory _serviceBus;
+        public CourseController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option , AzureServiceBusFactory serviceBus)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _option = option?.Value;
+            _serviceBus = serviceBus;
         }
 
         /// <summary>
@@ -191,35 +193,144 @@ namespace TEAMModelOS.Controllers
                 var client = _azureCosmos.GetCosmosClient();
                 string originCode = stuList.code;
                 stuList.code = stuList.pk + "-" + stuList.code;
+              
                 if (scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase))
                 {
-                    if (stuList.students.IsNotEmpty()) {
-                        var query = $"SELECT distinct value(c)  FROM c    where  c.id='{stuList.id}'";
-                        List<StuList> odlStus = new List<StuList>();
-                        await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: query,
-                                requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{originCode}") }))
+                    StuListChange change = new StuListChange() { 
+                        scope=$"{scope}",
+                        originCode= originCode
+                    };
+                    var query = $"SELECT distinct value(c)  FROM c    where  c.id='{stuList.id}'";
+                    List<StuList> odlStus = new List<StuList>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<StuList>(queryText: query,
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList-{originCode}") }))
+                    {
+                        odlStus.Add(item);
+                    }
+                    if (odlStus.Count > 0) 
+                    {
+                        if (stuList.students.IsNotEmpty())
                         {
-                            odlStus.Add(item);
+
+                            if (  odlStus[0].students.IsNotEmpty())
+                            {
+                                StuList oldStu = odlStus[0];
+                                foreach (var stu in stuList.students)
+                                {
+                                    bool flag = false;
+                                    //判断新增名单成员不在已经存在的名单
+                                    foreach (var old in oldStu.students)
+                                    {
+                                        if (old.id == stu.id && old.code == stu.code)
+                                        {
+                                            flag = true;
+                                        }
+                                    }
+                                    if (flag == false)
+                                    {
+                                        change.stujoin.Add(stu);
+                                    }
+                                }
+                            }
                         }
-                        if (odlStus.Count > 0 && odlStus[0].students.IsNotEmpty())
+                        if (stuList.tmids.IsNotEmpty())
                         {
-                            StuList oldStu = odlStus[0];
-                            foreach (var stu in oldStu.students) {
-                                stuList.students.ForEach(x => { 
-                                  //  x.id
-                                });
+                            if (  odlStus[0].tmids.IsNotEmpty())
+                            {
+                                StuList oldStu = odlStus[0];
+                                foreach (var tmdid in stuList.tmids)
+                                {
+                                    bool flag = false;
+                                    //判断新增名单成员不在已经存在的名单
+                                    foreach (var old in oldStu.tmids)
+                                    {
+                                        if (old == tmdid)
+                                        {
+                                            flag = true;
+                                        }
+                                    }
+                                    if (flag == false)
+                                    {
+                                        change.tmdjoin.Add(tmdid);
+                                    }
+                                }
                             }
                         }
+                        var messageChange = new ServiceBusMessage(change.ToJsonString());
+                        messageChange.ApplicationProperties.Add("name", "StuList");
+                        await _serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageChange);
                     }
-                    
-                   stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{originCode}"));
+                    stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").UpsertItemAsync(stuList, new PartitionKey($"StuList-{originCode}"));
                 }
                 else
                 {
+                    StuListChange change = new StuListChange()
+                    {
+                        scope = $"{scope}",
+                        originCode = originCode
+                    };
+                    var query = $"SELECT distinct value(c)  FROM c    where  c.id='{stuList.id}'";
+                    List<StuList> odlStus = new List<StuList>();
+                    await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StuList>(queryText: query,
+                            requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"StuList") }))
+                    {
+                        odlStus.Add(item);
+                    }
+                    if (odlStus.Count>0) {
+                        if (stuList.students.IsNotEmpty())
+                        {
+
+                            if (  odlStus[0].students.IsNotEmpty())
+                            {
+                                StuList oldStu = odlStus[0];
+                                foreach (var stu in stuList.students)
+                                {
+                                    bool flag = false;
+                                    //判断新增名单成员不在已经存在的名单
+                                    foreach (var old in oldStu.students)
+                                    {
+                                        if (old.id == stu.id && old.code == stu.code)
+                                        {
+                                            flag = true;
+                                        }
+                                    }
+                                    if (flag == false)
+                                    {
+                                        change.stujoin.Add(stu);
+                                    }
+                                }
+                            }
+                        }
+                        if (stuList.tmids.IsNotEmpty())
+                        {
+                            if (  odlStus[0].tmids.IsNotEmpty())
+                            {
+                                StuList oldStu = odlStus[0];
+                                foreach (var tmdid in stuList.tmids)
+                                {
+                                    bool flag = false;
+                                    //判断新增名单成员不在已经存在的名单
+                                    foreach (var old in oldStu.tmids)
+                                    {
+                                        if (old == tmdid)
+                                        {
+                                            flag = true;
+                                        }
+                                    }
+                                    if (flag == false)
+                                    {
+                                        change.tmdjoin.Add(tmdid);
+                                    }
+                                }
+                            }
+                        }
+                        var messageChange = new ServiceBusMessage(change.ToJsonString());
+                        messageChange.ApplicationProperties.Add("name", "StuList");
+                        await _serviceBus.GetServiceBusClient().SendMessageAsync("active-task", messageChange);
+                    }
                     stuList.code = "StuList";
                     stuList = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync(stuList, new PartitionKey($"StuList"));
                 }
-
                 return Ok(new { stuList });
             }
             catch (Exception ex)
@@ -227,7 +338,6 @@ namespace TEAMModelOS.Controllers
                 await _dingDing.SendBotMsg($"OS,{_option.Location},course/upsert-list()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
                 return BadRequest();
             }
-
         }
 
         //查询名单

+ 50 - 0
TEAMModelOS/Controllers/School/StudentCommonController.cs

@@ -1,3 +1,4 @@
+using Azure.Cosmos;
 using Microsoft.AspNetCore.Authorization;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
@@ -55,5 +56,54 @@ namespace TEAMModelOS.Controllers
             (List<StuActivity> datas, string continuationToken) = await ActivityStudentService.FindActivity(request, id, school, _azureCosmos, _azureRedis);
             return Ok(new { datas, continuationToken });
         }
+        /// <summary>
+        /// 查询活动所有活动类型的列表,学生端
+        /// </summary>
+        /// <param name="request">
+        /// userid
+        /// school
+        /// </param>
+        /// 
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("stu-course")]
+        // [AuthToken(Roles = "student")]
+        public async Task<IActionResult> StuCourse(JsonElement request)
+        {
+            var (id, name, pic, school) = HttpContext.GetAuthTokenInfo();
+            if (string.IsNullOrWhiteSpace(id))
+            {
+                if (request.TryGetProperty("userid", out JsonElement userid))
+                {
+                    if (!userid.ValueKind.Equals(JsonValueKind.Undefined) && !userid.ValueKind.Equals(JsonValueKind.Null) && userid.ValueKind.Equals(JsonValueKind.String))
+                    {
+                        id = userid.GetString();
+                    }
+                }
+            }
+            if (string.IsNullOrWhiteSpace(school))
+            {
+                if (request.TryGetProperty("school", out JsonElement schooljson)) {
+                    if (!schooljson.ValueKind.Equals(JsonValueKind.Undefined) && !schooljson.ValueKind.Equals(JsonValueKind.Null) && schooljson.ValueKind.Equals(JsonValueKind.String))
+                    {
+                        school = schooljson.GetString();
+                    }
+                }
+               
+            }
+            string containerId = "Teacher";
+            string PartitionKey = $"StuCourse-{id}";
+            if (!string.IsNullOrEmpty(school)) {
+                  containerId = "Student";
+                  PartitionKey = $"StuCourse-{school}-{id}";
+            }
+            List<StuCourse> stus = new List<StuCourse>();
+            await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", containerId).GetItemQueryIterator<StuCourse>(queryText: $"select value(c) from c ",
+              requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey(PartitionKey) }))
+            {
+                stus.Add(item);
+            }
+            return Ok(new { course=stus });
+        }
     }
 }

+ 17 - 7
TEAMModelOS/Services/Common/ActivityStudentService.cs

@@ -225,19 +225,29 @@ namespace TEAMModelOS.Services.Common
 
             if (string.IsNullOrWhiteSpace(id))
             {
-                id = request.GetProperty("userid").GetString();
-            }
-            if (string.IsNullOrWhiteSpace(school))
-            {
-                school = request.GetProperty("school").GetString();
+                if (request.TryGetProperty("userid", out JsonElement userid))
+                {
+                    if (!userid.ValueKind.Equals(JsonValueKind.Undefined) && !userid.ValueKind.Equals(JsonValueKind.Null) && userid.ValueKind.Equals(JsonValueKind.String))
+                    {
+                        id = userid.GetString();
+                    }
+                }
             }
+
+
             if (string.IsNullOrWhiteSpace(school))
             {
-                school = request.GetProperty("school").GetString();
+                if (request.TryGetProperty("school", out JsonElement schooljson))
+                {
+                    if (!schooljson.ValueKind.Equals(JsonValueKind.Undefined) && !schooljson.ValueKind.Equals(JsonValueKind.Null) && schooljson.ValueKind.Equals(JsonValueKind.String))
+                    {
+                        school = schooljson.GetString();
+                    }
+                }
             }
+
             /// tmdid, schoolid
             var userType = "tmdid";
-
             if (request.TryGetProperty("userType", out JsonElement usertype))
             {
                 if (!usertype.ValueKind.Equals(JsonValueKind.Undefined) && !usertype.ValueKind.Equals(JsonValueKind.Null) && usertype.ValueKind.Equals(JsonValueKind.String))