Browse Source

Merge branch 'develop3.0' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0

CrazyIter 4 years ago
parent
commit
db0c50bd04
28 changed files with 1227 additions and 500 deletions
  1. 104 0
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs
  2. 48 0
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactory.cs
  3. 22 0
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactoryExtensions.cs
  4. 14 0
      TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactoryOptions.cs
  5. 0 74
      TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusClientSingleton.cs
  6. 0 39
      TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusCollectionExtensions.cs
  7. 0 29
      TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusOptions.cs
  8. 0 32
      TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusService.cs
  9. 0 24
      TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusServiceBuilder.cs
  10. 0 13
      TEAMModelOS.SDK/Module/AzureServiceBus/IAzureServiceBusService.cs
  11. 1 1
      TEAMModelOS.SDK/TEAMModelOS.SDK.csproj
  12. 50 0
      TEAMModelOS/ClientApp/src/api/forgetPW.js
  13. 2 0
      TEAMModelOS/ClientApp/src/api/index.js
  14. 41 42
      TEAMModelOS/ClientApp/src/api/regist.js
  15. 9 0
      TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.less
  16. 61 42
      TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.vue
  17. 40 23
      TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.vue
  18. 297 0
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.less
  19. 20 39
      TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.vue
  20. 13 0
      TEAMModelOS/ClientApp/src/router/routes.js
  21. 1 1
      TEAMModelOS/ClientApp/src/utils/countryCodeData.js
  22. 14 0
      TEAMModelOS/ClientApp/src/view/forgotPw/Index.less
  23. 297 0
      TEAMModelOS/ClientApp/src/view/forgotPw/Index.vue
  24. 76 81
      TEAMModelOS/ClientApp/src/view/learnactivity/ManageEvaluation.vue
  25. 1 1
      TEAMModelOS/ClientApp/src/view/login/Index.vue
  26. 0 2
      TEAMModelOS/ClientApp/src/view/regist/Index.vue
  27. 10 1
      TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.less
  28. 106 56
      TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.vue

+ 104 - 0
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusExtensions.cs

@@ -0,0 +1,104 @@
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Azure.Cosmos.Table.Queryable;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+using Azure.Messaging.ServiceBus;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureServiceBusExtensions
+    {
+        /// <summary>
+        /// 發送信息至對列或主題
+        /// </summary>       
+        /// <param name="pathName">QueueName or TopicName</param>
+        /// <param name="message">訊息</param>
+        /// <returns></returns>
+        public static async Task SendMessageAsync(this ServiceBusClient client, string pathName, string message)
+        {
+            try
+            {
+                ServiceBusSender sender = client.CreateSender(pathName);
+                await sender.SendMessageAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes(message)));
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// 批量發送訊息至對列或主題,如果批量失敗返回False
+        /// </summary>       
+        /// <param name="pathName">QueueName or TopicName</param>
+        /// <param name="messages">批量訊息</param>
+        /// <returns></returns>
+        public static async Task<bool> SendBatchMessageAsync(this ServiceBusClient client, string pathName, IList<string> messages)
+        {
+            try
+            {
+                ServiceBusSender sender = client.CreateSender(pathName);
+                ServiceBusMessageBatch messageBatch = await sender.CreateMessageBatchAsync();
+                foreach (var msg in messages)
+                {
+                    if (!messageBatch.TryAddMessage(new ServiceBusMessage(Encoding.UTF8.GetBytes(msg)))) return false;
+                }
+                await sender.SendMessagesAsync(messageBatch);
+                return true;
+            }
+            catch
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// 發送信息至對列或主題(指定時間排程)
+        /// </summary>       
+        /// <param name="pathName">QueueName or TopicName</param>
+        /// <param name="message">訊息</param>
+        /// <returns>排程訊息的序列號。</returns>
+        public static async Task<long> SendScheduleMessageAsync(this ServiceBusClient client, string pathName, string message, DateTimeOffset scheduleTime)
+        {
+            try
+            {
+                ServiceBusSender sender = client.CreateSender(pathName);
+                return await sender.ScheduleMessageAsync(new ServiceBusMessage(Encoding.UTF8.GetBytes(message)), scheduleTime);
+            }
+            catch
+            {
+                throw;
+            }
+        }
+
+        /// <summary>
+        /// 批量發送訊息至對列或主題(指定時間排程),如果批量失敗返回False
+        /// </summary>       
+        /// <param name="pathName">QueueName or TopicName</param>
+        /// <param name="messages">批量訊息</param>
+        /// <returns>排程訊息的序列號</returns>
+        public static async Task<long[]> SendScheduleMessagesAsync(this ServiceBusClient client, string pathName, IList<string> messages, DateTimeOffset scheduleTime)
+        {
+            try
+            {
+                ServiceBusSender sender = client.CreateSender(pathName);
+                List<ServiceBusMessage> msgs = new List<ServiceBusMessage>() { };
+                foreach (var msg in messages)
+                {
+                    msgs.Add(new ServiceBusMessage(Encoding.UTF8.GetBytes(msg)));
+                }
+                return await sender.ScheduleMessagesAsync(msgs, scheduleTime);
+            }
+            catch
+            {
+                return null;
+            }
+        }
+    }
+}

+ 48 - 0
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactory.cs

@@ -0,0 +1,48 @@
+
+using Microsoft.Azure.Cosmos.Table;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.Extensions.DependencyInjection;
+using Azure.Storage.Blobs;
+using Azure.Storage.Blobs.Models;
+using Azure.Storage.Blobs.Specialized;
+using StackExchange.Redis;
+using System.Collections.Concurrent;
+using Azure.Messaging.ServiceBus;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureServiceBusFactory
+    {
+        private readonly IServiceProvider _services;
+        private readonly IOptionsMonitor<AzureServiceBusFactoryOptions> _optionsMonitor;
+        private readonly ILogger _logger;
+        private ConcurrentDictionary<string, ServiceBusClient> ServiceBusClients { get; } = new ConcurrentDictionary<string, ServiceBusClient>();
+        public AzureServiceBusFactory(IServiceProvider services, IOptionsMonitor<AzureServiceBusFactoryOptions> optionsMonitor, ILogger<AzureServiceBusFactory> logger)
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));
+            if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
+
+            _services = services;
+            _optionsMonitor = optionsMonitor;
+            _logger = logger;            
+        }
+
+        public ServiceBusClient GetServiceBusClient(string name = "Default")
+        {           
+            try
+            {
+                var client = ServiceBusClients.GetOrAdd(name, x => new ServiceBusClient(_optionsMonitor.Get(name).ServiceBusConnectionString));               
+                return client;
+            }
+            catch (OptionsValidationException e)
+            {
+                _logger?.LogWarning(e, e.Message);
+                return null;
+            }
+        }       
+    }
+}

+ 22 - 0
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactoryExtensions.cs

@@ -0,0 +1,22 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public static class AzureServiceBusFactoryExtensions
+    {
+        public static IServiceCollection AddAzureServiceBus(this IServiceCollection services, string connectionString, string name = "Default")
+        {
+            if (services == null) throw new ArgumentNullException(nameof(services));            
+            if (connectionString == null) throw new ArgumentNullException(nameof(connectionString));
+
+            services.TryAddSingleton<AzureServiceBusFactory>();
+            services.Configure<AzureServiceBusFactoryOptions>(name, o => { o.Name = name; o.ServiceBusConnectionString = connectionString; });
+
+            return services;
+        }
+    }
+}

+ 14 - 0
TEAMModelOS.SDK/DI/AzureServiceBus/AzureServiceBusFactoryOptions.cs

@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.DI
+{
+    public class AzureServiceBusFactoryOptions
+    {
+        public string Name { get; set; }
+        public string ServiceBusConnectionString { get; set; }
+    }
+
+   
+}

+ 0 - 74
TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusClientSingleton.cs

@@ -1,74 +0,0 @@
-using Microsoft.Azure.ServiceBus;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureServiceBus
-{
-    public  class AzureServiceBusClientSingleton
-    {
-
-        private ServiceBusModel ServiceBusModel;
-        public static AzureServiceBusOptions azureServiceBusOptions;
-        private AzureServiceBusClientSingleton() { }
-        public ServiceBusModel GetServiceBusClient()
-        {
-            if (ServiceBusModel != null)
-            {
-                return ServiceBusModel;
-            }
-            else
-            {
-                getInstance(azureServiceBusOptions);
-                return ServiceBusModel;
-            }
-        }
-        public static AzureServiceBusClientSingleton getInstance(AzureServiceBusOptions _azureServiceBusOptions)
-        {
-            azureServiceBusOptions= _azureServiceBusOptions;
-          
-         
-            return SingletonInstance.instance;
-        }
-
-        private static class SingletonInstance
-        {
-            public static AzureServiceBusClientSingleton instance = new AzureServiceBusClientSingleton()
-            {
-                ServiceBusModel = new ServiceBusModel { topClients = GetTopClients(),subClients=GetSubClients() }
-            };
-        }
-
-        private static Dictionary<string, TopClient> GetTopClients() {
-            Dictionary<string, TopClient> topClients = new Dictionary<string, TopClient>();
-            string ConnectionString = azureServiceBusOptions.ConnectionString;
-            azureServiceBusOptions.Topics.ForEach(x=> { topClients.TryAdd(x.Name, new TopClient { topicClient = new TopicClient(ConnectionString, x.Name) }); });
-            return topClients;
-        }
-        private static Dictionary<string, SubClient> GetSubClients()
-        {
-            Dictionary<string, SubClient>  subClients = new Dictionary<string, SubClient>();
-            string ConnectionString = azureServiceBusOptions.ConnectionString;
-            azureServiceBusOptions.Topics.ForEach(x => { x.Subscribe.ForEach(y => { subClients.TryAdd(y, new SubClient { topName = x.Name, subscriptionClient = new SubscriptionClient(ConnectionString, x.Name, y) }); }); });
-            return subClients;
-        }
-    }
-
-
-    public class ServiceBusModel {
-       public Dictionary<string, TopClient> topClients { get; set; } = new Dictionary<string, TopClient>();
-        public Dictionary<string, SubClient> subClients { get; set; } = new Dictionary<string, SubClient>();
-       
-    }
-
-    public class TopClient { 
-       
-        public ITopicClient topicClient { get; set; }
-    }
-    public class SubClient
-    {
-        public string topName { get; set; }
-       
-        public ISubscriptionClient subscriptionClient { get; set; }
-    }
-}

+ 0 - 39
TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusCollectionExtensions.cs

@@ -1,39 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Module.AzureServiceBus;
-
-namespace TEAMModelOS.SDK
-{
-    public static class AzureServiceBusCollectionExtensions
-    {
-
-        private static AzureServiceBusServiceBuilder AddServiceBusBuilder(this IServiceCollection services)
-        {
-            return new AzureServiceBusServiceBuilder(services);
-        }
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        /// <returns></returns>
-        public static AzureServiceBusServiceBuilder AddServiceBus(this IServiceCollection services)
-        {
-            var builder = services.AddServiceBusBuilder();
-            services.AddSingleton<IAzureServiceBusService, AzureServiceBusService>();
-            return builder;
-        }
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="builder"></param>
-        /// <param name="_connectionString"></param>
-        /// <returns></returns>
-        public static AzureServiceBusServiceBuilder AddServiceBusOptions(this AzureServiceBusServiceBuilder builder, AzureServiceBusOptions serviceBusOptions)
-        {
-            builder.Services.AddSingleton(serviceBusOptions);
-            return builder;
-        }
-    }
-}

+ 0 - 29
TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusOptions.cs

@@ -1,29 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureServiceBus
-{
-    /// <summary>
-    /// 主题配置信息
-    /// </summary>
-    public  class AzureServiceBusOptions
-    {
-        public string ConnectionString { get; set; } = null;
-        public List<Topic> Topics { get; set; } = null;
-       
-    }
-    /// <summary>
-    /// 主题
-    /// </summary>
-    public class Topic { 
-        /// <summary>
-        /// 主题名称
-        /// </summary>
-        public string Name { get; set; }
-        /// <summary>
-        /// 主题的订阅器
-        /// </summary>
-        public List<string> Subscribe { get; set; }
-    }
-}

+ 0 - 32
TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusService.cs

@@ -1,32 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureServiceBus
-{
-    public class AzureServiceBusService :IAzureServiceBusService
-    {
-        public ServiceBusModel serviceBusModel;
-
-        public AzureServiceBusService(AzureServiceBusOptions options) {
-            serviceBusModel = AzureServiceBusClientSingleton.getInstance(options).GetServiceBusClient() ;
-        }
-
-
-        public void init() {
-            if (serviceBusModel != null) {
-                
-            }
-        }
-        public TopClient GetTopClient(string TopName) {
-            serviceBusModel.topClients.TryGetValue(TopName, out TopClient topClient);
-            return topClient;
-        }
-
-        public SubClient GetSubClient(string SubName)
-        {
-            serviceBusModel.subClients.TryGetValue(SubName, out SubClient subClient);
-            return subClient;
-        }
-    }
-}

+ 0 - 24
TEAMModelOS.SDK/Module/AzureServiceBus/AzureServiceBusServiceBuilder.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureServiceBus
-{
-    public class AzureServiceBusServiceBuilder
-    {
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="services"></param>
-        public AzureServiceBusServiceBuilder(IServiceCollection services)
-        {
-            Services = services ?? throw new ArgumentNullException(nameof(services));
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        public IServiceCollection Services { get; }
-    }
-}

+ 0 - 13
TEAMModelOS.SDK/Module/AzureServiceBus/IAzureServiceBusService.cs

@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Module.AzureServiceBus
-{
-    public interface IAzureServiceBusService
-    {
-        public TopClient GetTopClient(string TopName);
-        public SubClient GetSubClient(string SubName);
-        void init();
-    }
-}

+ 1 - 1
TEAMModelOS.SDK/TEAMModelOS.SDK.csproj

@@ -20,6 +20,7 @@
   <ItemGroup>
   <ItemGroup>
     <PackageReference Include="AspectCore.Extensions.Reflection" Version="2.1.0" />
     <PackageReference Include="AspectCore.Extensions.Reflection" Version="2.1.0" />
     <PackageReference Include="Azure.Cosmos" Version="4.0.0-preview3" />
     <PackageReference Include="Azure.Cosmos" Version="4.0.0-preview3" />
+    <PackageReference Include="Azure.Messaging.ServiceBus" Version="7.0.0-preview.4" />
     <PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.2.1" />
     <PackageReference Include="Azure.Storage.Blobs.Batch" Version="12.2.1" />
     <PackageReference Include="Azure.Storage.Queues" Version="12.3.2" />
     <PackageReference Include="Azure.Storage.Queues" Version="12.3.2" />
     <PackageReference Include="ClouDASLibx" Version="1.1.4" />
     <PackageReference Include="ClouDASLibx" Version="1.1.4" />
@@ -37,7 +38,6 @@
     <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
     <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.2.2" />
     <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
     <PackageReference Include="Microsoft.AspNetCore.JsonPatch" Version="3.1.6" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
     <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.6" />
-    <PackageReference Include="Microsoft.Azure.ServiceBus" Version="4.1.3" />
     <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
     <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
     <PackageReference Include="Microsoft.Extensions.Configuration" Version="3.1.6" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />
     <PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="3.1.6" />

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

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

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

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

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

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

+ 9 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.less

@@ -85,4 +85,13 @@
             margin-left: 5px;
             margin-left: 5px;
         }
         }
     }
     }
+
+    .student-list {
+        display: block;
+        padding: 10px;
+    }
+
+    .search-box{
+        height:6%;
+    }
 }
 }

+ 61 - 42
TEAMModelOS/ClientApp/src/components/learnactivity/ClassList.vue

@@ -1,30 +1,29 @@
 <template>
 <template>
     <div class="content">
     <div class="content">
-            <div class="class-list">
-                <div class="activity-target-header">
-                    <span>测试科目</span>
-                </div>
-                <div @click="selectActivity(index)" v-for="(item,index) in activityList" :class="index == currentActivityIndex ? 'activity-target-item block-bg block-bg-active':'block-bg activity-target-item'">
-                    <p class="target-name">
-                        {{item.classroomName}}
-                        <span class="activity-status">进行中</span>
-                    </p>
-                    <p style="margin-top:6px;">
-                        <span class="info-label"><Icon type="md-flag" style="margin-right:5px;" size="16" />测试类型:</span>
-                        <span class="info-value">{{item.type}}</span>
-                    </p>
-                    <p style="margin-top:6px;" v-if="item.type == '自主学习'">
-                        <span class="info-label"><Icon type="md-time" style="margin-right:5px;" size="16" />开始时间:</span>
-                        <span class="info-value">{{item.startTime}}</span>
-                    </p>
-                    <p style="margin-top:6px;" v-else>
-                        <span class="info-label"><Icon type="md-time" style="margin-right:5px;" size="16" />结束时间:</span>
-                        <span class="info-value">{{item.endTime}}</span>
-                    </p>
-                </div>
+        <div class="class-list">
+            <div class="activity-target-header">
+                <span>测试科目</span>
             </div>
             </div>
+            <div @click="selectActivity(index)" v-for="(item,index) in paper" :key="index":class="index == currentActivityIndex ? 'activity-target-item block-bg block-bg-active':'block-bg activity-target-item'">
+                <p class="target-name">
+                    {{jsFn.getSubjectName(jsFn.getPeriod($store.state.schoolBaseInfo.schoolBaseInfo, item.periodCode), item.subjectCode)}}
+                    <span class="activity-status">进行中</span>
+                </p>
+                <p style="margin-top:6px;">
+                    <span class="info-label"><Icon type="md-flag" style="margin-right:5px;" size="16" />测试类型:</span>
+                    <span class="info-value">{{typeList[item.level].label}}</span>
+                </p>
+                <p style="margin-top:6px;" >
+                    <span class="info-label"><Icon type="md-time" style="margin-right:5px;" size="16" />开始时间:</span>
+                    <span class="info-value">{{ $tools.formatTime(item.createTime *1000 , 'yyyy-MM-dd')}}</span>
+                </p>
+                <!--<p style="margin-top:6px;" v-else>
+                    <span class="info-label"><Icon type="md-time" style="margin-right:5px;" size="16" />结束时间:</span>
+                    <span class="info-value">{{item.endTime}}</span>
+                </p>-->
+            </div>
+        </div>
             <div class="class-info">
             <div class="class-info">
-               
                 <div class="learn-progress-main dark-iview-table" v-if="currentActivityIndex == 0">
                 <div class="learn-progress-main dark-iview-table" v-if="currentActivityIndex == 0">
                     <vuescroll>
                     <vuescroll>
                         <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:15px;">测验成绩分析</p>
                         <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:15px;">测验成绩分析</p>
@@ -52,7 +51,7 @@
                     <div class="dark-iview-table" v-if="currentActivityIndex != 0">
                     <div class="dark-iview-table" v-if="currentActivityIndex != 0">
                         <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:15px;">测验成绩评审</p>
                         <p style="color:#EEEEEE;padding-left:15px;font-size:16px;margin-top:15px;">测验成绩评审</p>
                         <div style="margin-top:15px;margin-left:30px;">
                         <div style="margin-top:15px;margin-left:30px;">
-                            <grade-list></grade-list>
+                            <grade-list :paperInfo="paperData"></grade-list>
                         </div>
                         </div>
                     </div>
                     </div>
             </div>
             </div>
@@ -61,8 +60,15 @@
 <script>
 <script>
     import Grade from '@/components/learnactivity/GradeChart.vue'
     import Grade from '@/components/learnactivity/GradeChart.vue'
     import Table from '@/components/learnactivity/GradeTable.vue'
     import Table from '@/components/learnactivity/GradeTable.vue'
+    import jsFn from '@/utils/js-fn.js'
     import GradeList from '@/components/learnactivity/GradeList.vue'
     import GradeList from '@/components/learnactivity/GradeList.vue'
     export default {
     export default {
+        props: {
+            paper: {
+                type: Array,
+                default:[],
+            }
+        },
         components: {
         components: {
             Grade,
             Grade,
             Table,
             Table,
@@ -70,28 +76,31 @@
         },
         },
         data() {
         data() {
             return {
             return {
+                jsFn,
                 showAnswer: false,
                 showAnswer: false,
-                currentActivityIndex:0,
-                activityList: [
+                currentActivityIndex: 0,
+                studentData: [],
+                studentList: [],
+                testStatus: false,
+                typeList: [
                     {
                     {
-                        classroomName:'语文',
-                        classroomCode: '123',
-                        type: '平常考',
-                        startTime: '2020-05-06',
-                        endTime:'2020-07-07'
+                        value: '1',
+                        label: '联考'
                     },
                     },
                     {
                     {
-                        classroomName:'数学',
-                        classroomCode: '123',
-                        type:'平常考',
-                        startTime: '2020-05-06',
-                        endTime:'2020-05-07'
+                        value: '2',
+                        label: '段考'
                     },
                     },
-
+                    {
+                        value: '3',
+                        label: '平常考'
+                    },
+                    {
+                        value: '4',
+                        label: '其他'
+                    }
                 ],
                 ],
-                studentData: [], 
-                studentList: [],
-                testStatus:false
+                paperData: {}
             }
             }
         },
         },
         methods: {
         methods: {
@@ -99,7 +108,11 @@
                 this.testStatus = !this.testStatus
                 this.testStatus = !this.testStatus
             },
             },
             selectActivity(index) {
             selectActivity(index) {
+                this.paperData = {}
+                this.currentActivityIndex = 0 
                 this.currentActivityIndex = index
                 this.currentActivityIndex = index
+                this.paperData = this.paper[this.currentActivityIndex]
+                console.log(this.paperData)
             },
             },
             getData() {
             getData() {
                 let data = this.$Mock.data.studentList
                 let data = this.$Mock.data.studentList
@@ -115,7 +128,6 @@
                             }
                             }
                         }
                         }
                     } else {
                     } else {
-
                         this.studentList = this.studentData[0].studentScore
                         this.studentList = this.studentData[0].studentScore
                     }
                     }
                 } else {
                 } else {
@@ -127,7 +139,14 @@
             },
             },
             closeAnswerDetail() {
             closeAnswerDetail() {
                 this.showAnswer = false
                 this.showAnswer = false
-            }
+            },
+            //dataFormate() {
+            //    if (this.paper.length !== 0) {
+            //        for (let i = 0; i < this.paper.length; i++) {
+            //            this.paper[i].createTime = this.$tools.formatTime(this.paper[i].createTime * 1000)
+            //        }
+            //    } 
+            //}
         },
         },
         mounted() {
         mounted() {
             this.getData()
             this.getData()

+ 40 - 23
TEAMModelOS/ClientApp/src/components/learnactivity/GradeList.vue

@@ -1,16 +1,17 @@
 <template>
 <template>
     <div class="body">
     <div class="body">
-        <div class="search-box dark-iview-input">
-            <Input placeholder="查询学生姓名..." v-model="inputData" style="width:25%;margin:5px;">
-            <Icon type="ios-contact" slot="prefix" />
-            </Input>
-        </div>
+
         <div class="content">
         <div class="content">
             <div class="left-box">
             <div class="left-box">
                 <div class="student-box">
                 <div class="student-box">
+                    <div class="search-box dark-iview-input">
+                        <Input placeholder="查询学生姓名..." v-model="inputData" style="width:85%;margin:5px;margin-bottom:5px">
+                        <Icon type="ios-contact" slot="prefix" />
+                        </Input>
+                    </div>
                     <vuescroll>
                     <vuescroll>
                         <ul>
                         <ul>
-                            <li :class="index == selectIndex ?' block-bg-active block-bg':' block-bg'" v-for="(item,index) in studentList" @click="getStudentInfo(item,index)" >
+                            <li :class="index == selectIndex ?' block-bg-active block-bg':' block-bg'" v-for="(item,index) in studentList" @click="getStudentInfo(item,index)">
                                 <div class="student-list">
                                 <div class="student-list">
                                     <span>{{item.name}}</span><br />
                                     <span>{{item.name}}</span><br />
                                 </div>
                                 </div>
@@ -21,8 +22,7 @@
             </div>
             </div>
             <div class="grade-box">
             <div class="grade-box">
                 <vuescroll>
                 <vuescroll>
-                    <ReviewPaper :paper="paperInfo" style="color:#515a6e;" :isShowTools="isShowTools">
-                    </ReviewPaper>
+                    <ReviewPaper :paper="paperData" style="color:#515a6e;" :isShowTools="isShowTools"> </ReviewPaper>
                 </vuescroll>
                 </vuescroll>
             </div>
             </div>
         </div>
         </div>
@@ -33,24 +33,32 @@
 <script>
 <script>
     import ReviewPaper from '../learnactivity/ReviewPaper.vue'
     import ReviewPaper from '../learnactivity/ReviewPaper.vue'
     export default {
     export default {
+        props: {
+            paperInfo: {
+                type: Object,
+                default: {}
+            }
+        },
         components: {
         components: {
             ReviewPaper,
             ReviewPaper,
         },
         },
         data() {
         data() {
             return {
             return {
-                paperCode: "632dd8b3-c48c-4ee5-8448-7e539f764272",
-                paperInfo: {},
+                paperData: {},
                 examAnalysisStatus: false,
                 examAnalysisStatus: false,
                 isShowTools: true,
                 isShowTools: true,
                 dataInfo: {},
                 dataInfo: {},
                 inputData: "",
                 inputData: "",
                 studentData: [],
                 studentData: [],
-                selectIndex:0
+                selectIndex: 0,
+                testData: {
+                    code: '632dd8b3-c48c-4ee5-8448-7e539f764272',
+                }
             }
             }
         },
         },
         computed:{
         computed:{
             studentList() {
             studentList() {
-                this.studentData = this.$Mock.data.studentList[0].studentScore
+                
                 let filterData = this.studentData
                 let filterData = this.studentData
                 if (this.inputData) {
                 if (this.inputData) {
                     filterData = this.studentData.filter(res => {
                     filterData = this.studentData.filter(res => {
@@ -66,28 +74,29 @@
             getStudentInfo(data, index) {
             getStudentInfo(data, index) {
                 this.selectIndex = index
                 this.selectIndex = index
             },
             },
+
+
             //获取学生测验数据
             //获取学生测验数据
             getStudentData() {
             getStudentData() {
                 let requestData = {}
                 let requestData = {}
-                let datas = this.$Mock.data.studentList
-                console.log(datas)
-                requestData.examCode = "632dd8b3-c48c-4ee5-8448-7e539f764272"
-                requestData.id = "c3da2274-94ab-4cf1-92d8-dd30e8532aaf"
-                if (requestData.id !== undefined) {
+                requestData.examCode = this.testData.code
+                requestData.id = this.testData.id
+                if (requestData.examCode !== undefined) {
                     this.$api.learnActivity.FindSummaryRecord(requestData).then(
                     this.$api.learnActivity.FindSummaryRecord(requestData).then(
                         res => {
                         res => {
+                            console.log(res)
                             if (res.error == null) {
                             if (res.error == null) {
                                 let data = []
                                 let data = []
                                 data = res.result.data.map((item) => {
                                 data = res.result.data.map((item) => {
                                     return item.code
                                     return item.code
                                 })
                                 })
                                 let students = {}
                                 let students = {}
-                                students.id = data
+                                students.studentId = data
                                 students.code = "HBCN"
                                 students.code = "HBCN"
                                 this.$api.learnActivity.FindStudent(students).then(
                                 this.$api.learnActivity.FindStudent(students).then(
                                     res => {
                                     res => {
                                         if (res.error == null) {
                                         if (res.error == null) {
-                                            console.log(res.result.data)
+                                            this.studentData = res.result.data
                                         }
                                         }
                                     }
                                     }
                                 )
                                 )
@@ -98,24 +107,29 @@
                     )
                     )
                 }
                 }
             },
             },
+
+
             //获取试卷主观题信息
             //获取试卷主观题信息
             getPaperInfo() {
             getPaperInfo() {
+                console.log('试卷主观题信息')
                 if (this.paperCode !== "") {
                 if (this.paperCode !== "") {
                     let requestData = {
                     let requestData = {
-                        code: this.paperCode
+                        code: this.paperInfo.code
                     }
                     }
                     this.examAnalysisStatus = false
                     this.examAnalysisStatus = false
                     if (requestData.code !== "") {
                     if (requestData.code !== "") {
                         this.$api.learnActivity.FindExamPaper(requestData).then(
                         this.$api.learnActivity.FindExamPaper(requestData).then(
                             res => {
                             res => {
                                 if (res.error == null) {
                                 if (res.error == null) {
-                                    this.paperInfo = res.result.data[0]
+                                    this.paperData = res.result.data[0]
                                     let data = res.result.data[0].item
                                     let data = res.result.data[0].item
-                                    this.paperInfo.item = []
+                                    this.paperData.item = []
                                     for (let i = 0; i < data.length; i++) {
                                     for (let i = 0; i < data.length; i++) {
-                                        this.paperInfo.item.push(data[i])
+                                        this.paperData.item.push(data[i])
                                     }
                                     }
                                     this.examAnalysisStatus = true
                                     this.examAnalysisStatus = true
+                                    console.log('试卷信息2')
+                                    console.log(this.paperData)
                                 } else {
                                 } else {
                                     this.$Message.error('API ERROR!')
                                     this.$Message.error('API ERROR!')
                                 }
                                 }
@@ -126,6 +140,9 @@
             }
             }
         },
         },
         mounted() {
         mounted() {
+            console.log('试卷数据信息')
+            console.log(this.paperInfo)
+            console.log(this.studentData)
             this.getStudentData()
             this.getStudentData()
             this.getPaperInfo()
             this.getPaperInfo()
         }
         }

+ 297 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.less

@@ -0,0 +1,297 @@
+.paper-container {
+    user-select: none !important;
+    font-family: '微軟正黑體', 'Heiti TC' !important;
+
+
+    .paper-title {
+        font-size: 30px;
+        font-weight: bold;
+        vertical-align: middle;
+        text-align: center;
+        cursor: pointer;
+    }
+
+    .paper-subTitle {
+        font-size: 16px;
+        font-weight: bold;
+        margin: 15px;
+        text-align: center;
+        vertical-align: middle;
+    }
+
+    .paper-info {
+        font-size: 14px;
+        vertical-align: middle;
+    }
+
+    .paper-toolbar {
+        background: #fff;
+        padding: 20px;
+
+        .filter-title {
+            font-size: 14px;
+        }
+    }
+}
+
+.paper-main-wrap {
+    width: 100%;
+    display: flex;
+    justify-content: space-between;
+    margin-top: 10px;
+    padding: 20px 0;
+
+    .paper-analysis {
+        position: sticky;
+        top: 0;
+        background: White;
+        width: 20%;
+        padding: 20px 10px;
+
+        .ivu-radio-group {
+            margin: 15px 0 0 0;
+        }
+
+        .analysis-btns {
+            width: 100%;
+            .flex-row-center;
+            justify-content: space-around;
+
+            .ivu-btn {
+                width: 30%;
+                height: 40px;
+            }
+        }
+
+        .analysis-infos {
+            margin-top: 15px;
+            border-top: 1px dotted #cfcfcf;
+            padding: 0 20px 0 20px;
+
+            .analysis-title {
+                font-size: 18px;
+                margin: 30px 0 10px 0;
+                font-weight: bold;
+
+                &::before {
+                    content: "";
+                    height: 14px;
+                    width: 5px;
+                    margin-top: 2px;
+                    margin-right: 8px;
+                    border-radius: 5px;
+                    background: #01b4ef;
+                    display: inline-block;
+                    vertical-align: baseline;
+                }
+            }
+
+            .flex-row-center {
+                justify-content: space-between;
+            }
+
+            .analysis-info {
+                font-weight: bold;
+                color: #69baec;
+                margin: 0 5px;
+            }
+
+            .analysis-index-wrap {
+                display: flex;
+                flex-wrap: wrap;
+            }
+
+            .exercise-index-item {
+                width: 34px;
+                height: 34px;
+                line-height: 34px;
+                text-align: center;
+                margin-right: 10px;
+                margin-top: 10px;
+                background: #69BAEC;
+                color: #fff;
+                border-radius: 5px;
+                cursor: pointer;
+                .flex-row-center;
+
+                &:hover {
+                    background: #0097F4;
+                }
+            }
+        }
+    }
+}
+
+.paper-content {
+    width: 100%;
+    background: #fff;
+    padding: 20px;
+    display: flex;
+    flex-direction: row;
+
+    .paper-body {
+        width: 94%;
+        padding-left: 50px;
+
+        .paper-header {
+            margin-top: 20px;
+        }
+    }
+
+    .paper-base-info {
+        height: 60px;
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        align-items: center;
+        border-bottom: 1px dashed #cfcfcf;
+
+        .base-info-item:not(:first-child) {
+            margin-left: 30px;
+        }
+
+        .base-info-btn:not(:last-child) {
+            margin-right: 10px;
+        }
+
+        .analysis-info {
+            font-weight: bold;
+            color: #69baec;
+            margin: 0 5px;
+        }
+    }
+
+    .paper-part {
+        padding: 15px;
+    }
+
+    .exercise-item {
+        position: relative;
+        font-size: 14px !important;
+        margin-top: 0 !important;
+        padding: 5px 10px !important;
+        box-sizing: border-box;
+        background: transparent;
+        border: 1px solid rgba(1,1,1,0);
+
+        .item-concept {
+            margin-top: 10px;
+        }
+
+        .item-tools {
+            position: absolute;
+            right: -2px;
+            top: -30px;
+            width: auto;
+            height: 30px;
+            margin: 0;
+            padding: 0;
+            background: #01b4ef;
+            display: none;
+        }
+
+        .item-tools-t {
+            height: 100%;
+            padding: 0 15px;
+            float: left;
+            color: white;
+            cursor: pointer;
+
+            &:hover {
+                background: #4a5ae6;
+            }
+
+            .ivu-icon {
+                color: white;
+                font-size: 14px;
+                margin: 0 3px;
+            }
+        }
+
+        &:hover {
+            box-shadow: none !important;
+            border-color: #cfcfcf;
+        }
+    }
+
+    .paper-content-section {
+        font-size: 18px;
+        font-weight: bold;
+        margin-top: 20px;
+
+        span {
+            font-size: 14px;
+            font-weight: 500;
+            margin-left: 10px;
+        }
+    }
+}
+/*.paper-content .paper-part:hover {
+            background: #bfcdad45;
+        }*/
+.paper-content .item-answer, .paper-content .item-explain {
+    line-height: 26px;
+}
+
+.paper-tools {
+    width: 100%;
+    height: 60px;
+    margin-top: 10px;
+    border-top: 1px dashed #cfcfcf;
+    padding: 10px 0;
+
+    .paper-tools-title {
+        font-size: 14px;
+        font-weight: bold;
+        margin-right: 10px;
+    }
+
+    .ivu-checkbox-wrapper {
+        font-size: 14px;
+        margin-left: 10px;
+    }
+
+    .ivu-checkbox {
+        margin: 0 4px;
+        vertical-align: text-bottom;
+    }
+
+    .ivu-checkbox-checked {
+        .ivu-checkbox-inner {
+            background: #01b4ef;
+            border-color: #01b4ef;
+        }
+    }
+}
+
+.rules-modal {
+
+    .ivu-modal-body {
+
+        .rule-item {
+            display: flex;
+            flex-direction: column;
+
+            &-title {
+                margin: 10px 0;
+                font-weight: bold;
+            }
+        }
+    }
+}
+
+
+/*横向垂直水平居中*/
+.flex-row-center {
+    display: flex;
+    flex-direction: row;
+    justify-content: center;
+    align-items: center;
+}
+/*向垂直水平居中*/
+.flex-col-center {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+}

+ 20 - 39
TEAMModelOS/ClientApp/src/components/learnactivity/ReviewPaper.vue

@@ -12,7 +12,7 @@
                             <span class="base-info-item">总分:<span class="analysis-info">52</span></span>
                             <span class="base-info-item">总分:<span class="analysis-info">52</span></span>
                         </div>
                         </div>
                         <div>
                         <div>
-                            <Button class="base-info-btn" type="info" @click="onHandleToggle" v-show="paperInfo.item.length">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button>
+                            <!--<Button class="base-info-btn" type="info" @click="onHandleToggle" v-show="paperInfo.item.length">{{ isAllOpen ? '全部折叠' : '全部展开'}}</Button>-->
                             <Button class="base-info-btn" type="success" @click="savePaper">提交分数</Button>
                             <Button class="base-info-btn" type="success" @click="savePaper">提交分数</Button>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -52,27 +52,7 @@
                 exersicesList: [],
                 exersicesList: [],
                 list: [],
                 list: [],
                 schoolInfo: {},
                 schoolInfo: {},
-                paperInfo: {
-                    name: "",
-                    score: 100,
-                    answers: [],
-                    markConfig: {
-                        auto: false,
-                        type: 0,
-                        score: 0
-                    },
-                    item: []
-                },
-                exersicesType: {
-                    Single: '单选题',
-                    Multiple: '多选题',
-                    Judge: '判断题',
-                    Complete: '填空题',
-                    Subjective: '问答题',
-                    Compose: '综合题'
-                },
-                exersicesDiff: ['容易', '较易', '一般', '较难', '困难'],
-                diffColors: ['#32CF74', '#E8BE15', '#F19300', '#EB5E00', '#D30000'],
+                paperInfo: {},
                 filterType: '0',
                 filterType: '0',
                 filterDiff: '0',
                 filterDiff: '0',
                 filterSort: '0',
                 filterSort: '0',
@@ -101,6 +81,7 @@
             }
             }
         },
         },
         mounted() {
         mounted() {
+            console.log(this.paper)
             this.onHandleToggle()
             this.onHandleToggle()
             this.onToggleChange()
             this.onToggleChange()
         },
         },
@@ -119,9 +100,9 @@
              * exList的collapseList变化
              * exList的collapseList变化
              * @param list
              * @param list
              */
              */
-            onToggleChange(list) {
-                this.isAllOpen = list.length !== 0
-            },
+            //onToggleChange(list) {
+            //    this.isAllOpen = list.length !== 0
+            //},
 
 
             /** 返回试卷库 */
             /** 返回试卷库 */
             onBackToBank() {
             onBackToBank() {
@@ -138,14 +119,14 @@
                
                
             },
             },
             /** 重新挑题 */
             /** 重新挑题 */
-            goToPickExercise() {
-                this.$router.push({
-                    name: 'exercisesList',
-                    params: {
-                        paperInfo: this.paperInfo
-                    }
-                })
-            },
+            //goToPickExercise() {
+            //    this.$router.push({
+            //        name: 'exercisesList',
+            //        params: {
+            //            paperInfo: this.paperInfo
+            //        }
+            //    })
+            //},
 
 
             /** 点击题型配分 */
             /** 点击题型配分 */
             onSetScoreByType() {
             onSetScoreByType() {
@@ -176,11 +157,11 @@
         },
         },
         mounted() {
         mounted() {
             this.isShowSave = window.location.pathname === '/home/evaluation/testPaper'
             this.isShowSave = window.location.pathname === '/home/evaluation/testPaper'
-            let paper = this.paper || this.$route.params.paper || JSON.parse(localStorage.getItem('_paperInfo'))
-            if (!paper) return
-            localStorage.setItem('_paperInfo', JSON.stringify(paper))
-            this.paperInfo = paper // 自己页面的值
-            this.paperDiff = paper.item ? this.handleDiffCalc(paper.item) : 0
+            //let paper = this.paper || this.$route.params.paper || JSON.parse(localStorage.getItem('_paperInfo'))
+            //if (!paper) return
+            //localStorage.setItem('_paperInfo', JSON.stringify(paper))
+            this.paperInfo = this.paper // 自己页面的值
+            this.paperDiff = this.paper.item ? this.handleDiffCalc(this.paper.item) : 0
         },
         },
         computed: {
         computed: {
             isAuto() {
             isAuto() {
@@ -195,7 +176,7 @@
                 handler(newValue, oldValue) {
                 handler(newValue, oldValue) {
                     console.log(newValue)
                     console.log(newValue)
                     this.paperInfo = newValue
                     this.paperInfo = newValue
-                    localStorage.setItem('_paperInfo', JSON.stringify(newValue))
+                    //localStorage.setItem('_paperInfo', JSON.stringify(newValue))
                     this.paperDiff = newValue.item ? this.handleDiffCalc(newValue.item) : 4
                     this.paperDiff = newValue.item ? this.handleDiffCalc(newValue.item) : 4
                 },
                 },
                 deep: true
                 deep: true

+ 13 - 0
TEAMModelOS/ClientApp/src/router/routes.js

@@ -35,6 +35,19 @@ export const routes = [
             }
             }
         ]
         ]
     },
     },
+    {
+        path: '/forgotpw', component: FrontEndMain,
+        children: [
+            {
+                name: 'forgotpw',
+                path: '/',
+                meta: {
+                    middleware: ['login?']
+                },
+                component: resolve => require(['@/view/forgotPw/Index.vue'], resolve)
+            }
+        ]
+    },
     {
     {
         path: '/schoolList',
         path: '/schoolList',
         component: Home,
         component: Home,

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


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

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

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

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

+ 76 - 81
TEAMModelOS/ClientApp/src/view/learnactivity/ManageEvaluation.vue

@@ -90,7 +90,7 @@
             </div>
             </div>
             <div :class="currentBraIndex == 1 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="currentBraIndex == 1">
             <div :class="currentBraIndex == 1 ? 'animated fadeIn evaluation-base-info':'evaluation-base-info animated fadeOutRight'" v-show="currentBraIndex == 1">
                 <vuescroll>
                 <vuescroll>
-                    <ClassList></ClassList>
+                    <ClassList :paper="examPaperList"></ClassList>
                 </vuescroll>
                 </vuescroll>
             </div>
             </div>
         </div>
         </div>
@@ -506,8 +506,6 @@
             },
             },
             selectEvaluation(index) {
             selectEvaluation(index) {
                 this.avtiveEvaluationIndex = index
                 this.avtiveEvaluationIndex = index
-                console.log(index)
-                console.log(this.evaluationList[this.avtiveEvaluationIndex])
                 this.getMyDate(this.evaluationList[this.avtiveEvaluationIndex].startTime, this.evaluationList[this.avtiveEvaluationIndex].endTime)
                 this.getMyDate(this.evaluationList[this.avtiveEvaluationIndex].startTime, this.evaluationList[this.avtiveEvaluationIndex].endTime)
                 this.findExamPaper()
                 this.findExamPaper()
             },
             },
@@ -526,8 +524,6 @@
                     res => {
                     res => {
                         if (res.error == null) {
                         if (res.error == null) {
                             this.evaluationList = res.result.data
                             this.evaluationList = res.result.data
-                            console.log('獲取评测列表')
-                            console.log(this.evaluationList)
                             if (this.evaluationList.length > 0) {
                             if (this.evaluationList.length > 0) {
                                 this.selectEvaluation(0)
                                 this.selectEvaluation(0)
                             }
                             }
@@ -548,7 +544,6 @@
                     res => {
                     res => {
                         if (res.error == null) {
                         if (res.error == null) {
                             this.examPaperList = res.result.data
                             this.examPaperList = res.result.data
-                            console.log(this.examPaperList)
                             this.groupQuestion = {}
                             this.groupQuestion = {}
                             if (this.examPaperList.length > 0) {
                             if (this.examPaperList.length > 0) {
                                 let groupResult = jsFn.groupBy(this.examPaperList[0].item, 'type')
                                 let groupResult = jsFn.groupBy(this.examPaperList[0].item, 'type')
@@ -568,82 +563,82 @@
                     }
                     }
                 )
                 )
             },
             },
-            checkCount(count) {
-                switch (count) {
-                    case 0:
-                        return '一、'
-                        break
-                    case 1:
-                        return '二、'
-                        break
-                    case 2:
-                        return '三、'
-                        break
-                    case 3:
-                        return '四、'
-                        break
-                    case 4:
-                        return '五、'
-                        break
-                    case 5:
-                        return '六、'
-                        break
-                    default:
-                        return ''
-                        break
-                }
-            },
-            getOrder(type) {
-                let count = 0
-                switch (type) {
-                    case 'Single':
-                        return '一、'
-                        break
-                    case 'Multiple':
-                        if (this.groupQuestion.Single != undefined) {
-                            return '二、'
-                        } else {
-                            return '一、'
-                        }
-                        break
-                    case 'Complete':
-                        for (let key in this.groupQuestion) {
-                            if (key == 'Single' || key == 'Multiple') {
-                                count++
-                            }
-                        }
-                        return this.checkCount(count)
-                        break
-                    case 'Judge':
+            //checkCount(count) {
+            //    switch (count) {
+            //        case 0:
+            //            return '一、'
+            //            break
+            //        case 1:
+            //            return '二、'
+            //            break
+            //        case 2:
+            //            return '三、'
+            //            break
+            //        case 3:
+            //            return '四、'
+            //            break
+            //        case 4:
+            //            return '五、'
+            //            break
+            //        case 5:
+            //            return '六、'
+            //            break
+            //        default:
+            //            return ''
+            //            break
+            //    }
+            //},
+            //getOrder(type) {
+            //    let count = 0
+            //    switch (type) {
+            //        case 'Single':
+            //            return '一、'
+            //            break
+            //        case 'Multiple':
+            //            if (this.groupQuestion.Single != undefined) {
+            //                return '二、'
+            //            } else {
+            //                return '一、'
+            //            }
+            //            break
+            //        case 'Complete':
+            //            for (let key in this.groupQuestion) {
+            //                if (key == 'Single' || key == 'Multiple') {
+            //                    count++
+            //                }
+            //            }
+            //            return this.checkCount(count)
+            //            break
+            //        case 'Judge':
 
 
-                        for (let key in this.groupQuestion) {
-                            if (key == 'Single' || key == 'Complete' || key == 'Multiple') {
-                                count++
-                            }
-                        }
-                        return this.checkCount(count)
-                        break
-                    case 'Subjective':
-                        for (let key in this.groupQuestion) {
-                            if (key == 'Single' || key == 'Complete' || key == 'Multiple' || key == 'Judge') {
-                                count++
-                            }
-                        }
-                        return this.checkCount(count)
-                        break
-                    case 'Compose':
-                        for (let key in this.groupQuestion) {
-                            if (key == 'Single' || key == 'Complete' || key == 'Multiple' || key == 'Judge' || key == 'Subjective') {
-                                count++
-                            }
-                        }
-                        return this.checkCount(count)
-                        break
-                    default:
-                        return ''
-                        break
-                }
-            }
+            //            for (let key in this.groupQuestion) {
+            //                if (key == 'Single' || key == 'Complete' || key == 'Multiple') {
+            //                    count++
+            //                }
+            //            }
+            //            return this.checkCount(count)
+            //            break
+            //        case 'Subjective':
+            //            for (let key in this.groupQuestion) {
+            //                if (key == 'Single' || key == 'Complete' || key == 'Multiple' || key == 'Judge') {
+            //                    count++
+            //                }
+            //            }
+            //            return this.checkCount(count)
+            //            break
+            //        case 'Compose':
+            //            for (let key in this.groupQuestion) {
+            //                if (key == 'Single' || key == 'Complete' || key == 'Multiple' || key == 'Judge' || key == 'Subjective') {
+            //                    count++
+            //                }
+            //            }
+            //            return this.checkCount(count)
+            //            break
+            //        default:
+            //            return ''
+            //            break
+            //    }
+            //}
         },
         },
         mounted() {
         mounted() {
             //console.log('sas')
             //console.log('sas')

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

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

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

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

+ 10 - 1
TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.less

@@ -382,7 +382,6 @@
                 .ivu-icon {
                 .ivu-icon {
                     margin-top: -3px;
                     margin-top: -3px;
                     margin-right: 5px;
                     margin-right: 5px;
-                    display: none;
                 }
                 }
             }
             }
 
 
@@ -519,3 +518,13 @@
     display: inline-block;
     display: inline-block;
     vertical-align: super;
     vertical-align: super;
 }
 }
+
+#get-width {
+    position: absolute;
+    left: 0px;
+    top: 0px;
+    font-size: 18px;
+    visibility: hidden;
+    border: 1px solid black;
+    width: fit-content;
+}

+ 106 - 56
TEAMModelOS/ClientApp/src/view/school-mgmt/SystemSetting/SystemSetting.vue

@@ -1,29 +1,5 @@
-<style lang="less" scoped>
-    @import './SystemSetting.less';
-</style>
-<style>
-    .second-arrow {
-        margin-left: -16px;
-    }
-
-    .color-check {
-        color: #08d0c8;
-    }
-
-    .color-uncheck {
-        color: #FF6C6B;
-    }
-
-    .bg-color-check {
-        background-color: #08d0c8 !important;
-    }
-
-    .bg-color-uncheck {
-        background-color: #FF6C6B !important;
-    }
-</style>
 <template>
 <template>
-    <div class="sm-system">
+    <div class="sm-system" @click="editSubStatus = false">
         <div class="sm-school-name">
         <div class="sm-school-name">
             <div>
             <div>
                 <span class="setting-title">{{$t('schoolBaseInfo.schoolNameLabel')}}</span>
                 <span class="setting-title">{{$t('schoolBaseInfo.schoolNameLabel')}}</span>
@@ -54,15 +30,13 @@
                             <span class="campus-label" @click="setCampus">
                             <span class="campus-label" @click="setCampus">
                                 {{item.campusCode === null ? '请设置校区': $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]").length > 0 ? $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]")[0].campusName : '请设置校区' }}
                                 {{item.campusCode === null ? '请设置校区': $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]").length > 0 ? $JSONPath.query(schoolSetting, "$..campuses[?(@.campusCode=='" + item.campusCode + "')]")[0].campusName : '请设置校区' }}
                             </span>
                             </span>
-                            <!--<Icon type="md-create" class="period-btn-edit" title="编辑" @click="changePeriodEditStatus(index)" />-->
                         </p>
                         </p>
-
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.semesterNum') + item.semesters.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.semesterNum') + item.semesters.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.gradeNum') + item.grades.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.gradeNum') + item.grades.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.periodNum') + item.subjects.length}}</p>
                         <p class="period-item-num"><span></span>{{ $t('schoolBaseInfo.periodNum') + item.subjects.length}}</p>
 
 
                     </div>
                     </div>
-                    
+
                 </div>
                 </div>
             </div>
             </div>
             <!--学期列表-->
             <!--学期列表-->
@@ -84,17 +58,14 @@
                             </p>
                             </p>
                             <div class="term-item-start">
                             <div class="term-item-start">
                                 <span>{{$t('schoolBaseInfo.startDate')}}</span>
                                 <span>{{$t('schoolBaseInfo.startDate')}}</span>
-                                <!--<Select v-model="item.month" :disabled="editSemIndex !== index" :placeholder="$t('schoolBaseInfo.monthHolder')">
-        <Option v-for="(item,index) in monthList" :value="item" :key="index">{{ item }}</Option>
-    </Select>-->
-                                <InputNumber v-model="item.month" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="12" :min="1"></InputNumber>
+                                <InputNumber @on-change="countSemDays" v-model="item.month" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="12" :min="1"></InputNumber>
                                 <span> / </span>
                                 <span> / </span>
-                                <InputNumber v-model="item.day" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="31" :min="1"></InputNumber>
+                                <InputNumber @on-change="countSemDays" v-model="item.day" size="small" style="width:50px;" :disabled="editSemIndex !== index" :max="31" :min="1"></InputNumber>
                             </div>
                             </div>
                             <p class="term-item-students-num">{{$t('schoolBaseInfo.semesterDuration')+ item.days + $t('schoolBaseInfo.dayUnit')  }}</p>
                             <p class="term-item-students-num">{{$t('schoolBaseInfo.semesterDuration')+ item.days + $t('schoolBaseInfo.dayUnit')  }}</p>
                         </div>
                         </div>
                     </div>
                     </div>
-                    
+
                     <div class="term-item-time-line" v-if="schoolSetting.period[currentSchoolSysIndex].semesters.length">
                     <div class="term-item-time-line" v-if="schoolSetting.period[currentSchoolSysIndex].semesters.length">
                         <ul>
                         <ul>
                             <li v-for="(item,index) in monthEnList" :key="index">
                             <li v-for="(item,index) in monthEnList" :key="index">
@@ -134,17 +105,22 @@
                     </div>
                     </div>
                 </div>
                 </div>
                 <!--学科显示区域-->
                 <!--学科显示区域-->
-                <div class="col-title">
+                <div class="col-title" @click.stop>
                     <span>{{$t('schoolBaseInfo.subjectSetting')}}</span>
                     <span>{{$t('schoolBaseInfo.subjectSetting')}}</span>
-                    <Icon type="md-add" @click="addSubject()" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll"/>
+                    <Icon type="md-add" @click="addSubject()" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                    <Icon type="md-trash" @click="delSubStatus = true" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                    <Icon type="md-create" @click.stop="editSubStatus = true" class="action-btn-icon" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
                 </div>
                 </div>
-                <div class="grade-body">
+                <div class="grade-body dark-iview-input disabled-iview-input" @click.stop>
                     <div class="grade-item item-active" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].subjects" :key="index">
                     <div class="grade-item item-active" v-for="(item,index) in schoolSetting.period[currentSchoolSysIndex].subjects" :key="index">
                         <span class="grade-item-icon"></span>
                         <span class="grade-item-icon"></span>
-                        <EditableLabel ref="subjectName" class="grade-item-name" :content="item.subjectName" @editComplete="handleEditSubject($event,index)">
-                        </EditableLabel>
-                        <Icon type="md-create" class="period-btn-edit" :title="$t('schoolBaseInfo.editLabel')" @click="changeSubjectEditStatus(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
-                        <Icon type="md-close" @click="delSubject(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />
+                        <!--<EditableLabel ref="subjectName" class="grade-item-name" :content="item.subjectName" @editComplete="handleEditSubject($event,index)">
+    </EditableLabel>-->
+                        <p :class="'get-width'+index" id="get-width">{{item.subjectName}}</p>
+
+                        <Input v-model="item.subjectName" :disabled="!editSubStatus" placeholder="设置学科..." :style="{width: getWidth(index)+'px'}" />
+                        <!--<Icon type="md-create" class="period-btn-edit" :title="$t('schoolBaseInfo.editLabel')" @click="changeSubjectEditStatus(index)" v-if="$access.ability('admin','schoolSetting-upd').validateAll" />-->
+                        <Icon type="md-close" @click="delSubject(index)" v-show="delSubStatus" />
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
@@ -190,6 +166,8 @@
         },
         },
         data() {
         data() {
             return {
             return {
+                editSubStatus: false,
+                delSubStatus: false,
                 updateDays: false,
                 updateDays: false,
                 isSaveLoading: false,
                 isSaveLoading: false,
                 delSemesterStatus: false,
                 delSemesterStatus: false,
@@ -215,25 +193,71 @@
                 subjectSelectList: [],
                 subjectSelectList: [],
                 TERM_MAX_LENGTH: 3, // 学期数上限
                 TERM_MAX_LENGTH: 3, // 学期数上限
                 campusStatus: false,
                 campusStatus: false,
-                selectedCampusIndex: -1
+                selectedCampusIndex: -1,
+                width:[]
             }
             }
         },
         },
         methods: {
         methods: {
+            /**
+             * 动态设置input宽度
+             * */
+            getWidth(index) {
+                let width = 100
+                this.$nextTick(() => {
+                    let dom = document.getElementsByClassName('get-width' + index)
+                    console.log(dom)
+                    if (dom.length > 0) {
+                        width = dom[0].clientWidth + 25
+                        console.log(width)
+                    }
+                })
+
+                return width
+            },
+
+            /**
+             * 计算学期天数
+             * @param date1
+             * @param date2
+            */
+            countSemDays() {
+                if (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length > 0) {
+                    let count = 365
+                    let index = 0
+                    let year = new Date().getFullYear()
+                    for (let i = 0; i < this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length; i++) {
+                        if (i == (this.schoolSetting.period[this.currentSchoolSysIndex].semesters.length - 1)) {
+                            index = i
+                            break
+                        } else {
+                            let sDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].day
+                            let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].day
+                            let d = this.getDays(sDate, eDate)
+                            count -= d
+                            this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i], 'days', d)
+
+                        }
+                    }
+                    this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[index], 'days', count)
+
+                    this.updated = false
+                }
+            },
             /**
             /**
              * 计算两个日期的天数
              * 计算两个日期的天数
              * @param date1
              * @param date1
              * @param date2
              * @param date2
              */
              */
-            getDays(date1 , date2){
+            getDays(date1, date2) {
                 var date1Str = date1.split("-");//将日期字符串分隔为数组,数组元素分别为年.月.日
                 var date1Str = date1.split("-");//将日期字符串分隔为数组,数组元素分别为年.月.日
                 //根据年 . 月 . 日的值创建Date对象
                 //根据年 . 月 . 日的值创建Date对象
-                var date1Obj = new Date(date1Str[0],(date1Str[1]-1),date1Str[2]);
+                var date1Obj = new Date(date1Str[0], (date1Str[1] - 1), date1Str[2]);
                 var date2Str = date2.split("-");
                 var date2Str = date2.split("-");
-                var date2Obj = new Date(date2Str[0],(date2Str[1]-1),date2Str[2]);
+                var date2Obj = new Date(date2Str[0], (date2Str[1] - 1), date2Str[2]);
                 var t1 = date1Obj.getTime();
                 var t1 = date1Obj.getTime();
                 var t2 = date2Obj.getTime();
                 var t2 = date2Obj.getTime();
-                var dateTime = 1000*60*60*24; //每一天的毫秒数
-                var minusDays = Math.floor(((t2-t1)/dateTime));//计算出两个日期的天数差
+                var dateTime = 1000 * 60 * 60 * 24; //每一天的毫秒数
+                var minusDays = Math.floor(((t2 - t1) / dateTime));//计算出两个日期的天数差
                 var days = Math.abs(minusDays);//取绝对值
                 var days = Math.abs(minusDays);//取绝对值
                 return days;
                 return days;
             },
             },
@@ -281,7 +305,7 @@
                 if (this.$access.ability('admin', 'schoolSetting-upd').validateAll) {
                 if (this.$access.ability('admin', 'schoolSetting-upd').validateAll) {
                     this.campusStatus = true
                     this.campusStatus = true
                 }
                 }
-                
+
             },
             },
             // 删除节点
             // 删除节点
             delGrade(index) {
             delGrade(index) {
@@ -314,6 +338,7 @@
                     this.currentSchoolSysIndex = 0
                     this.currentSchoolSysIndex = 0
                     this.curSemIndex = 0
                     this.curSemIndex = 0
                     this.schoolSetting.period[this.currentSchoolSysIndex].semesters.splice(index, 1)
                     this.schoolSetting.period[this.currentSchoolSysIndex].semesters.splice(index, 1)
+                    this.countSemDays()
                 } else {
                 } else {
                     this.$Message.warning(this.$t('schoolBaseInfo.ssTips2'))
                     this.$Message.warning(this.$t('schoolBaseInfo.ssTips2'))
                 }
                 }
@@ -401,21 +426,21 @@
                                 break
                                 break
                             } else {
                             } else {
                                 let sDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].day
                                 let sDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i].day
-                                let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i+1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i+1].day
+                                let eDate = year + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].month + '-' + this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i + 1].day
                                 let d = this.getDays(sDate, eDate)
                                 let d = this.getDays(sDate, eDate)
                                 console.log(d)
                                 console.log(d)
                                 count -= d
                                 count -= d
                                 this.updateDays = true
                                 this.updateDays = true
-                                this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i],'days',d)
-                                
+                                this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[i], 'days', d)
+
                             }
                             }
                         }
                         }
                         this.updateDays = true
                         this.updateDays = true
                         this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[index], 'days', count)
                         this.$set(this.schoolSetting.period[this.currentSchoolSysIndex].semesters[index], 'days', count)
-                        
+
                     }
                     }
                 }
                 }
-                
+
             },
             },
             //保存数据
             //保存数据
             saveData() {
             saveData() {
@@ -427,6 +452,7 @@
                             this.$Message.success(this.$t('schoolBaseInfo.ssTips3'))
                             this.$Message.success(this.$t('schoolBaseInfo.ssTips3'))
                             this.updated = false
                             this.updated = false
                             this.isSaveLoading = false
                             this.isSaveLoading = false
+                            this.editSemIndex = -1
                         }
                         }
                     },
                     },
                     (err) => {
                     (err) => {
@@ -627,6 +653,7 @@
                         day: 26,
                         day: 26,
                         semesterCode: this.guid()
                         semesterCode: this.guid()
                     })
                     })
+                    this.countSemDays()
                 } else {
                 } else {
                     this.$Message.info(this.$t('schoolBaseInfo.ssTips7'))
                     this.$Message.info(this.$t('schoolBaseInfo.ssTips7'))
                 }
                 }
@@ -756,17 +783,40 @@
                 } else {
                 } else {
                     return false
                     return false
                 }
                 }
-            }
+            },
+            
         }
         }
 
 
     }
     }
 </script>
 </script>
 
 
-<!-- 覆盖iview样式 -->
+<style lang="less" scoped>
+    @import './SystemSetting.less';
+</style>
 <style>
 <style>
+    .second-arrow {
+        margin-left: -16px;
+    }
+
+    .color-check {
+        color: #08d0c8;
+    }
+
+    .color-uncheck {
+        color: #FF6C6B;
+    }
+
+    .bg-color-check {
+        background-color: #08d0c8 !important;
+    }
+
+    .bg-color-uncheck {
+        background-color: #FF6C6B !important;
+    }
+
     .semester-name-label .ivu-input[disabled] {
     .semester-name-label .ivu-input[disabled] {
         font-size: 20px !important;
         font-size: 20px !important;
         font-weight: bold;
         font-weight: bold;
         color: white;
         color: white;
     }
     }
-</style>
+</style>