Pārlūkot izejas kodu

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

liqk 4 gadi atpakaļ
vecāks
revīzija
3b71ae21f9
47 mainītis faili ar 519 papildinājumiem un 906 dzēšanām
  1. 11 11
      TEAMModelGrpc/Services/ClassroomService.cs
  2. 6 6
      TEAMModelGrpc/Services/ClassroomStudentService.cs
  3. 7 7
      TEAMModelGrpc/Services/CourseService.cs
  4. 9 9
      TEAMModelGrpc/Services/HomeWorkService.cs
  5. 2 2
      TEAMModelGrpc/Startup.cs
  6. 22 0
      TEAMModelOS.SDK/Extension/HttpContextExtensions.cs
  7. 0 0
      TEAMModelOS.SDK/Extension/JsonContent.cs
  8. 0 39
      TEAMModelOS.SDK/Extension/JwtAuth/Filters/BlackListJwtSecurityTokenHandler.cs
  9. 0 54
      TEAMModelOS.SDK/Extension/JwtAuth/Filters/JwtAuthorizationFilter.cs
  10. 0 100
      TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs
  11. 0 106
      TEAMModelOS.SDK/Extension/JwtAuth/JwtHelper/JwtHelper.cs
  12. 0 33
      TEAMModelOS.SDK/Extension/JwtAuth/Models/ClaimModel.cs
  13. 0 12
      TEAMModelOS.SDK/Extension/JwtAuth/Models/HttpConstant.cs
  14. 0 14
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtBlackRecord.cs
  15. 0 12
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtClient.cs
  16. 0 15
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtResponse.cs
  17. 0 30
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtSetting.cs
  18. 0 15
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtTokenOptions.cs
  19. 86 0
      TEAMModelOS.SDK/Extension/JwtAuthExtension.cs
  20. 6 0
      TEAMModelOS.SDK/Extension/Utils.cs
  21. 0 148
      TEAMModelOS.SDK/Helper/Network/HttpHelper/HttpContextHelper.cs
  22. 1 1
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteBar.vue
  23. 18 0
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.less
  24. 20 4
      TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.vue
  25. 1 2
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue
  26. 2 2
      TEAMModelOS/ClientApp/src/view/evaluation/components/BaseExerciseList.vue
  27. 5 3
      TEAMModelOS/ClientApp/src/view/evaluation/index/CreatePaper.vue
  28. 2 1
      TEAMModelOS/ClientApp/src/view/evaluation/index/PickExercise.css
  29. 4 0
      TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue
  30. 1 1
      TEAMModelOS/ClientApp/src/view/homework/ManageHomeWork.vue
  31. 6 6
      TEAMModelOS/ClientApp/src/view/learnactivity/ExamPaperAnalysis.vue
  32. 53 20
      TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue
  33. 9 9
      TEAMModelOS/Controllers/Analysis/AchievementController.cs
  34. 29 30
      TEAMModelOS/Controllers/BaseController.cs
  35. 0 27
      TEAMModelOS/Controllers/Client/Attribute/AuthFilter.cs
  36. 78 0
      TEAMModelOS/Controllers/Client/Filter/AuthTokenAttribute.cs
  37. 30 25
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  38. 1 53
      TEAMModelOS/Controllers/Core/AuthController.cs
  39. 5 5
      TEAMModelOS/Controllers/Core/CommonController.cs
  40. 13 13
      TEAMModelOS/Controllers/School/ClassRoomController.cs
  41. 14 14
      TEAMModelOS/Controllers/School/ClassStudentController.cs
  42. 25 25
      TEAMModelOS/Controllers/School/CourseController.cs
  43. 8 8
      TEAMModelOS/Controllers/School/SchoolController.cs
  44. 18 18
      TEAMModelOS/Controllers/Student/StudentController.cs
  45. 9 9
      TEAMModelOS/Controllers/Teacher/CommentController.cs
  46. 17 17
      TEAMModelOS/Controllers/Teacher/SchoolUserController.cs
  47. 1 0
      TEAMModelOS/TEAMModelOS.csproj

+ 11 - 11
TEAMModelGrpc/Services/ClassroomService.cs

@@ -14,11 +14,11 @@ namespace TEAMModelGrpc.Services
 {
     public class ClassroomService : IGrpcService
     {
-        public readonly AzureCosmosFactory cosmosrepository;
+        public readonly AzureCosmosFactory _azureCosmos;
 
-        public ClassroomService(AzureCosmosFactory cosmosrepository)
+        public ClassroomService(AzureCosmosFactory azureCosmos)
         {
-            this.cosmosrepository = cosmosrepository;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -37,15 +37,15 @@ namespace TEAMModelGrpc.Services
             {
                 if (classroom.id != null)
                 {
-                    classrooms.Add( await cosmosrepository.SaveOrUpdate(classroom));
+                    classrooms.Add( await _azureCosmos.SaveOrUpdate(classroom));
                 }
                 else
                 {
                     ClassStudent students = new ClassStudent();
                     students.code = classroom.code;
                     students.id = classroom.classroomCode;
-                    await cosmosrepository.SaveOrUpdate(students);
-                    classrooms.Add(await cosmosrepository.SaveOrUpdate(classroom));
+                    await _azureCosmos.SaveOrUpdate(students);
+                    classrooms.Add(await _azureCosmos.SaveOrUpdate(classroom));
 
                 }
             }
@@ -67,7 +67,7 @@ namespace TEAMModelGrpc.Services
         {
 
             Dictionary<string, object> dict = request.ToDict();
-            List<Classroom> syllabusVolumes = await cosmosrepository.FindByDict<Classroom>(dict);
+            List<Classroom> syllabusVolumes = await _azureCosmos.FindByDict<Classroom>(dict);
             syllabusVolumes.ForEach(x => {
                 responseStream.WriteAsync(x);
             });
@@ -83,20 +83,20 @@ namespace TEAMModelGrpc.Services
         [Authorize]
         public async Task<ListPid> Delete(ListPid listPid, ServerCallContext context)
         {
-            await cosmosrepository.DeleteAll<Classroom>(listPid.idPks);
+            await _azureCosmos.DeleteAll<Classroom>(listPid.idPks);
             if (listPid.idPks.IsNotEmpty())
             {
                 List<ClassStudent> students = new List<ClassStudent>();
                 foreach (IdPk classroom in listPid.idPks)
                 {
-                    List<ClassStudent> ClassStudents = await cosmosrepository.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", classroom.id }, { "code", classroom.pk } });
+                    List<ClassStudent> ClassStudents = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", classroom.id }, { "code", classroom.pk } });
                     students.AddRange(ClassStudents);
                 }
                 if (students.Count > 0)
                 {
-                    await cosmosrepository.DeleteAll<ClassStudent>(students);
+                    await _azureCosmos.DeleteAll<ClassStudent>(students);
                 }
-                listPid.idPks = await cosmosrepository.DeleteAll<Classroom>(listPid.idPks);
+                listPid.idPks = await _azureCosmos.DeleteAll<Classroom>(listPid.idPks);
             }
             return listPid;
         }

+ 6 - 6
TEAMModelGrpc/Services/ClassroomStudentService.cs

@@ -1,4 +1,4 @@
-using Grpc.Core;
+using Grpc.Core;
 using Grpc.Extension.Abstract;
 using Microsoft.AspNetCore.Authorization;
 using System;
@@ -14,10 +14,10 @@ namespace TEAMModelGrpc.Services
 {
     public class ClassStudentService : IGrpcService
     {
-        private AzureCosmosFactory _cosmos;
-        public ClassStudentService(AzureCosmosFactory cosmos)
+        private AzureCosmosFactory _azureCosmos;
+        public ClassStudentService(AzureCosmosFactory azureCosmos)
         {
-            _cosmos = cosmos;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -33,7 +33,7 @@ namespace TEAMModelGrpc.Services
             List<ClassStudent> classrooms = new List<ClassStudent>();
             await foreach (ClassStudent students in requestStream.ReadAllAsync())
             {
-                classrooms.Add(await _cosmos.SaveOrUpdate(students));
+                classrooms.Add(await _azureCosmos.SaveOrUpdate(students));
             }
             classrooms.ForEach(x => {
                 responseStream.WriteAsync(x);
@@ -56,7 +56,7 @@ namespace TEAMModelGrpc.Services
         [Authorize]
         public async Task FindStudents(StringDto request, IServerStreamWriter<ClassStudent> responseStream, ServerCallContext context) 
         {
-            List<ClassStudent> ClassStudents = await _cosmos.FindSQL<ClassStudent>("select c.id,c.code from c join A0  in c.studentId where 1=1 and c.pk='ClassStudent' and A0 =  \'" + request + "\'");
+            List<ClassStudent> ClassStudents = await _azureCosmos.FindSQL<ClassStudent>("select c.id,c.code from c join A0  in c.studentId where 1=1 and c.pk='ClassStudent' and A0 =  \'" + request + "\'");
             if (ClassStudents.IsNotEmpty()) {
                 ClassStudents.ForEach(  x => { 
                 responseStream.WriteAsync(x);

+ 7 - 7
TEAMModelGrpc/Services/CourseService.cs

@@ -1,4 +1,4 @@
-using Grpc.Core;
+using Grpc.Core;
 using Grpc.Extension.Abstract;
 using Microsoft.AspNetCore.Authorization;
 using System;
@@ -13,11 +13,11 @@ namespace TEAMModelGrpc.Services
 {
     public class CourseService : IGrpcService
     {
-        public AzureCosmosFactory _cosmos;
+        public AzureCosmosFactory _azureCosmos;
 
-        public CourseService(AzureCosmosFactory cosmosDBV3Repository)
+        public CourseService(AzureCosmosFactory azureCosmos)
         {
-            this._cosmos = cosmosDBV3Repository;
+            _azureCosmos = azureCosmos;
         }
 
 
@@ -35,7 +35,7 @@ namespace TEAMModelGrpc.Services
             Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
             keyValuePairs = request.ToDict();
 
-            List<Course> course = await _cosmos.FindByDict<Course>(keyValuePairs);
+            List<Course> course = await _azureCosmos.FindByDict<Course>(keyValuePairs);
             course.ForEach(x =>
             {
                 responseStream.WriteAsync(x);
@@ -62,7 +62,7 @@ namespace TEAMModelGrpc.Services
                 knowledges.Add(message);
             }
 
-            await _cosmos.SaveOrUpdateAll(knowledges);
+            await _azureCosmos.SaveOrUpdateAll(knowledges);
 
             knowledges.ForEach(x =>
             {
@@ -80,7 +80,7 @@ namespace TEAMModelGrpc.Services
         [Authorize]
         public async Task<ListPid> DeleteCourse(ListPid listPid, ServerCallContext context)
         {
-            List<IdPk> idPks = await _cosmos.DeleteAll<Course>(listPid.idPks);
+            List<IdPk> idPks = await _azureCosmos.DeleteAll<Course>(listPid.idPks);
             listPid.idPks = idPks;
             return listPid;
         }

+ 9 - 9
TEAMModelGrpc/Services/HomeWorkService.cs

@@ -16,11 +16,11 @@ namespace TEAMModelGrpc.Services
 {
     public class HomeWorkService : IGrpcService
     {
-        private readonly AzureCosmosFactory _cosmos;
+        private readonly AzureCosmosFactory _azureCosmos;
 
-        public HomeWorkService(AzureCosmosFactory cosmos)
+        public HomeWorkService(AzureCosmosFactory azureCosmos)
         {
-            _cosmos = cosmos;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -32,8 +32,8 @@ namespace TEAMModelGrpc.Services
         [Authorize]
         public async Task<HomeworkRecord> StudentScoring(HomeworkCommentDto homeWorkCommentDto, ServerCallContext context) 
         {
-            List<HomeworkRecord> homeWorkStudents = await _cosmos.FindByDict<HomeworkRecord>(new Dictionary<string, object> { { "code", homeWorkCommentDto.homeWorkId }, { "id", homeWorkCommentDto.homeWorkId } });
-            List<Homework> homeWorks = await _cosmos.FindByDict<Homework>(new Dictionary<string, object> { { "id", homeWorkCommentDto.homeWorkId } });
+            List<HomeworkRecord> homeWorkStudents = await _azureCosmos.FindByDict<HomeworkRecord>(new Dictionary<string, object> { { "code", homeWorkCommentDto.homeWorkId }, { "id", homeWorkCommentDto.homeWorkId } });
+            List<Homework> homeWorks = await _azureCosmos.FindByDict<Homework>(new Dictionary<string, object> { { "id", homeWorkCommentDto.homeWorkId } });
             HomeworkRecord data = new HomeworkRecord();
 
             if (homeWorks.IsNotEmpty() && homeWorks[0].other.Contains("comment"))
@@ -70,7 +70,7 @@ namespace TEAMModelGrpc.Services
                         }
                     }
                     //homeWorkStudents[0].comments[request.@params.TEAMModelId] = request.@params.comment;
-                    data = await _cosmos.Update(homeWorkStudents[0]);
+                    data = await _azureCosmos.Update(homeWorkStudents[0]);
                 }
                 return data;
             }
@@ -87,7 +87,7 @@ namespace TEAMModelGrpc.Services
         public async Task<HomeworkRecord> TeacherScoring(HomeworkScoringDto homeWorkCommentDto, ServerCallContext context)
         {
 
-            List<HomeworkRecord> homeWorkStudents = await _cosmos.FindByDict<HomeworkRecord>(new Dictionary<string, object> { { "code", homeWorkCommentDto.studentId }, { "id", homeWorkCommentDto.homeWorkId } });
+            List<HomeworkRecord> homeWorkStudents = await _azureCosmos.FindByDict<HomeworkRecord>(new Dictionary<string, object> { { "code", homeWorkCommentDto.studentId }, { "id", homeWorkCommentDto.homeWorkId } });
             HomeworkRecord data = new HomeworkRecord();
             if (homeWorkStudents.IsNotEmpty())
             {
@@ -101,7 +101,7 @@ namespace TEAMModelGrpc.Services
                 };
 
                 homeWorkStudents[0].tchCmt = homeWorkComment;
-                data = await _cosmos.SaveOrUpdate(homeWorkStudents[0]);
+                data = await _azureCosmos.SaveOrUpdate(homeWorkStudents[0]);
 
             }
             return data;
@@ -120,7 +120,7 @@ namespace TEAMModelGrpc.Services
             Dictionary<string, object> keyValuePairs = dict.ToDict();
             List<Comment> teacherComments = new List<Comment>();
             if (keyValuePairs.IsNotEmpty()) {
-                teacherComments = await _cosmos.FindByDict<Comment>(keyValuePairs);
+                teacherComments = await _azureCosmos.FindByDict<Comment>(keyValuePairs);
                 if (teacherComments.IsNotEmpty()) {
                     teacherComments.ForEach(x=> { 
                         responseStream.WriteAsync(x);

+ 2 - 2
TEAMModelGrpc/Startup.cs

@@ -91,13 +91,13 @@ namespace TEAMModelGrpc
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
-        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AzureCosmosFactory cosmosDBV3Repository)
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
         {
             if (env.IsDevelopment())
             {
                 app.UseDeveloperExceptionPage();
             }
-            cosmosDBV3Repository.InitializeDatabase();
+            
             app.UseRouting();
 
             //注册 ASP.NET Core 身份验证中间件的顺序很重要。 

+ 22 - 0
TEAMModelOS.SDK/Extension/HttpContextExtensions.cs

@@ -90,5 +90,27 @@ namespace TEAMModelOS.SDK.Extension
         {            
                 return httpContext?.Request?.Host.ToString();          
         }
+
+        /// <summary>
+        /// 设置本地cookie
+        /// </summary>
+        /// <param name="key">键</param>
+        /// <param name="value">值</param>  
+        /// <param name="minutes">过期时长,单位:分钟</param>      
+        public static void SetCookies(HttpResponse Response, string key, string value, int minutes = 30)
+        {
+            Response.Cookies.Append(key, value, new CookieOptions
+            {
+                Expires = DateTime.Now.AddMinutes(minutes)
+            });
+        }
+        /// <summary>
+        /// 删除指定的cookie
+        /// </summary>
+        /// <param name="key">键</param>
+        public static void DeleteCookies(HttpContext httpContext, string key)
+        {
+            httpContext.Response.Cookies.Delete(key);
+        }
     }
 }

TEAMModelOS.SDK/Helper/Network/HttpHelper/JsonContent.cs → TEAMModelOS.SDK/Extension/JsonContent.cs


+ 0 - 39
TEAMModelOS.SDK/Extension/JwtAuth/Filters/BlackListJwtSecurityTokenHandler.cs

@@ -1,39 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-using System;
-using System.Collections.Generic;
-using System.IdentityModel.Tokens.Jwt;
-using System.Security.Claims;
-using System.Text;
-using TEAMModelOS.SDK.Context.Exception;
-using TEAMModelOS.SDK.Helper.Security.ShaHash;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Filters
-{
-    public class BlackListJwtSecurityTokenHandler : JwtSecurityTokenHandler
-    {
-
-
-        public BlackListJwtSecurityTokenHandler()
-        {
-
-        }
-
-        public override ClaimsPrincipal ValidateToken(string token, TokenValidationParameters validationParameters,
-            out SecurityToken validatedToken)
-        {
-            var claimsPrincipal = base.ValidateToken(token, validationParameters, out validatedToken);
-
-            //解析ClaimsPrincipal取出UserId、Iat和Jti
-            //具体的验证步骤有两个:
-            //- 到Redis查找该用户的Token失效时间,如果当前Token的颁发时间在此之前就是无效的;
-            //- 到Redis的黑名单里判断是否存在该Token; 
-            //通过Redis验证Token
-            string sha = ShaHashHelper.GetSHA1(token);
-            if (RedisHelper.Exists("jwt:" + sha))
-            {
-                throw new BizException("登录失效!", 401);
-            }
-            return claimsPrincipal;
-        }
-    }
-}

+ 0 - 54
TEAMModelOS.SDK/Extension/JwtAuth/Filters/JwtAuthorizationFilter.cs

@@ -1,54 +0,0 @@
-using TEAMModelOS.SDK.Extension.JwtAuth.Models;
-using Microsoft.AspNetCore.Http;
-using System;
-using System.Collections.Generic;
-using System.Security.Claims;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Filters
-{
-    public class JwtAuthorizationFilter
-    {
-        private readonly RequestDelegate _next;
-        public JwtAuthorizationFilter(RequestDelegate next)
-        {
-            _next = next;
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="httpContext"></param>
-        /// <returns></returns>
-        public Task Invoke(HttpContext httpContext)
-        {
-            //检测是否包含'Authorization'请求头,如果不包含则直接放行
-            if (!httpContext.Request.Headers.ContainsKey(HttpConstant.Authorization) &&!httpContext.Request.Query.ContainsKey(HttpConstant.access_token))
-            {
-                return _next(httpContext);
-            }
-            var tokenHeader = "";
-            if (httpContext.Request.Headers.ContainsKey(HttpConstant.Authorization))
-            {
-                tokenHeader = httpContext.Request.Headers[HttpConstant.Authorization];
-                tokenHeader = tokenHeader.Replace("Bearer ", "");
-            }
-            if (httpContext.Request.Query.ContainsKey(HttpConstant.access_token))
-            {
-                tokenHeader = httpContext.Request.Query[HttpConstant.access_token];
-                //tokenHeader = tokenHeader.Trim();
-            }
-            ClaimModel claimModel = JwtHelper.JwtHelper.SerializeJWT(tokenHeader);
-
-            //将tokenModel存入缓存中
-            //授权
-            //已经弃用该方式获取User信息,采用官方认证,必须在上边ConfigureService 中,配置JWT的认证服务 (.AddAuthentication 和 .AddJwtBearer 二者缺一不可)
-            //var identity = new ClaimsIdentity(claimModel.Claims);
-            //var principal = new ClaimsPrincipal(identity);
-            //httpContext.User = principal;
-
-            return _next(httpContext);
-        }
-    }
-}

+ 0 - 100
TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs

@@ -1,100 +0,0 @@
-using TEAMModelOS.SDK.Extension.JwtAuth.Models;
-using IdentityModel;
-using Microsoft.AspNetCore.Authentication.JwtBearer;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.IdentityModel.Tokens;
-using System;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Context.Configuration;
-using TEAMModelOS.SDK.Helper.Security.RSACrypt;
-using TEAMModelOS.SDK.Extension.JwtAuth.Filters;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth
-{
-    public static class JwtAuthExtension
-    {
-        public static void JwtAuth(this IServiceCollection services , IConfigurationSection configuration)
-        {
-            services.Configure<JwtSetting>(configuration);
-            // var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]), SecurityAlgorithms.RsaSha256Signature);
-            //var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]));
-            string path = BaseConfigModel.ContentRootPath;
-           // RsaSecurityKey creds = new RsaSecurityKey(RsaHelper.LoadCertificateFile(path + "/private.pem"));
-
-            SecurityKey creds = RsaHelper.GenerateValidationKey(path + "/public.pem");
-            //RsaSecurityKey creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"])), SecurityAlgorithms.RsaSha256Signature);
-            // 令牌验证参数
-            var tokenValidationParameters = new TokenValidationParameters
-            {
-                NameClaimType = JwtClaimTypes.Name,
-                RoleClaimType = JwtClaimTypes.Role,
-                ValidateIssuerSigningKey = true,
-                IssuerSigningKey = creds,
-                ValidateIssuer = true,
-                ValidIssuer = configuration["Issuer"],//发行人
-                ValidateAudience = true,
-                ValidAudience = configuration["Audience"],//订阅人
-                                                           // 是否验证Token有效期,使用当前时间与Token的Claims中的NotBefore和Expires对比
-                ValidateLifetime = true,
-                //允许的服务器时间偏移量
-                ClockSkew = TimeSpan.Zero,
-                //是否要求Token的Claims中必须包含Expires
-                RequireExpirationTime = true,
-            };
-            services.AddAuthentication(x => {
-                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
-                x.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
-                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
-            }).AddJwtBearer(o =>
-            {
-                ///https://blog.csdn.net/sinat_14899485/article/details/88591848 jwt 黑名单
-                //o.SecurityTokenValidators.Clear();
-                o.SecurityTokenValidators.Add(new BlackListJwtSecurityTokenHandler()); /// 自定义黑名单拦截
-                o.TokenValidationParameters = tokenValidationParameters;
-                o.Events = new JwtBearerEvents
-                {
-                    OnAuthenticationFailed = context =>
-                    {
-                        // 如果过期,则把<是否过期>添加到,返回头信息中
-                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
-                        {
-                            context.Response.Headers.Add("Token-Expired", "true");
-                        }
-                        return Task.CompletedTask;
-                    },
-                    //Url中添加access_token=[token],直接在浏览器中访问
-                    OnMessageReceived = context => {
-                        context.Token = context.Request.Query["access_token"];
-                        return Task.CompletedTask;
-                    },
-                    //URL未授权调用
-                    OnChallenge = context => {
-                        return Task.CompletedTask;
-                    },
-                    //在Token验证通过后调用
-                    OnTokenValidated = context => {
-                        //编写业务
-                        return Task.CompletedTask;
-                    },
-
-                };
-            });
-            if (services == null) throw new ArgumentNullException(nameof(services));
-            // 1【授权】、这个和上边的异曲同工,好处就是不用在controller中,写多个 roles 。
-            // 然后这么写 [Authorize(Policy = "Admin")]
-            services.AddAuthorization(options =>
-            {
-                //options.AddPolicy(Constant.Role_Root, policy => policy.RequireRole("root").Build());
-                //options.AddPolicy(Constant.Role_Admin, policy => policy.RequireRole("admin").Build());
-                //options.AddPolicy(Constant.Role_Lecturer, policy => policy.RequireRole("lecturer").Build());
-                //options.AddPolicy(Constant.Role_Learner, policy => policy.RequireRole("learner").Build());
-                //options.AddPolicy(Constant.Role_RootAdmin, policy => policy.RequireRole("root", "admin").Build());
-                //options.AddPolicy(Constant.Role_WebAll, policy => policy.RequireRole("root", "admin", "lecturer").Build());
-                //options.AddPolicy(Constant.Role_LecturerLearner, policy => policy.RequireRole("lecturer", "learner").Build());
-
-            });
-        }
-    }
-}

+ 0 - 106
TEAMModelOS.SDK/Extension/JwtAuth/JwtHelper/JwtHelper.cs

@@ -1,106 +0,0 @@
-using TEAMModelOS.SDK.Extension.JwtAuth.Models;
-using IdentityModel;
-using Microsoft.IdentityModel.Tokens;
-using System;
-using System.Collections.Generic;
-using System.IdentityModel.Tokens.Jwt;
-using System.Linq;
-using System.Security.Claims;
-using System.Text;
-using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
-using TEAMModelOS.SDK.Context.Configuration;
-using System.Security.Cryptography;
-using TEAMModelOS.SDK.Helper.Security.RSACrypt;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper
-{
-    public class JwtHelper
-    {
-        /// <summary>
-        /// 颁发JWT Token
-        /// </summary>
-        /// <param name="claimModel"></param>
-        /// <param name="tokenModel"></param>
-        /// <returns></returns>
-        public static JwtResponse IssueJWT(ClaimModel claimModel, JwtSetting setting)
-        {
-           // JwtClient jwtClient = null;
-
-            JwtClient jwtClient= setting.JwtClient.Where(x => x.Name.Equals(claimModel.Scope)).First();
-            //foreach (JwtClient client in setting.JwtClient) {
-            //    if (claimModel.Scope.Equals(client.Name)) {
-            //        jwtClient = client;
-            //        break; 
-            //    }
-            //}
-            List<Claim> claims = new List<Claim>();
-            var dateTime = DateTimeHelper.ConvertToTimeStamp10(DateTime.Now);
-            claims.AddRange(claimModel.Claims);
-            claims.Add(new Claim(JwtClaimTypes.IssuedAt, dateTime + "", ClaimValueTypes.Integer64));
-            claims.Add(new Claim(JwtClaimTypes.NotBefore, dateTime + "", ClaimValueTypes.Integer64));
-            claims.Add(new Claim(JwtClaimTypes.Expiration, dateTime + jwtClient.Exp + "", ClaimValueTypes.Integer64));
-            claims.Add(new Claim(JwtClaimTypes.Audience, setting.Audience));
-            claims.Add(new Claim(JwtClaimTypes.Issuer, setting.Issuer));
-            claims.Add(new Claim(JwtClaimTypes.Scope, claimModel.Scope));
-            claims.Add(new Claim(JwtClaimTypes.JwtId, Guid.NewGuid().ToString()));
-            //claims.AddRange(claimModel.Roles.Select(s=>new Claim(JwtClaimTypes.Role, s)));
-            //claims.AddRange(claimModel.Claims.Select(s => new Claim(ClaimTypes.Role, s)));
-            string path = BaseConfigModel.ContentRootPath;
-            var creds = RsaHelper.GenerateSigningCredentials(path + "/private.pem");
-            var jwt = new JwtSecurityToken(
-                issuer: setting.Issuer,
-                claims:claims,
-                signingCredentials:creds
-                );
-            var jwtHandler = new JwtSecurityTokenHandler();
-            return new JwtResponse {
-                Access_token = jwtHandler.WriteToken(jwt),
-                Scope = claimModel.Scope
-            };
-        }
-        /// <summary>
-        /// 解析jwt
-        /// </summary>
-        /// <param name="jwtStr"></param>
-        /// <returns></returns>
-        public static ClaimModel SerializeJWT(string jwtStr)
-        {
-
-            ///https://www.cnblogs.com/JacZhu/p/6837676.html#Update2.0  刷新     用户的 Token 在过期时间之内根本无法手动设置失效,随之而来的还有重放攻击等等问题
-
-
-            var jwtHandler = new JwtSecurityTokenHandler();
-            if (string.IsNullOrEmpty(jwtStr)) {
-                return null;
-            }
-            JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
-            object role = new object(); ;
-            jwtToken.Payload.TryGetValue(ClaimTypes.Role, out role);
-          
-            //var tm = new TokenModelJWT
-            //{
-            //    Uid = (jwtToken.Id).ObjToInt(),
-            //    Role = role != null ? role.ObjToString() : "",
-            //};
-
-
-
-           // var jwtHandler = new JwtSecurityTokenHandler();
-           // JwtSecurityToken jwtToken = jwtHandler.ReadJwtToken(jwtStr);
-            ClaimModel claimModel = new ClaimModel();
-            //object role = new object();
-           // claimModel.Claim = jwtToken.Claims.ToDictionary(claim => claim.Type, claim => claim.Value);
-            Dictionary<string, object> claimDict = new Dictionary<string, object>();
-            foreach (Claim claim in jwtToken.Claims)
-            {
-                claimDict.TryAdd(claim.Type, claim.Value);
-            }
-            claimDict[ClaimTypes.Role] = role;
-            claimModel.Claim = claimDict;
-            claimModel.Claims = jwtToken.Claims.ToList();
-            jwtToken.Payload.TryGetValue(JwtClaimTypes.Role, out role);
-            if(role!=null)claimModel.Roles=role.ToString().Split(",").ToList();
-            return claimModel;
-        }
-    }
-}

+ 0 - 33
TEAMModelOS.SDK/Extension/JwtAuth/Models/ClaimModel.cs

@@ -1,33 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Security.Claims;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    public class ClaimModel
-    {
-        public ClaimModel() {
-            Claims = new List<Claim>();
-            Claim = new Dictionary<string, object>();
-            Roles = new List<string>();
-        }
-
-
-        /// <summary>
-        /// 用户身份信息
-        /// </summary>
-        public List<Claim> Claims { get; set; }
-        /// <summary>
-        /// 用户身份信息
-        /// </summary>
-        public Dictionary<string ,object> Claim { get; set; }
-        /// <summary>
-        /// 用户角色信息
-        /// </summary>
-        public List<string> Roles { get; set; }
-        /// <summary>
-        /// 令牌类型
-        /// </summary>
-        public string Scope { get; set; }
-    }
-}

+ 0 - 12
TEAMModelOS.SDK/Extension/JwtAuth/Models/HttpConstant.cs

@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    public class HttpConstant
-    {
-        public static readonly string Authorization = "Authorization";
-        public static readonly string access_token = "access_token";
-    }
-}

+ 0 - 14
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtBlackRecord.cs

@@ -1,14 +0,0 @@
-using Microsoft.Azure.Cosmos.Table;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Context.Attributes.Azure;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    [TableNameAttribute(Name = "CommonJwtBlackRecord")]
-    public class JwtBlackRecord :TableEntity
-    {
-        public string Jti { get; set; } 
-    }
-}

+ 0 - 12
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtClient.cs

@@ -1,12 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    public class JwtClient
-    {
-        public string Name { get; set; }
-        public double Exp { get; set; }
-    }
-}

+ 0 - 15
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtResponse.cs

@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Context.Constant.Common;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    public class JwtResponse
-    {
-        public string Access_token { get; set; }
-        public string Token_type { get; set; } = "Bearer";
-        public string Token_key { get; set; } =Constants.AUTHORIZATION;
-        public string Scope { get; set; }
-    }
-}

+ 0 - 30
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtSetting.cs

@@ -1,30 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-    public class JwtSetting
-    {
-        /// <summary>
-        /// 项目名称
-        /// </summary>
-       // public string Project { get; set; }
-        /// <summary>
-        /// JwtClient
-        /// </summary>
-        public List<JwtClient> JwtClient { get; set; }
-        /// <summary>
-        /// WT的接收对象
-        /// </summary>
-        public string Audience { get; set; }
-        /// <summary>
-        /// JWT的签发主体
-        /// </summary>
-        public string Issuer { get; set; }
-        /// <summary>
-        /// JWT Secret Key
-        /// </summary>
-        //public string SecurityKey { get; set; }
-    }
-}

+ 0 - 15
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtTokenOptions.cs

@@ -1,15 +0,0 @@
-using Microsoft.IdentityModel.Tokens;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
-{
-     public  class JwtTokenOptions
-    {
-        public string Audience { get; set; }
-        public RsaSecurityKey Key { get; set; }
-        public SigningCredentials Credentials { get; set; }
-        public string Issuer { get; set; }
-    }
-}

+ 86 - 0
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -0,0 +1,86 @@
+using IdentityModel;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.IdentityModel.Tokens;
+using System;
+using System.Threading.Tasks;
+using System.Security.Claims;
+using System.IdentityModel.Tokens.Jwt;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.SDK.Extension
+{
+    public static class JwtAuthExtension
+    {
+        public static string CreateAuthToken(string issuer, string userID, string salt, string[] roles = null, string[] permissions = null, int expire = 1)
+        {
+            // 設定要加入到 JWT Token 中的聲明資訊(Claims)
+            var claims = new List<Claim>();
+            // 在 RFC 7519 規格中(Section#4),總共定義了 7 個預設的 Claims
+            claims.Add(new Claim(JwtRegisteredClaimNames.Iss, issuer)); //發行者
+            claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userID)); // 用戶ID            
+            claims.Add(new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString())); // 到期的時間,必須為數字
+
+            // 擴充 "roles" 加入登入者的角色,角色類型 (USER、HABOOK) 
+            foreach (var role in roles)
+            {
+                claims.Add(new Claim("roles", role));
+            }
+            // 擴充 "permissions" 加入登入者的權限請求  
+
+            foreach (var role in permissions)
+            {
+                claims.Add(new Claim("permissions", role));
+            }           
+
+            // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
+            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
+            // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
+            // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
+            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
+            // 建立 SecurityTokenDescriptor
+            var tokenDescriptor = new SecurityTokenDescriptor
+            {                
+                Issuer = issuer,
+                Subject = new ClaimsIdentity(claims),
+                Expires = DateTime.Now.AddHours(expire),
+                SigningCredentials = signingCredentials
+            };
+
+            // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
+            var tokenHandler = new JwtSecurityTokenHandler();
+            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
+            var serializeToken = tokenHandler.WriteToken(securityToken);
+
+            return serializeToken;
+        }
+
+        public static bool ValidateAuthToken(string token, string salt)
+        {
+            try
+            {
+                var handler = new JwtSecurityTokenHandler();
+                var validationParameters = new TokenValidationParameters
+                {
+                    RequireExpirationTime = true,
+                    ValidateIssuer = false,
+                    ValidateAudience = false,
+                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt)),
+                    ValidateLifetime = false,
+                    //LifetimeValidator = LifetimeValidator,
+                    ClockSkew = TimeSpan.Zero
+                };
+                ClaimsPrincipal principal = handler.ValidateToken(token, validationParameters, out SecurityToken securityToken);
+                return true;
+            }
+            catch (Exception ex)
+            {
+                //Trace.WriteLine(ex.Message);
+                return false;
+            }
+        }
+    }
+}

+ 6 - 0
TEAMModelOS.SDK/Extension/Utils.cs

@@ -1,6 +1,9 @@
 using Microsoft.AspNetCore.Cryptography.KeyDerivation;
+using Microsoft.IdentityModel.Tokens;
 using System;
 using System.Collections.Generic;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
 using System.Security.Cryptography;
 using System.Text;
 
@@ -82,6 +85,7 @@ namespace TEAMModelOS.SDK.Extension
             }
             return d;
         }
+        
 
         private static int SetRandomSeeds(int length)
         {
@@ -90,5 +94,7 @@ namespace TEAMModelOS.SDK.Extension
             _random.GetBytes(array);
             return (int)(Math.Abs(BitConverter.ToInt64(array, 0)) / maxValue * length);
         }
+
+
     }
 }

+ 0 - 148
TEAMModelOS.SDK/Helper/Network/HttpHelper/HttpContextHelper.cs

@@ -1,148 +0,0 @@
-using Microsoft.AspNetCore.Http;
-using Microsoft.Extensions.Primitives;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Claims;
-using TEAMModelOS.SDK.Context.Constant.Common;
-using TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper;
-using TEAMModelOS.SDK.Extension.JwtAuth.Models;
-
-namespace TEAMModelOS.SDK.Helper.Network.HttpHelper
-{
-    public static class HttpContextHelper
-    {
-        /// <summary>
-        /// 设置本地cookie
-        /// </summary>
-        /// <param name="key">键</param>
-        /// <param name="value">值</param>  
-        /// <param name="minutes">过期时长,单位:分钟</param>      
-        public static void SetCookies(HttpResponse Response, string key, string value, int minutes = 30)
-        {
-            Response.Cookies.Append(key, value, new CookieOptions
-            {
-                Expires = DateTime.Now.AddMinutes(minutes)
-            });
-        }
-        /// <summary>
-        /// 删除指定的cookie
-        /// </summary>
-        /// <param name="key">键</param>
-        public static void DeleteCookies(HttpContext httpContext, string key)
-        {
-            httpContext.Response.Cookies.Delete(key);
-        }
-
-        /// <summary>
-        /// 在Http中获取值
-        /// </summary>
-        /// <param name="key">键</param>
-        /// <returns>返回对应的值</returns>
-        public static string GetValueInHttp(HttpRequest Request, string key)
-        {
-            string aktoken = "";
-            if (string.IsNullOrEmpty(aktoken))
-            {
-                //或者在头获取
-                Request.Headers.TryGetValue(key, out StringValues akh);
-                if (!string.IsNullOrEmpty(akh))
-                {
-                    aktoken = akh;
-                }
-            }
-            if (string.IsNullOrEmpty(aktoken))
-            {
-                //其次在参数中获取
-                Request.Query.TryGetValue(key, out StringValues ak);
-                if (!string.IsNullOrEmpty(ak))
-                {
-                    aktoken = ak;
-                }
-            }
-            //从cookie获取
-            if (string.IsNullOrEmpty(aktoken))
-            {
-                Request.Cookies.TryGetValue(key, out string value);
-                if (!string.IsNullOrEmpty(value))
-                {
-                    aktoken = value;
-                }
-            }
-            if (string.IsNullOrEmpty(aktoken))
-            {
-                //在referer获取
-                Request.Headers.TryGetValue("referer", out StringValues referer);
-                string token = "";
-                if (referer.Contains(key + "="))
-                {
-                    string[] pramas = referer[0].Substring(referer[0].IndexOf(key + "=")).Split("&");
-                    int len = pramas.Count();
-                    if (len > 0)
-                    {
-                        for (int i = 0; i < len; i++)
-                        {
-                            if (pramas[i].Contains(key))
-                            {
-                                token = pramas[i].Split("=")[1];
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (!string.IsNullOrEmpty(token))
-                {
-                    aktoken = token;
-                }
-            }
-            return aktoken;
-        }
-        public static List<string> GetLoginUser(IHttpContextAccessor httpContextAccessor ,string claimType) {
-            var tokenHeader = "";
-            HttpRequest request = httpContextAccessor.HttpContext.Request;
-            if (request.Headers.ContainsKey(Constants.AUTHORIZATION))
-            {
-                tokenHeader = request.Headers[Constants.AUTHORIZATION];
-                //tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
-                tokenHeader = tokenHeader.Replace("Bearer ", "");
-            }
-            if (request.Query.ContainsKey(Constants.ACCESS_TOKEN))
-            {
-                tokenHeader = request.Query[Constants.ACCESS_TOKEN];
-                //tokenHeader = tokenHeader;
-            }
-            if (string.IsNullOrEmpty(tokenHeader))
-            {
-                return null;
-            }
-            ClaimModel claimModel = JwtHelper.SerializeJWT(tokenHeader);
-            claimModel.Claim.TryGetValue(claimType, out var claimValue);
-            List<string> claimValues = new List<string>();
-            foreach (Claim claim in claimModel.Claims)
-            {
-                if (claim.Type.Equals(claimType))
-                {
-                    claimValues.Add(claim.Value);
-                }
-            }
-            return claimValues;
-        }
-        public static string GetAuthorizationCode(IHttpContextAccessor httpContextAccessor)
-        {
-            var tokenHeader = "";
-            HttpRequest request = httpContextAccessor.HttpContext.Request;
-            if (request.Headers.ContainsKey(Constants.AUTHORIZATION))
-            {
-                tokenHeader = request.Headers[Constants.AUTHORIZATION];
-                //tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
-                tokenHeader = tokenHeader.Replace("Bearer ", "");
-            }
-            if (request.Query.ContainsKey(Constants.ACCESS_TOKEN))
-            {
-                tokenHeader = request.Query[Constants.ACCESS_TOKEN];
-                tokenHeader = tokenHeader.Trim();
-            }
-            return tokenHeader;
-        }
-    }
-}

+ 1 - 1
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteBar.vue

@@ -78,7 +78,7 @@
                     series: [{
                         type: 'bar',
                         data: data.map(item => item.value),
-                        barWidth: 50, //柱子宽度
+                        barMaxWidth: 80, //柱子宽度
                         itemStyle: {
                             normal: {
                                 color: new that.$echarts.graphic.LinearGradient(0, 0, 0, 1, [{

+ 18 - 0
TEAMModelOS/ClientApp/src/components/learnactivity/BaseVoteForm.less

@@ -214,6 +214,7 @@
         margin-top: 10px;
 
         .option-order {
+			position: relative;
             display: inline-block;
             min-height: 42px;
             width: 10%;
@@ -223,6 +224,23 @@
             text-align: center;
             line-height: 42px;
             border-right: 1px solid #4e4e4e;
+			
+			&:hover{
+				.ivu-icon{
+					display: unset;
+				}
+			}
+			
+			.ivu-icon{
+				position: absolute;
+				top: 50%;
+				left: 50%;
+				transform: translate(-50%,-50%);
+				font-size: 20px;
+				color:#fff;
+				display: none;
+				cursor: pointer;
+			}
         }
 
         .option-editor {

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

@@ -37,8 +37,15 @@
 
             <FormItem label="选项设置" prop="attachment">
                 <div v-for="(item,index) in voteOptions" :key="index" class="option-editor-wrap">
-                    <span class="option-order">{{ index + 1 }}</span>
-                    <div :ref="'voteOption'+index" style="text-align:left" class="option-editor" @click="optionClick(index)"></div>
+					<div v-show="voteFormEdit">
+						<span class="option-order">{{ index + 1 }}<Icon type="md-trash" @click="deleteOption(index)"/></span>
+						<div :ref="'voteOption'+index" style="text-align:left" class="option-editor" @click="optionClick(index)"></div>
+					</div>
+					<div v-show="!voteFormEdit">
+						<span style="color:#fff;margin-left: 10px;">{{ index + 1 }} .</span>
+						<div v-html="(voteOptionsContent[index]) ? voteOptionsContent[index].value : ''" v-show="!voteFormEdit" style="margin:10px;font-size:16px;font-weight:bold;color:#fff;display: inline-block;"></div>
+					</div>
+                    
                 </div>
                 <p style="float:right;color:#BDBDBD;cursor:pointer" @click="onAddOption" v-show="voteFormEdit"><Icon type="md-add" />添加选项</p>
             </FormItem>
@@ -121,7 +128,7 @@
                     name: "",
                     target: [],
                     publishModel: "0",
-					status:100,
+					status:0,
                     startTime: 0,
                     endTime: 0,
                     resource: []
@@ -253,7 +260,7 @@
 
                             // 如果是编辑状态 则将选项内容回显
                             if (this.editInfo) {
-                                editor.txt.html(this.editInfo.option[i].value)
+                                editor.txt.html(this.voteOptionsContent[i].value)
                             }
                         })
                         }
@@ -273,6 +280,15 @@
                     currentToolBar.style.visibility = 'visible'
                 }, 100)
             },
+			
+			// 删除选项
+			deleteOption(index) {
+				this.voteOptions.splice(index, 1)
+				this.voteOptionsContent.splice(index, 1)
+				this.$nextTick(() => {
+				    this.initEditors()
+				})
+			},
 
             // 添加选项
             onAddOption() {

+ 1 - 2
TEAMModelOS/ClientApp/src/view/evaluation/components/BaseCreateChild.vue

@@ -264,8 +264,7 @@
 					.state.userInfo.schoolCode
 
 				// 判断获取的数据是否有空数据以及是否为空字符串
-				if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question) && this.getSimpleText(
-						exerciseItem.explain)) {
+				if (this.checkContent(exerciseItem) && this.getSimpleText(exerciseItem.question)) {
 					// this.saveLoading = true
 					this.$emit('addFinish', exerciseItem)
 				} else {

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

@@ -90,7 +90,7 @@
 										<span v-if="! (_.compact(item.points).length)">暂未绑定知识点</span>
 										<div v-else>
 											<span v-for="point in item.points" class="item-point-tag">
-												<span v-if="allPointList.length">{{ allPointList.filter(i => i.id === point)[0].name }}</span>
+												<span v-if="allPointList.length && allPointList.filter(i => i.id === point).length">{{ allPointList.filter(i => i.id === point)[0].name }}</span>
 											</span>
 										</div>
 									</div>
@@ -654,7 +654,7 @@
 	}
 
 	.components-el-container .exercise-item .item-explain-details {
-		width: 90%;
+		/* width: 90%; */
 	}
 
 	.components-el-container .exercise-item .item-tools-t .ivu-icon {

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

@@ -1,7 +1,7 @@
 <template>
 	<div class="create-evaluation-container">
 		<div class="create-header">
-			<p class="create-header-title">创建试卷</p>
+			<p class="create-header-title">{{ isEditPaper ? '编辑试卷' : '新建试卷'}}</p>
 			<div style="float: right;">
 				<Button class="btn-save" type="info" @click="goBack">返回试卷库</Button>
 				<Button class="btn-save" type="success" :loading="isLoading" @click="saveTestPaper">保存试卷</Button>
@@ -80,10 +80,10 @@
 						<TabPane label="学生作答预览" name="student" :index="5" tab="createTest">
 							<StudentPreview></StudentPreview>
 						</TabPane>
-						<span slot="extra" class="test-paper-analysis" @click="examAnalysisStatus = !examAnalysisStatus" v-show="activeTab == 'preview'">
+						<!-- <span slot="extra" class="test-paper-analysis" @click="examAnalysisStatus = !examAnalysisStatus" v-show="activeTab == 'preview'">
 							<Icon :type="examAnalysisStatus ? 'md-list-box':'md-stats'" style="margin-right:5px;" />
 							{{examAnalysisStatus ? '试卷预览':'试卷分析'}}
-						</span>
+						</span> -->
 					</Tabs>
 				</div>
 			</div>
@@ -116,6 +116,7 @@
 		data() {
 			return {
 				isLoading: false,
+				isEditPaper:false,
 				examAnalysisStatus: false,
 				comfirmPreviewStatus: false,
 				goToManageStatus: false,
@@ -537,6 +538,7 @@
 			let routerData = this.$route.params.paper
 			if (routerData) {
 				this.doRender(routerData)
+				this.isEditPaper = true
 				this.activeTab = 'preview'
 			}
 			

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

@@ -310,7 +310,8 @@
 }
 
 .exercise-item .item-explain .explain-title {
-	width: 80px;
+	width: 10%;
+	max-width: 78px;
 	display: inline-block;
     color: rgb(16, 171, 231);
 }

+ 4 - 0
TEAMModelOS/ClientApp/src/view/evaluation/types/BaseSingle.vue

@@ -144,6 +144,10 @@
                 } else {
                     this.$Message.warning('至少保留两个选项!')
                 }
+				
+				// this.$nextTick(() => {
+				//     this.initEditors()
+				// })
             },
 
             // 模拟选项聚焦事件

+ 1 - 1
TEAMModelOS/ClientApp/src/view/homework/ManageHomeWork.vue

@@ -220,7 +220,7 @@
 				//  先查找 作业发布对象关联的学生清单 然后再去判断学生的作答情况
 				this.$api.courseMgmt.getClassroomStudent({
 					classroomCode: target.map(i => i.classroomCode),
-					schoolCode: 'HBCN'
+					schoolCode: this.$store.state.userInfo.schoolCode
 				}).then(res => {
 					if (!res.error && res.result.data) {
 						let list = res.result.data

+ 6 - 6
TEAMModelOS/ClientApp/src/view/learnactivity/ExamPaperAnalysis.vue

@@ -17,10 +17,10 @@
                     <p class="while-table-question-type">主观题(占比)</p>
                 </div>
                 <div class="whole-table-col">
-                    <p class="while-table-question-type">{{examAnalysisData.whole.objectiveScore}}({{examAnalysisData.whole.objectiveScoreP}}%)</p>
-                    <p class="while-table-question-type">{{examAnalysisData.whole.subjectiveScore}}({{examAnalysisData.whole.subjectiveScoreP}}%)</p>
-                    <p class="while-table-question-type">{{examAnalysisData.whole.subjectiveNum}}({{examAnalysisData.whole.subjectiveNumP}}%)</p>
-                    <p class="while-table-question-type">{{examAnalysisData.whole.objectiveNum}}({{examAnalysisData.whole.objectiveNumP}}%)</p>
+                    <p class="while-table-question-type">{{examAnalysisData.whole.objectiveScore}}({{examAnalysisData.whole.objectiveScoreP}}%)</p>
+                    <p class="while-table-question-type">{{examAnalysisData.whole.subjectiveScore}}({{examAnalysisData.whole.subjectiveScoreP}}%)</p>
+                    <p class="while-table-question-type">{{examAnalysisData.whole.subjectiveNum}}({{examAnalysisData.whole.subjectiveNumP}}%)</p>
+                    <p class="while-table-question-type">{{examAnalysisData.whole.objectiveNum}}({{examAnalysisData.whole.objectiveNumP}}%)</p>
                 </div>
             </div>
         </div>
@@ -45,10 +45,10 @@
                         {{getQuestionLabel(index)}}
                     </div>
                     <div class="question-type-table-td">
-                        {{item.count}}({{item.countPercent}}%)
+                        {{item.count}}({{item.countPercent}}%)
                     </div>
                     <div class="question-type-table-td">
-                        {{item.score}}({{item.scorePercent}}%)
+                        {{item.score}}({{item.scorePercent}}%)
                     </div>
                 </div>
 

+ 53 - 20
TEAMModelOS/ClientApp/src/view/vote/ManageVote.vue

@@ -178,6 +178,8 @@
 										let jsonInfo = await that.$tools.getFile(i.url + sasString.sas)
 										let jsonData = JSON.parse(jsonInfo)
 										jsonData.id = i.id
+										jsonData.status = i.status
+										jsonData.startTime = i.startTime
 										jsonData.fileName = i.url.split('/')[i.url.split('/').length - 1].split('.json')[0]
 										that.$set(list, j, jsonData)
 									} catch (e) {
@@ -204,10 +206,8 @@
 			 */
 			onVoteClick(item, index) {
 				this.currentVote = item
-				console.log(item)
-				console.log(index)
 				this.activeHwIndex = index
-				if (item.id) this.getVoteStudents(item.id)
+				if (item.id) this.getVoteStudents(item.id,item.target)
 				this.$refs.voteForm.voteFormEdit = false
 				this.hasNewAdd = false
 			},
@@ -250,31 +250,64 @@
 			 * 获取投票关联的学生清单
 			 * @param voteId 投票ID
 			 */
-			getVoteStudents(voteId) {
-				this.$api.learnActivity.FindRecordByVoteId({
-					id: voteId
+			async getVoteStudents(voteId, target) {
+				this.isLoading = true
+				let records = await this.getVoteRecord(voteId)
+				//  先查找 投票发布对象关联的学生清单 然后再去判断学生的作答情况
+				this.$api.courseMgmt.getClassroomStudent({
+					classroomCode: target.map(i => i.classroomCode),
+					schoolCode: this.$store.state.userInfo.schoolCode
 				}).then(res => {
 					if (!res.error && res.result.data) {
-						this.studentsList = res.result.data
-						let arr = []
-						this.studentsTable = []
-						res.result.data.forEach((item,index) => {
-							arr.push({
-								// option: this.getSimpleText(item.optionValue),
-								option: item.optionKey ? '选项' + (index + 1) : '未投票',
-								key: item.optionKey || '',
-								result: item.students
-							})
-
-							this.studentsTable = this.studentsTable.concat(item.students)
+						let list = res.result.data
+						let infoList = res.result.extend.students
+						list.forEach(i => {
+							i.name = infoList.filter(j => j.studentId === i.code)[0].name
+							i.classroomName = target.filter(k => k.classroomCode === i.id)[0].classroomName
 						})
-						console.log(arr)
-						this.tableData = arr
+						// 要根据作答情况 结合两张表 处理表格显示的数据 
+						if (records.length) {
+							let arr = []
+							this.studentsTable = []
+							records.forEach((item,index) => {
+								arr.push({
+									// option: this.getSimpleText(item.optionValue),
+									option: item.optionKey ? '选项' + (index + 1) : '未投票',
+									key: item.optionKey || '',
+									result: item.students
+								})
+								this.studentsTable = this.studentsTable.concat(item.students)
+							})
+							this.studentsTable.forEach(i => {
+								let matchList = list.filter(j => j.code === i.code)
+								i.name = matchList.length ? matchList[0].name : '暂无数据'
+							})
+							this.tableData = arr
+						}else{
+							this.tableData = []
+						}
+						this.isLoading = false
 					} else {
 						this.$Message.error('获取数据失败')
+						this.isLoading = false
 					}
 				})
 			},
+			
+			/* 获取投票结果数据 */
+			getVoteRecord(voteId) {
+				return new Promise((r, j) => {
+					this.$api.learnActivity.FindRecordByVoteId({
+						id: voteId
+					}).then(res => {
+						if (!res.error && res.result.data) {
+							r(res.result.data)
+						} else {
+							j(500)
+						}
+					})
+				})
+			},
 
 			// 提取富文本内容中的文本
 			getSimpleText(html) {

+ 9 - 9
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -28,13 +28,13 @@ namespace TEAMModelOS.Controllers.Analysis
     public class AchievementController : Controller
     {
 
-        private readonly AzureCosmosFactory azureCosmosDBRepository;
+        private readonly AzureCosmosFactory _azureCosmos;
 
         private const string CacheCosmosPrefix = "Analysis:";
         private const int timeoutSeconds = 3600;
-        public AchievementController(AzureCosmosFactory _azureCosmosDBRepository)
+        public AchievementController(AzureCosmosFactory azureCosmos)
         {
-            azureCosmosDBRepository = _azureCosmosDBRepository;
+            _azureCosmos = azureCosmos;
 
 
         }
@@ -71,7 +71,7 @@ namespace TEAMModelOS.Controllers.Analysis
         {
             try
             {
-                List<ExamResult> info = await azureCosmosDBRepository.FindByDict<ExamResult>(dict);
+                List<ExamResult> info = await _azureCosmos.FindByDict<ExamResult>(dict);
                 if (RedisHelper.Instance != null)
                 {
                     if (!RedisHelper.Exists(CacheCosmosPrefix + method))
@@ -127,7 +127,7 @@ namespace TEAMModelOS.Controllers.Analysis
             };
             //声明进行标准用来设置进线标准,权重等参数
             dict.TryGetValue("Standard", out object Standard);
-            List<Student> students = await azureCosmosDBRepository.FindByDict<Student>(stuMap);
+            List<Student> students = await _azureCosmos.FindByDict<Student>(stuMap);
             //Console.WriteLine(DateTimeOffset.Now.Second);
             List<Dictionary<string, object>> examList = new List<Dictionary<string, object>>();
             HashSet<string> classList = new HashSet<string>();
@@ -1563,7 +1563,7 @@ namespace TEAMModelOS.Controllers.Analysis
         {
             try
             {
-                List<ExamInfo> info = await azureCosmosDBRepository.FindByDict<ExamInfo>(dict);
+                List<ExamInfo> info = await _azureCosmos.FindByDict<ExamInfo>(dict);
 
                 if (RedisHelper.Instance != null)
                 {
@@ -1627,7 +1627,7 @@ namespace TEAMModelOS.Controllers.Analysis
         {
             try
             {
-                List<Paper> info = await azureCosmosDBRepository.FindByDict<Paper>(dict);
+                List<Paper> info = await _azureCosmos.FindByDict<Paper>(dict);
                 if (RedisHelper.Instance != null)
                 {
                     if (!RedisHelper.Exists(CacheCosmosPrefix + method))
@@ -1668,7 +1668,7 @@ namespace TEAMModelOS.Controllers.Analysis
         {
             try
             {
-                List<ExamAnswer> info = await azureCosmosDBRepository.FindByDict<ExamAnswer>(dict);
+                List<ExamAnswer> info = await _azureCosmos.FindByDict<ExamAnswer>(dict);
                 if (RedisHelper.Instance != null)
                 {
                     if (!RedisHelper.Exists(CacheCosmosPrefix + method))
@@ -1694,7 +1694,7 @@ namespace TEAMModelOS.Controllers.Analysis
         {
             try
             {
-                List<ExamAnswer> info = await azureCosmosDBRepository.FindByDict<ExamAnswer>(dict);
+                List<ExamAnswer> info = await _azureCosmos.FindByDict<ExamAnswer>(dict);
                 if (RedisHelper.Instance != null)
                 {
                     if (!RedisHelper.Exists(CacheCosmosPrefix + "FindExamAnswer"))

+ 29 - 30
TEAMModelOS/Controllers/BaseController.cs

@@ -1,8 +1,6 @@
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Mvc;
 using System.Collections.Generic;
-using TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper;
-using TEAMModelOS.SDK.Extension.JwtAuth.Models;
 using TEAMModelOS.SDK.Context.Constant.Common;
 using System.Security.Claims;
 using TEAMModelOS.Service.Models;
@@ -19,34 +17,35 @@ namespace TEAMModelOS.Controllers
     {
         public List<string> GetLoginUser(string claimType)
         {
-            var tokenHeader = "";
-            HttpRequest request = HttpContext.Request;
-            if (request.Headers.ContainsKey(Constants.AUTHORIZATION))
-            {
-                tokenHeader = request.Headers[Constants.AUTHORIZATION];
-                //tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
-                tokenHeader = tokenHeader.Replace("Bearer ", "");
-            }
-            if (request.Query.ContainsKey(Constants.ACCESS_TOKEN))
-            {
-                tokenHeader = request.Query[Constants.ACCESS_TOKEN];
-                tokenHeader = tokenHeader.Trim();
-            }
-            if (string.IsNullOrEmpty(tokenHeader))
-            {
-                return null;
-            }
-            ClaimModel claimModel = JwtHelper.SerializeJWT(tokenHeader);
-            claimModel.Claim.TryGetValue(claimType, out var claimValue);
-            List<string> claimValues = new List<string>();
-            foreach (Claim claim in claimModel.Claims)
-            {
-                if (claim.Type.Equals(claimType))
-                {
-                    claimValues.Add(claim.Value);
-                }
-            }
-            return claimValues;
+            //var tokenHeader = "";
+            //HttpRequest request = HttpContext.Request;
+            //if (request.Headers.ContainsKey(Constants.AUTHORIZATION))
+            //{
+            //    tokenHeader = request.Headers[Constants.AUTHORIZATION];
+            //    //tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
+            //    tokenHeader = tokenHeader.Replace("Bearer ", "");
+            //}
+            //if (request.Query.ContainsKey(Constants.ACCESS_TOKEN))
+            //{
+            //    tokenHeader = request.Query[Constants.ACCESS_TOKEN];
+            //    tokenHeader = tokenHeader.Trim();
+            //}
+            //if (string.IsNullOrEmpty(tokenHeader))
+            //{
+            //    return null;
+            //}
+            //ClaimModel claimModel = JwtHelper.SerializeJWT(tokenHeader);
+            //claimModel.Claim.TryGetValue(claimType, out var claimValue);
+            //List<string> claimValues = new List<string>();
+            //foreach (Claim claim in claimModel.Claims)
+            //{
+            //    if (claim.Type.Equals(claimType))
+            //    {
+            //        claimValues.Add(claim.Value);
+            //    }
+            //}
+            //return claimValues;
+            return null;
         }
 
         public static bool ValidateIdToken(string token, string salt)

+ 0 - 27
TEAMModelOS/Controllers/Client/Attribute/AuthFilter.cs

@@ -1,27 +0,0 @@
-using Microsoft.AspNetCore.Mvc.Filters;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Mvc;
-using TEAMModelOS.SDK.Extension;
-
-namespace TEAMModelOS.Controllers.Client.Attribute
-{
-    public class AuthFilter : IResourceFilter
-    {
-        public void OnResourceExecuting(ResourceExecutingContext context)
-        {
-            var authtoken = context.HttpContext.GetXAuth("AuthToken");
-
-            context.Result = new ContentResult()
-            {
-                Content = "Resource unavailable - header not set."
-            };
-        }
-
-        public void OnResourceExecuted(ResourceExecutedContext context)
-        {
-        }
-    }    
-}

+ 78 - 0
TEAMModelOS/Controllers/Client/Filter/AuthTokenAttribute.cs

@@ -0,0 +1,78 @@
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using TEAMModelOS.SDK.Extension;
+using System;
+using TEAMModelOS.Models;
+using Microsoft.Extensions.Options;
+using Microsoft.Extensions.DependencyInjection;
+using System.IdentityModel.Tokens.Jwt;
+using System.Linq;
+
+namespace TEAMModelOS.Controllers.Client
+{
+    public class AuthTokenAttribute : Attribute, IFilterFactory
+    {
+        public bool IsReusable => true;
+        public string Roles { get; set; }
+        public string Permissions { get; set; }
+
+        public IFilterMetadata CreateInstance(IServiceProvider services)
+        {
+            var option = services.GetService<IOptions<Option>>();
+            return new InternalAuthTokenFilter(option, Roles, Permissions);
+        }
+
+        private class InternalAuthTokenFilter : IResourceFilter
+        {
+            private readonly Option _option;
+            private readonly string _roles ;
+            private readonly string _permissions ;
+
+            public InternalAuthTokenFilter(IOptions<Option> option, string roles, string permissions)
+            {
+                _option = option.Value;
+                _roles = roles;
+                _permissions = permissions;
+            }
+            public void OnResourceExecuting(ResourceExecutingContext context)
+            {
+                bool pass = false;
+                var authtoken = context.HttpContext.GetXAuth("AuthToken");
+                if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateAuthToken(authtoken, _option.JwtSecretKey))
+                {
+                    var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authtoken);
+                    if (!string.IsNullOrWhiteSpace(_roles))
+                    {
+                        var roles = jwt.Claims.Where(c => c.Type == "roles");
+                        foreach (var role in roles)
+                        {
+                            if (_roles.Contains(role.Value, StringComparison.OrdinalIgnoreCase))
+                            {
+                                pass = true;
+                                break;
+                            }
+                        }
+                    }
+                    if (!string.IsNullOrWhiteSpace(_permissions))
+                    {
+                        var permissions = jwt.Claims.Where(c => c.Type == "permissions");
+                        foreach (var permission in permissions)
+                        {                            
+                            if (_permissions.Contains(permission.Value, StringComparison.OrdinalIgnoreCase))
+                            {
+                                pass = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if (!pass) context.Result = new BadRequestResult();               
+            }
+
+            public void OnResourceExecuted(ResourceExecutedContext context)
+            {
+            }
+        }
+    }
+}

+ 30 - 25
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -91,6 +91,7 @@ namespace TEAMModelOS.Controllers.Client
                     //string teacher = Encoding.UTF8.GetString(stream.ToArray());
                     response = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOSTemp", "Teacher").CreateItemStreamAsync(stream, new PartitionKey("Base"));
                 }
+
                 List<object> courses = new List<object>();
                 await foreach (var item in client.GetContainer("TEAMModelOSTemp", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id, c.name, c.classes, c.notice ,c.scope from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-{id}") }))
                 {
@@ -103,6 +104,8 @@ namespace TEAMModelOS.Controllers.Client
                         }
                     }
                 }
+
+
                 List<object> syllabus = new List<object>();
                 await foreach (var item in client.GetContainer("TEAMModelOSTemp", "Teacher").GetItemQueryStreamIterator(queryText: $"select c.id, c.name, c.classes, c.notice ,c.scope from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{id}") }))
                 {
@@ -131,32 +134,34 @@ namespace TEAMModelOS.Controllers.Client
         }
 
 
-        //[ProducesResponseType(StatusCodes.Status200OK)]
-        //[ProducesResponseType(StatusCodes.Status400BadRequest)]
-        //[ProducesDefaultResponseType]
-        //[HttpPost("GetSchoolInfo")]
-        //public async Task<IActionResult> GetSchoolInfo(JsonElement requert)
-        //{
-        //    if (!requert.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
-        //    if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
-        //    var jwt = new JwtSecurityToken(id_token.GetString());
-        //    if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
-        //    var id = jwt.Payload.Sub;
-        //    jwt.Payload.TryGetValue("name", out object name);
-        //    jwt.Payload.TryGetValue("picture", out object picture);
-        //    object school = null;
-        //    //查找Teacher數據
-        //    var response = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOSTemp", "Teacher").ReadItemStreamAsync(id, new PartitionKey("Base"));
-        //    if (response.Status == 200)
-        //    {
-        //        using var json = await JsonDocument.ParseAsync(response.ContentStream);
-        //        if (json.RootElement.TryGetProperty("schools", out JsonElement schools))
-        //        {
-        //            school = schools.ToObject<object>();
-        //        }
-        //    }
+        [ProducesResponseType(StatusCodes.Status200OK)]
+        [ProducesResponseType(StatusCodes.Status400BadRequest)]
+        [ProducesDefaultResponseType]
+        [HttpPost("GetSchoolInfo")]
+        [AuthToken(Roles ="Admin,Teacher",Permissions = "classroom-read,classroom-upd")]
+        public async Task<IActionResult> GetSchoolInfo(JsonElement requert)
+        {
+            if (!requert.TryGetProperty("id_token", out JsonElement id_token)) return BadRequest();
+            //if (!requert.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
+            var jwt = new JwtSecurityToken(id_token.GetString());
+            if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
 
-        //}
+            var client = _azureCosmos.GetCosmosClient();
+            List<object> courses = new List<object>();
+            await foreach (var item in client.GetContainer("TEAMModelOSTemp", "School").GetItemQueryStreamIterator(queryText: $"select * from c where c.code = 'Course-hbcn' AND ARRAY_CONTAINS(c.teacherIds, 'jeffmk30033', true)", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Course-hbcn") }))
+            {
+                using var json = await JsonDocument.ParseAsync(item.ContentStream);
+                if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                {
+                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                    {
+                        courses.Add(obj.ToObject<object>());
+                    }
+                }
+            }
+            return Ok(new { courses });
+
+        }
 
         //[ProducesResponseType(StatusCodes.Status200OK)]
         //[ProducesResponseType(StatusCodes.Status400BadRequest)]

+ 1 - 53
TEAMModelOS/Controllers/Core/AuthController.cs

@@ -53,58 +53,6 @@
 //                BaseConfigModel.Configuration.GetSection("Option:Exp").Get<int>());
 //            return builder.Data(a).build();
 //        }
-
-//        public static string CreateToken(string userID, string salt, string[] roles = null, string[] permissions = null, int expire = 86400)
-//        {
-//            // 設定要加入到 JWT Token 中的聲明資訊(Claims)
-//            var claims = new List<Claim>();
-//            string iss = BaseConfigModel.Configuration["Option:Issuer"];
-//            // 在 RFC 7519 規格中(Section#4),總共定義了 7 個預設的 Claims
-//            claims.Add(new Claim(JwtRegisteredClaimNames.Iss, iss)); //發行者
-//            claims.Add(new Claim(JwtRegisteredClaimNames.Sub, userID)); // 用戶ID            
-//            claims.Add(new Claim(JwtRegisteredClaimNames.Exp, DateTimeOffset.UtcNow.AddHours(expire).ToUnixTimeSeconds().ToString())); // 到期的時間,必須為數字
-
-//            // 擴充 "roles" 加入登入者的角色,角色類型 (USER、HABOOK)   
-//            if (roles != null)
-//            {
-//                foreach (var role in roles)
-//                {
-//                    claims.Add(new Claim("roles", role));
-//                }
-//            }
-//            // 擴充 "permissions" 加入登入者的權限請求  
-//            if (permissions != null)
-//            {
-//                foreach (var role in permissions)
-//                {
-//                    claims.Add(new Claim("permissions", role));
-//                }
-//            }
-
-//            var userClaimsIdentity = new ClaimsIdentity(claims);
-
-//            // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用
-//            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(salt));
-
-//            // HmacSha256 有要求必須要大於 128 bits,所以 salt 不能太短,至少要 16 字元以上
-//            // https://stackoverflow.com/questions/47279947/idx10603-the-algorithm-hs256-requires-the-securitykey-keysize-to-be-greater
-//            var signingCredentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
-
-//            // 建立 SecurityTokenDescriptor
-//            var tokenDescriptor = new SecurityTokenDescriptor
-//            {
-//                Issuer = iss,
-//                Subject = userClaimsIdentity,
-//                Expires = DateTime.Now.AddSeconds(expire),
-//                SigningCredentials = signingCredentials
-//            };
-
-//            // 產出所需要的 JWT securityToken 物件,並取得序列化後的 Token 結果(字串格式)
-//            var tokenHandler = new JwtSecurityTokenHandler();
-//            var securityToken = tokenHandler.CreateToken(tokenDescriptor);
-//            var serializeToken = tokenHandler.WriteToken(securityToken);
-
-//            return serializeToken;
-//        }
+//        
 //    }
 //}

+ 5 - 5
TEAMModelOS/Controllers/Core/CommonController.cs

@@ -24,12 +24,12 @@ namespace TEAMModelOS.Controllers
     public class CommonController : BaseController
     {
 
-        private readonly AzureCosmosFactory azureCosmosDBRepository;
+        private readonly AzureCosmosFactory _azureCosmos;
         private readonly IWebHostEnvironment webHostEnvironment;
-        public CommonController(IWebHostEnvironment _webHostEnvironment, AzureCosmosFactory _azureCosmosDBRepository)
+        public CommonController(IWebHostEnvironment _webHostEnvironment, AzureCosmosFactory azureCosmos)
         {
             webHostEnvironment = _webHostEnvironment;
-            azureCosmosDBRepository = _azureCosmosDBRepository;
+            _azureCosmos = azureCosmos;
         }
        
 
@@ -80,7 +80,7 @@ namespace TEAMModelOS.Controllers
         public async  Task<BaseResponse> FindCollection(CommonQuery request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<dynamic>  data =  await  azureCosmosDBRepository.FindByDict(request.collectionName,request.queryDict);
+            List<dynamic>  data =  await _azureCosmos.FindByDict(request.collectionName,request.queryDict);
            // JsonElement json = JsonApiHelper.FromApiJson<JsonElement>( data.ToJson());
             return builder.Data(data).build();
         }
@@ -90,7 +90,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> FindCount(CommonQuery request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<dynamic> data = await  azureCosmosDBRepository.FindCountByDict(request.collectionName, request.queryDict);
+            List<dynamic> data = await _azureCosmos.FindCountByDict(request.collectionName, request.queryDict);
             return builder.Data(data).build();
         }
     }

+ 13 - 13
TEAMModelOS/Controllers/School/ClassRoomController.cs

@@ -18,9 +18,9 @@ namespace TEAMModelOS.Controllers
     [ApiController]
     public  class ClassroomController : BaseController
     {
-        public readonly AzureCosmosFactory cosmosrepository;
-        public ClassroomController(AzureCosmosFactory _cosmosrepository) {
-            cosmosrepository = _cosmosrepository;
+        public readonly AzureCosmosFactory _azureCosmos;
+        public ClassroomController(AzureCosmosFactory azureCosmos) {
+            _azureCosmos = azureCosmos;
         }
         [HttpPost("upsert")]
         public async ValueTask<BaseResponse> Upsert(Classroom request)
@@ -30,21 +30,21 @@ namespace TEAMModelOS.Controllers
 
             if (request.id != null)
             {
-                await cosmosrepository.SaveOrUpdate(request);
-                students = await cosmosrepository.FindByDict<Student>(new Dictionary<string, object>() { { "classroomCode", request.classroomCode }, { "schoolCode", request.code } });
+                await _azureCosmos.SaveOrUpdate(request);
+                students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "classroomCode", request.classroomCode }, { "schoolCode", request.code } });
             }
             else
             {
-                List<int> sc = await cosmosrepository.FindCountByDict<Classroom>(new Dictionary<string, object> { { "classroomCode", request.classroomCode } });
+                List<int> sc = await _azureCosmos.FindCountByDict<Classroom>(new Dictionary<string, object> { { "classroomCode", request.classroomCode } });
                 if (sc.IsNotEmpty() && sc[0]>0) {
                     return builder.Error(ResponseCode.DATA_EXIST, "班级代码已经存在!").build();
                 }
                 request.id = request.classroomCode;
-                await cosmosrepository.SaveOrUpdate<Classroom>(request);
+                await _azureCosmos.SaveOrUpdate<Classroom>(request);
                 
             }
             //强制关联原生班级的id
-            List<ClassStudent> classroomStudents = await cosmosrepository.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", request.classroomCode } });
+            List<ClassStudent> classroomStudents = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", request.classroomCode } });
             if (classroomStudents.IsNotEmpty())
             {
                 if (students.IsNotEmpty()) {
@@ -54,7 +54,7 @@ namespace TEAMModelOS.Controllers
                             newClassStudents.Add(new ClassStudent { code = x.studentId, id= request.classroomCode });
                         }
                     });
-                    await cosmosrepository.SaveOrUpdateAll<ClassStudent>(newClassStudents);
+                    await _azureCosmos.SaveOrUpdateAll<ClassStudent>(newClassStudents);
                 }
             }
             return builder.Data(request).build();
@@ -64,7 +64,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> Find(JsonElement request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<Classroom> sc = await cosmosrepository.FindByDict<Classroom>(request);
+            List<Classroom> sc = await _azureCosmos.FindByDict<Classroom>(request);
             return builder.Data(sc).build();
         }
 
@@ -77,11 +77,11 @@ namespace TEAMModelOS.Controllers
 
             if (request.TryGetProperty("id", out JsonElement id))
             {
-                List<Classroom> sc = await cosmosrepository.FindByDict<Classroom>(request);
+                List<Classroom> sc = await _azureCosmos.FindByDict<Classroom>(request);
                 if (sc.IsNotEmpty())
                 {
-                    await cosmosrepository.DeleteAll<ClassStudent>(new Dictionary<string, object> { { "id", sc.Select(x=>x.classroomCode).ToArray()} });
-                    List<IdPk> idPks = await cosmosrepository.DeleteAll<Classroom>(sc);
+                    await _azureCosmos.DeleteAll<ClassStudent>(new Dictionary<string, object> { { "id", sc.Select(x=>x.classroomCode).ToArray()} });
+                    List<IdPk> idPks = await _azureCosmos.DeleteAll<Classroom>(sc);
                     builder.Data(idPks);
                 }
             }

+ 14 - 14
TEAMModelOS/Controllers/School/ClassStudentController.cs

@@ -19,11 +19,11 @@ namespace TEAMModelOS.Controllers
     public class ClassStudentController : BaseController
     {
 
-        private AzureCosmosFactory _cosmos;
+        private AzureCosmosFactory _azureCosmos;
 
-        public ClassStudentController(AzureCosmosFactory cosmos)
+        public ClassStudentController(AzureCosmosFactory azureCosmos)
         {
-            _cosmos = cosmos;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -46,8 +46,8 @@ namespace TEAMModelOS.Controllers
                  && request.TryGetProperty("schoolCode", out JsonElement schoolCode)
                 )
             {
-                List<ClassStudent> classroomStudents = await _cosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", classroomCode } });
-                List<Student> students = await _cosmos.FindByDict<Student>(
+                List<ClassStudent> classroomStudents = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "id", classroomCode } });
+                List<Student> students = await _azureCosmos.FindByDict<Student>(
                     new Dictionary<string, object>() { { "classroomCode", classroomCode }, { "code", schoolCode } },
                     new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
                 List<dynamic> stus = new List<dynamic>();
@@ -80,7 +80,7 @@ namespace TEAMModelOS.Controllers
                         });
                     }
                 
-                    var sts = await _cosmos.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids.ToArray() } });
+                    var sts = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids.ToArray() } });
                     if (sts.IsNotEmpty())
                     {
                         sts.ForEach(x =>
@@ -94,7 +94,7 @@ namespace TEAMModelOS.Controllers
                 //保存新增学生
                 if (newClassStudents.IsNotEmpty())
                 {
-                    classroomStudents.AddRange(await _cosmos.SaveOrUpdateAll(newClassStudents));
+                    classroomStudents.AddRange(await _azureCosmos.SaveOrUpdateAll(newClassStudents));
                 }
                 return builder.Data(classroomStudents).Extend(new Dictionary<string, object> { { "students", stus }, { "count", stus.Count } }).build();
             }
@@ -113,7 +113,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> Upsert(List<ClassStudent> request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<ClassStudent> students = await _cosmos.SaveOrUpdateAll(request);
+            List<ClassStudent> students = await _azureCosmos.SaveOrUpdateAll(request);
             builder.Data(students);
             return builder.build();
         }
@@ -145,7 +145,7 @@ namespace TEAMModelOS.Controllers
             if (ValidateHelper.IsValid(request) && request.Count>0)
             {
                 List<ClassStudent> rm = new List<ClassStudent>();
-                List<Student> students = await _cosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId", request.GroupBy(x => x.code).ToList().Select(x => x.Key).ToArray() } });
+                List<Student> students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId", request.GroupBy(x => x.code).ToList().Select(x => x.Key).ToArray() } });
                 students.ForEach(x => {
                     if (!string.IsNullOrEmpty(x.classroomCode)) {
                         request.ForEach(m =>
@@ -157,7 +157,7 @@ namespace TEAMModelOS.Controllers
                     }
                 });
                 rm.ForEach(x=> { request.Remove(x); });
-                List<IdPk> idPks = await _cosmos.DeleteAll<ClassStudent>(request.Select(x=> new IdPk { id=x.id,pk=x.code}).ToList());
+                List<IdPk> idPks = await _azureCosmos.DeleteAll<ClassStudent>(request.Select(x=> new IdPk { id=x.id,pk=x.code}).ToList());
                 builder.Data(idPks);
             }
             return builder.build();
@@ -174,8 +174,8 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             if (ValidateHelper.IsValid(request))
             {
-                ClassStudent classStudent = await _cosmos.FindByIdPk<ClassStudent>(request.id,request.pk);
-                List<Student> students = await _cosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId",request.pk } }, new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
+                ClassStudent classStudent = await _azureCosmos.FindByIdPk<ClassStudent>(request.id,request.pk);
+                List<Student> students = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object> { { "studentId",request.pk } }, new List<string> { "id", "name", "code", "seatNo", "studentId", "classroomCode" });
                 builder.Data(classStudent).Extend(new Dictionary<string, object> { { "student",students.IsNotEmpty()&& classStudent !=null? new { students[0].id, students[0].name, students[0].code, students[0].seatNo, students[0].studentId, students[0].classroomCode }:null } });
             }
             return builder.build();
@@ -191,8 +191,8 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             if (request.TryGetProperty("code", out JsonElement studentId))
             {
-                List<ClassStudent> sc = await _cosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "code",studentId.ToString()} });
-                List<Classroom> classrooms = await _cosmos.FindByDict<Classroom>(new Dictionary<string, object> { { "classroomCode", sc.GroupBy(x => x.id).Select(x => x.Key).ToArray() } });
+                List<ClassStudent> sc = await _azureCosmos.FindByDict<ClassStudent>(new Dictionary<string, object> { { "code",studentId.ToString()} });
+                List<Classroom> classrooms = await _azureCosmos.FindByDict<Classroom>(new Dictionary<string, object> { { "classroomCode", sc.GroupBy(x => x.id).Select(x => x.Key).ToArray() } });
                 builder.Data(classrooms).Extend(new Dictionary<string, object> { { "count", classrooms.Count } });
             }
             return builder.build();

+ 25 - 25
TEAMModelOS/Controllers/School/CourseController.cs

@@ -17,11 +17,11 @@ namespace TEAMModelOS.Controllers
     [ApiController]
     public class CourseController : BaseController
     {
-        private AzureCosmosFactory _cosmos;
+        private AzureCosmosFactory _azureCosmos;
 
-        public CourseController(AzureCosmosFactory cosmos)
+        public CourseController(AzureCosmosFactory azureCosmos)
         {
-            _cosmos = cosmos;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -34,13 +34,13 @@ namespace TEAMModelOS.Controllers
         {
             ResponseBuilder builder = ResponseBuilder.custom();
             if (string.IsNullOrEmpty(request.id)) {
-                List<int> count =await _cosmos.FindCountByDict<Course>(new Dictionary<string, object> { { "courseCode", request.courseCode },{ "code",request.code} });
+                List<int> count =await _azureCosmos.FindCountByDict<Course>(new Dictionary<string, object> { { "courseCode", request.courseCode },{ "code",request.code} });
                 if (count.IsNotEmpty() && count[0] > 0) {
                     return builder.Error(ResponseCode.DATA_EXIST, "课程编码已经存在!").build();
                 }
                 request.id = request.code.Replace("#", "") +"-"+ request.courseCode;
             }
-            Course  response = await _cosmos.SaveOrUpdate<Course>(request);
+            Course  response = await _azureCosmos.SaveOrUpdate<Course>(request);
             return builder.Data(response).build();
         }
         /// <summary>
@@ -55,7 +55,7 @@ namespace TEAMModelOS.Controllers
            
             List<Course> data = new List<Course>();
             if (StringHelper.getKeyCount(request) > 0) {
-                data = await _cosmos.FindByDict<Course>(request);
+                data = await _azureCosmos.FindByDict<Course>(request);
             }
             return builder.Data(data).Extend(new Dictionary<string, object> { { "count", data.Count } }).build();
         }
@@ -68,7 +68,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> Delete(IdPk request) 
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            IdPk idPk=  await _cosmos.DeleteAsync<Course>(request);
+            IdPk idPk=  await _azureCosmos.DeleteAsync<Course>(request);
             return builder.Data(idPk).build();
         }
         /// <summary>
@@ -80,7 +80,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> DeleteAll(List<IdPk> request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<IdPk> idPk = await _cosmos.DeleteAll<Course>(request);
+            List<IdPk> idPk = await _azureCosmos.DeleteAll<Course>(request);
             return builder.Data(idPk).build();
         }
       
@@ -95,7 +95,7 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             string classroomCode=  request.classroomCode;
             Dictionary<string, object> dictcode = new Dictionary<string, object>() { { "classes[*].classroomCode", classroomCode } };
-            List<CoursePlan> courses= await _cosmos.FindByDict<CoursePlan>(dictcode);
+            List<CoursePlan> courses= await _azureCosmos.FindByDict<CoursePlan>(dictcode);
             //按班级导入课程表 要清除之前的课程安排
             if (courses.IsNotEmpty()) {
                 for (int i = 0; i < courses.Count; i++)
@@ -109,7 +109,7 @@ namespace TEAMModelOS.Controllers
                     }
                 }
                 //清除之前的
-                await _cosmos.SaveOrUpdateAll(courses);
+                await _azureCosmos.SaveOrUpdateAll(courses);
                 //重新设置
                 for (int i = 0; i < courses.Count; i++) {
                     CourseClass courseClass =   new CourseClass
@@ -120,7 +120,7 @@ namespace TEAMModelOS.Controllers
                     coursePlans.ForEach(x=> { courseClass.courseTimes.Add(x.courseTime); });
                     courses[i].classes.Add(courseClass);
                 }
-                await _cosmos.SaveOrUpdateAll(courses);
+                await _azureCosmos.SaveOrUpdateAll(courses);
             }
             return builder.Data(courses).build();
         }
@@ -136,7 +136,7 @@ namespace TEAMModelOS.Controllers
             List<CoursePlan> plans = new List<CoursePlan>();
             ResponseBuilder builder = ResponseBuilder.custom();
             List<CoursePlan> coursePlans = new List<CoursePlan>();
-            CoursePlan data = await _cosmos.FindByIdPk<CoursePlan>(request.courseId, request.code );
+            CoursePlan data = await _azureCosmos.FindByIdPk<CoursePlan>(request.courseId, request.code );
             if (data != null)
             {
                 bool flag = true;
@@ -174,7 +174,7 @@ namespace TEAMModelOS.Controllers
                 };
                 data.classes.Add(new CourseClass { classroomCode = request.classroomCode, courseTimes = new List<CourseTime> { request.courseTime } });
             }
-            await _cosmos.SaveOrUpdate(data);
+            await _azureCosmos.SaveOrUpdate(data);
             return builder.Data(data).build();
         }
 
@@ -208,7 +208,7 @@ namespace TEAMModelOS.Controllers
         [HttpPost("upsertPlan")]
         public async Task<BaseResponse> UpsertPlan(CoursePlan request) {
             ResponseBuilder builder = ResponseBuilder.custom();
-            CoursePlan datas = await _cosmos.FindByIdPk<CoursePlan>(request.id,request.code);
+            CoursePlan datas = await _azureCosmos.FindByIdPk<CoursePlan>(request.id,request.code);
             if (datas!=null) {
                 request.semesterCode = datas.semesterCode;
                 request.classes.ForEach(x => {
@@ -217,7 +217,7 @@ namespace TEAMModelOS.Controllers
                         x.courseTimes = m.courseTimes;
                     } }); 
                 });
-                await _cosmos.Update(request);
+                await _azureCosmos.Update(request);
             }
             return builder.Data(request).build();
         }
@@ -239,7 +239,7 @@ namespace TEAMModelOS.Controllers
                 request.TryGetProperty("classes[*].classroomCode",out _))
                 )
             {
-                data = await _cosmos.FindByDict<CoursePlan>(request);
+                data = await _azureCosmos.FindByDict<CoursePlan>(request);
                 if (data.IsNotEmpty()) {
                     if (request.TryGetProperty("classes[*].classroomCode",out  JsonElement classcode)) {
                         List<CoursePlan> coursePlans = new List<CoursePlan>();
@@ -270,12 +270,12 @@ namespace TEAMModelOS.Controllers
         {
             ResponseBuilder builder = ResponseBuilder.custom();
             request.TryGetProperty("code" ,out JsonElement code);
-            List<CoursePlan> data= await _cosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "code", code.ToString() } }, new List<string> { "id" });
+            List<CoursePlan> data= await _azureCosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "code", code.ToString() } }, new List<string> { "id" });
             List<Course> courses = new List<Course>();
             if (data.IsNotEmpty()) {
-                courses= await  _cosmos.FindByDict<Course>(new Dictionary<string, object> { { "id", courses.Select(x => x.id).ToArray() } });
+                courses= await  _azureCosmos.FindByDict<Course>(new Dictionary<string, object> { { "id", courses.Select(x => x.id).ToArray() } });
             }
-            List<Course> coursesp = await _cosmos.FindByDict<Course>(new Dictionary<string, object> { { "code", code.ToString() } });
+            List<Course> coursesp = await _azureCosmos.FindByDict<Course>(new Dictionary<string, object> { { "code", code.ToString() } });
             if (courses.IsNotEmpty())
             {
                 //个人教室
@@ -310,20 +310,20 @@ namespace TEAMModelOS.Controllers
             var prop = new List<string> { "classes" };
             if (request.TryGetProperty("code", out JsonElement code))
             {
-                var teachers = await _cosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "code", code.ToString() } }, prop);
+                var teachers = await _azureCosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "code", code.ToString() } }, prop);
                 if (teachers.IsNotEmpty()) {
                     teachers.Select(x => x.classes).ToList().ForEach(x => { x.ForEach(y => { data.Add(y.classroomCode); }); });
 
                 }
             }
             if (request.TryGetProperty("assistant[*]", out JsonElement element)) { 
-                var assistant = await _cosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "assistant[*]", element.ToString() } }, prop);
+                var assistant = await _azureCosmos.FindByDict<CoursePlan>(new Dictionary<string, object> { { "assistant[*]", element.ToString() } }, prop);
                 if (assistant.IsNotEmpty()) {
                     assistant.Select(x => x.classes).ToList().ForEach(x => { x.ForEach(y => { data.Add(y.classroomCode); }); });
                 }
             }
             if (data.Count > 0) { 
-                var classRoom=  await _cosmos.FindByDict<Classroom>(new Dictionary<string, object> { { "classroomCode",data.ToArray() } } );
+                var classRoom=  await _azureCosmos.FindByDict<Classroom>(new Dictionary<string, object> { { "classroomCode",data.ToArray() } } );
                 if (classRoom.IsNotEmpty()) {
                     classRoom.ForEach(x => {
                         room.Add(x);
@@ -343,7 +343,7 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             if (request.TryGetProperty("id",out JsonElement id) && request.TryGetProperty("code",out JsonElement code) && request.TryGetProperty("classroomCode",out JsonElement classroomCode) 
                 && request.TryGetProperty("time",out JsonElement time) && request.TryGetProperty("day",out JsonElement day)) {
-                CoursePlan coursePlan = await _cosmos.FindByIdPk<CoursePlan>(id.ToString(), code.ToString());
+                CoursePlan coursePlan = await _azureCosmos.FindByIdPk<CoursePlan>(id.ToString(), code.ToString());
                 List<CourseTime> courseTimes = new List<CourseTime>();
                 coursePlan.classes.ForEach(x=> {
                     if (x.classroomCode == classroomCode.ToString()) {
@@ -358,7 +358,7 @@ namespace TEAMModelOS.Controllers
                coursePlan.classes.ForEach(x => { if (x.classroomCode == classroomCode.ToString()) {
                        courseTimes.ForEach(y => { x.courseTimes.Remove(y); });
                    } });
-               await _cosmos.Update(coursePlan);
+               await _azureCosmos.Update(coursePlan);
                 return builder.Data(coursePlan).build();
             }
             return builder.Data(null).build();
@@ -372,7 +372,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> DeletePlan(IdPk request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            IdPk idPk = await _cosmos.DeleteAsync<CoursePlan>(request);
+            IdPk idPk = await _azureCosmos.DeleteAsync<CoursePlan>(request);
             return builder.Data(idPk).build();
         }
     }

+ 8 - 8
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -17,10 +17,10 @@ namespace TEAMModelOS.Controllers
     public class SchoolController : Controller
     {
 
-        public AzureCosmosFactory _cosmosrepository;
-        public SchoolController(AzureCosmosFactory cosmosDBRepository)
+        public AzureCosmosFactory _azureCosmos;
+        public SchoolController(AzureCosmosFactory azureCosmos)
         {
-            _cosmosrepository = cosmosDBRepository;
+            _azureCosmos = azureCosmos;
         }
         /// <summary>
         /// 保存或更新学校
@@ -33,7 +33,7 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             if (string.IsNullOrEmpty(request.id))
             {
-                List<School> schools = await _cosmosrepository.FindByDict<School>(new Dictionary<string, object> { { "code", request.schoolCode } });
+                List<School> schools = await _azureCosmos.FindByDict<School>(new Dictionary<string, object> { { "code", request.schoolCode } });
                 if (schools.IsNotEmpty())
                 {
                     return builder.Error(ResponseCode.DATA_EXIST, "学校编码已存在!").build();
@@ -42,7 +42,7 @@ namespace TEAMModelOS.Controllers
                 request.id = request.schoolCode;
             }
             else {
-                List<School> schools = await _cosmosrepository.FindByDict<School>(new Dictionary<string, object> { { "id", request.id } });
+                List<School> schools = await _azureCosmos.FindByDict<School>(new Dictionary<string, object> { { "id", request.id } });
                 if (schools.IsEmpty())
                 {
                     return builder.Error(ResponseCode.PARAMS_ERROR, "id不存在,不能更新").build();
@@ -50,7 +50,7 @@ namespace TEAMModelOS.Controllers
             }
             if (request.id.Equals(request.code) && request.id.Equals(request.schoolCode))
             {
-                School datas = await _cosmosrepository.SaveOrUpdate<School>(request);
+                School datas = await _azureCosmos.SaveOrUpdate<School>(request);
                 return builder.Data(datas).build();
             }
             else {
@@ -70,7 +70,7 @@ namespace TEAMModelOS.Controllers
             
             if (request.TryGetProperty("code", out JsonElement code) &&! string.IsNullOrEmpty(code.ToString()))
             {
-                List<School> sc = await _cosmosrepository.FindByDict<School>(request);
+                List<School> sc = await _azureCosmos.FindByDict<School>(request);
                 return builder.Data(sc).build();
             }
             else {
@@ -86,7 +86,7 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> GetAllSchoolBaesInfo(JsonElement request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<School> sc = await _cosmosrepository.FindSQL<School>("SELECT c.id, c.schoolCode, c.schoolName, c.address, c.picture FROM c WHERE c.pk='School'");
+            List<School> sc = await _azureCosmos.FindSQL<School>("SELECT c.id, c.schoolCode, c.schoolName, c.address, c.picture FROM c WHERE c.pk='School'");
             return builder.Data(sc).build();
         }
     }

+ 18 - 18
TEAMModelOS/Controllers/Student/StudentController.cs

@@ -1,4 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -19,10 +19,10 @@ namespace TEAMModelOS.Controllers
     // [Authorize]
     public class StudentController : BaseController
     {
-        private readonly AzureCosmosFactory azureCosmosDBRepository;
-        public StudentController(AzureCosmosFactory _azureCosmosDBRepository)
+        private readonly AzureCosmosFactory _azureCosmos;
+        public StudentController(AzureCosmosFactory azureCosmos)
         {
-            azureCosmosDBRepository = _azureCosmosDBRepository;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -43,16 +43,16 @@ namespace TEAMModelOS.Controllers
             }
             request.id = request.studentId.Replace("#", "-");
             ///假如更新了班级则先获取更新之前的班级
-            var olStudent= await azureCosmosDBRepository.FindByIdPk<Student>(request.id,request.code);
+            var olStudent= await _azureCosmos.FindByIdPk<Student>(request.id,request.code);
             if (olStudent!=null &&  !string.IsNullOrEmpty(olStudent.classroomCode) && ! olStudent.classroomCode.Equals(request.classroomCode) ) {
                 //移除之前的原生班级
-                IdPk idPk=await azureCosmosDBRepository.DeleteAsync<ClassStudent>( olStudent.classroomCode ,olStudent.studentId);
+                IdPk idPk=await _azureCosmos.DeleteAsync<ClassStudent>( olStudent.classroomCode ,olStudent.studentId);
                
             }
             ///新建最新的班级关系表
             ClassStudent classroomStudent = new ClassStudent { id = request.classroomCode, code = request.studentId };
-            await azureCosmosDBRepository.SaveOrUpdate(classroomStudent);
-            Student data = await azureCosmosDBRepository.SaveOrUpdate<Student>(request);
+            await _azureCosmos.SaveOrUpdate(classroomStudent);
+            Student data = await _azureCosmos.SaveOrUpdate<Student>(request);
             return builder.Data(data).build();
         }
 
@@ -67,7 +67,7 @@ namespace TEAMModelOS.Controllers
             ResponseBuilder builder = ResponseBuilder.custom();
             if (request.TryGetProperty("code", out _))
             {
-                List<Student> data = await azureCosmosDBRepository.FindByDict<Student>(request);
+                List<Student> data = await _azureCosmos.FindByDict<Student>(request);
                 return builder.Data(data).build();
             }
             else
@@ -85,7 +85,7 @@ namespace TEAMModelOS.Controllers
 
                 ///假如更新了班级则先获取更新之前的班级
                 string[] ids = request.Select(x=>x.studentId).ToArray();
-                List<Student> oldStudent = await azureCosmosDBRepository.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids } });
+                List<Student> oldStudent = await _azureCosmos.FindByDict<Student>(new Dictionary<string, object>() { { "studentId", ids } });
                 List<IdPk> idPks = new List<IdPk>();
                 ///处理未变动的班级关系
                 List<IdPk> unpk = new List<IdPk>();
@@ -103,7 +103,7 @@ namespace TEAMModelOS.Controllers
                     });
                 });
                 if (idPks.IsNotEmpty()) {
-                    await azureCosmosDBRepository.DeleteAll<ClassStudent>(idPks);
+                    await _azureCosmos.DeleteAll<ClassStudent>(idPks);
                 }
                 long createDate = DateTimeOffset.UtcNow.Ticks;
                 request.ForEach(
@@ -117,7 +117,7 @@ namespace TEAMModelOS.Controllers
                             x.password.isSet = true;
                         }
                     });
-                List<Student> students = await azureCosmosDBRepository.SaveOrUpdateAll(request);
+                List<Student> students = await _azureCosmos.SaveOrUpdateAll(request);
                 ///更新学生关系表
                 List<ClassStudent> classroomStudents = new List<ClassStudent>();
                 foreach (var student  in students)
@@ -137,7 +137,7 @@ namespace TEAMModelOS.Controllers
                         classroomStudents.Add(new ClassStudent { id = student.classroomCode, code = student.studentId });
                     }
                 }
-                await  azureCosmosDBRepository.SaveOrUpdateAll(classroomStudents);
+                await  _azureCosmos.SaveOrUpdateAll(classroomStudents);
                 builder.Data(students);
             }
             return builder.build();
@@ -154,9 +154,9 @@ namespace TEAMModelOS.Controllers
         public async Task<BaseResponse> Delete(Student request)
         {
             ResponseBuilder builder = ResponseBuilder.custom();
-            IdPk data = await azureCosmosDBRepository.DeleteAsync<Student>(request.id, request.code);
+            IdPk data = await _azureCosmos.DeleteAsync<Student>(request.id, request.code);
             ///更新学生关系表
-            await azureCosmosDBRepository.DeleteAll<ClassStudent>(new Dictionary<string, object> { { "code", request.studentId } });
+            await _azureCosmos.DeleteAll<ClassStudent>(new Dictionary<string, object> { { "code", request.studentId } });
             return builder.Data(data).build();
         }
         /// <summary>
@@ -177,10 +177,10 @@ namespace TEAMModelOS.Controllers
                 //dict[emobj.Current.Name] = emobj.Current.Value;
             }
             if (keys > 0&& request.TryGetProperty("code",out JsonElement code)) {
-                List<Student> students = await azureCosmosDBRepository.FindByDict<Student>(request);
-                await azureCosmosDBRepository.DeleteAll<Student>(students);
+                List<Student> students = await _azureCosmos.FindByDict<Student>(request);
+                await _azureCosmos.DeleteAll<Student>(students);
                 ///更新学生关系表
-                await azureCosmosDBRepository.DeleteAll<ClassStudent>(new Dictionary<string, object> { {"code",students.Select(x=>x.studentId).ToArray() } });
+                await _azureCosmos.DeleteAll<ClassStudent>(new Dictionary<string, object> { {"code",students.Select(x=>x.studentId).ToArray() } });
                 builder.Data(students);
             }
             return builder.build();

+ 9 - 9
TEAMModelOS/Controllers/Teacher/CommentController.cs

@@ -1,4 +1,4 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -18,10 +18,10 @@ namespace TEAMModelOS.Controllers
     [ApiController]
     public class CommentController :BaseController
     {
-        private readonly AzureCosmosFactory _cosmos;
-        public CommentController(AzureCosmosFactory _cosmosDBV3Repository)
+        private readonly AzureCosmosFactory _azureCosmos;
+        public CommentController(AzureCosmosFactory azureCosmos)
         {
-            _cosmos = _cosmosDBV3Repository;
+            _azureCosmos = azureCosmos;
         }
 
         /// <summary>
@@ -34,7 +34,7 @@ namespace TEAMModelOS.Controllers
         {
             var id = "Comment-" + request.TEAMModelId.Replace("#", "");
             ResponseBuilder builder = ResponseBuilder.custom();
-            List<Comment> Comment = await _cosmos.FindByDict<Comment>(new Dictionary<string, object> { { "code", request.TEAMModelId }, { "id", id } });
+            List<Comment> Comment = await _azureCosmos.FindByDict<Comment>(new Dictionary<string, object> { { "code", request.TEAMModelId }, { "id", id } });
             Comment comment = new Comment();
             if (Comment.IsEmpty())
             {
@@ -47,7 +47,7 @@ namespace TEAMModelOS.Controllers
                 comment = Comment[0];
                 comment.comment.Add(request.comment);
             }
-            builder.Data(await _cosmos.SaveOrUpdate(comment));
+            builder.Data(await _azureCosmos.SaveOrUpdate(comment));
             return builder.build();
         }
 
@@ -65,7 +65,7 @@ namespace TEAMModelOS.Controllers
             List<Comment> data = new List<Comment>();
             if (StringHelper.getKeyCount(request) > 0)
             {
-                data = await _cosmos.FindByDict<Comment>(request);
+                data = await _azureCosmos.FindByDict<Comment>(request);
             }
             else
             {
@@ -89,12 +89,12 @@ namespace TEAMModelOS.Controllers
                 if (string.IsNullOrEmpty(request.id)) {
                     request.id  = "Comment-" + request.code.Replace("#", "");
                 }
-                comment = await _cosmos.SaveOrUpdate<Comment>(request);
+                comment = await _azureCosmos.SaveOrUpdate<Comment>(request);
             }
             else {
                 if (!string.IsNullOrEmpty(request.id))
                 {
-                    IdPk idPk = await _cosmos.DeleteAsync<Comment>(request.id, request.code);
+                    IdPk idPk = await _azureCosmos.DeleteAsync<Comment>(request.id, request.code);
                 }
                    
             }

+ 17 - 17
TEAMModelOS/Controllers/Teacher/SchoolUserController.cs

@@ -23,14 +23,14 @@ namespace TEAMModelOS.Controllers
 {
     [Route("api/[controller]")]
     [ApiController]
-    public class SchoolUserController : Controller
+    public class TeacherController : ControllerBase
     {
-        private AzureCosmosFactory _cosmosrepository;
-        private AzureStorageFactory _tablerepository;
-        public SchoolUserController(AzureCosmosFactory cosmosDBRepository, AzureStorageFactory tableDBRepository)
+        private AzureCosmosFactory _azureCosmos;
+        private AzureStorageFactory _azureStorage;
+        public TeacherController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage)
         {
-            _cosmosrepository = cosmosDBRepository;
-            _tablerepository = tableDBRepository;
+            _azureCosmos = azureCosmos;
+            _azureStorage = azureStorage;
         }
 
         /// <summary>
@@ -41,7 +41,7 @@ namespace TEAMModelOS.Controllers
         {
             ResponseBuilder builder = ResponseBuilder.custom();
             //request.@params.TryGetValue("code", out object partitionKey);
-            List<SchoolUser> su = await _cosmosrepository.FindByDict<SchoolUser>(request);
+            List<SchoolUser> su = await _azureCosmos.FindByDict<SchoolUser>(request);
             return builder.Data(su).build();
         }
 
@@ -73,7 +73,7 @@ namespace TEAMModelOS.Controllers
             {
                 userDict.Add("joinStatus", joinStatus);
             }
-            List<SchoolUser> su = await _cosmosrepository.FindByDict<SchoolUser>(userDict);
+            List<SchoolUser> su = await _azureCosmos.FindByDict<SchoolUser>(userDict);
 
             return builder.Data(su).build();
         }
@@ -106,7 +106,7 @@ namespace TEAMModelOS.Controllers
                 { "joinStatus",  1}
             };
             List<SchoolUser> suListResponse = new List<SchoolUser>(); //返回值
-            List<SchoolUser> suList = await _cosmosrepository.FindByDict<SchoolUser>(userDict);
+            List<SchoolUser> suList = await _azureCosmos.FindByDict<SchoolUser>(userDict);
             //設定權限
             if (suList.Count > 0)
             {
@@ -114,7 +114,7 @@ namespace TEAMModelOS.Controllers
                 {
                     su.authority = authList;
                     suListResponse.Add(su);
-                    await _cosmosrepository.Update(su);
+                    await _azureCosmos.Update(su);
                 }
             }
             return builder.Data(suListResponse).build();
@@ -142,7 +142,7 @@ namespace TEAMModelOS.Controllers
                 { "id",  id.ToString()}
             };
             SchoolUser suResponse = new SchoolUser(); //返回值
-            List<SchoolUser> suList = await _cosmosrepository.FindByDict<SchoolUser>(userDict);
+            List<SchoolUser> suList = await _azureCosmos.FindByDict<SchoolUser>(userDict);
             //更新資料
             if (suList.Count > 0)
             {
@@ -165,7 +165,7 @@ namespace TEAMModelOS.Controllers
                             }
                         }
                     }
-                    await _cosmosrepository.Update(su);
+                    await _azureCosmos.Update(su);
                     suResponse = su;
                 }
             }
@@ -187,13 +187,13 @@ namespace TEAMModelOS.Controllers
                 { "schoolCode",  schoolCode.ToString()},
                 { "id",  Ids}
             };
-            List<SchoolUser> suList = await _cosmosrepository.FindByDict<SchoolUser>(userDict);
+            List<SchoolUser> suList = await _azureCosmos.FindByDict<SchoolUser>(userDict);
             //移除
             if (suList.Count > 0)
             {
                 foreach (SchoolUser su in suList)
                 {
-                    await _cosmosrepository.DeleteAsync(su);
+                    await _azureCosmos.DeleteAsync(su);
                 }
             }
             return builder.build();
@@ -210,7 +210,7 @@ namespace TEAMModelOS.Controllers
             {
                 { "PartitionKey",  "authority"}
             };
-            List<Authority> schoolAuthorityList = await _tablerepository.FindListByDict<Authority>(dict);
+            List<Authority> schoolAuthorityList = await _azureStorage.FindListByDict<Authority>(dict);
             return builder.Data(schoolAuthorityList).build();
         }
 
@@ -246,7 +246,7 @@ namespace TEAMModelOS.Controllers
                     addUser.authority = new List<string>();
                     addUser.code = schoolCode + "-SchoolUser";
                 }
-                await _cosmosrepository.SaveOrUpdateAll<SchoolUser>(addUserlist);
+                await _azureCosmos.SaveOrUpdateAll<SchoolUser>(addUserlist);
                 return builder.build();
             }
             catch (Exception e)
@@ -276,7 +276,7 @@ namespace TEAMModelOS.Controllers
                 addUserinfo.authority = new List<string>();
                 addUserinfo.code = schoolCode + "-SchoolUser";
 
-                await _cosmosrepository.SaveOrUpdate<SchoolUser>(addUserinfo);
+                await _azureCosmos.SaveOrUpdate<SchoolUser>(addUserinfo);
 
                 return builder.Data(addUserinfo).build();
             }

+ 1 - 0
TEAMModelOS/TEAMModelOS.csproj

@@ -7,6 +7,7 @@
     <PackageReference Include="Bogus" Version="29.0.1" />
     <PackageReference Include="Caching.CSRedis" Version="3.5.5" />
     <PackageReference Include="CSRedisCore" Version="3.5.5" />
+    <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
     <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.6" />
     <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.2" />
       <PackageReference Include="VueCliMiddleware" Version="3.1.1" />  </ItemGroup>