Bläddra i källkod

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

zhouj1203@hotmail.com 6 år sedan
förälder
incheckning
714e0491a5
100 ändrade filer med 2374 tillägg och 297 borttagningar
  1. 13 0
      TEAMModelOS.Model/Core/Dtos/LoginResult.cs
  2. 13 0
      TEAMModelOS.Model/Core/Dtos/RootUser.cs
  3. 15 0
      TEAMModelOS.Model/Core/Dtos/SchoolCode.cs
  4. 20 0
      TEAMModelOS.Model/Core/Dtos/TeamModelIdInfo.cs
  5. 22 0
      TEAMModelOS.Model/Core/Dtos/TicketInfo.cs
  6. 14 0
      TEAMModelOS.Model/Core/Models/JwtBlackRecord.cs
  7. 39 0
      TEAMModelOS.Model/Core/Models/LoginInfo.cs
  8. 22 0
      TEAMModelOS.Model/Core/Models/Product.cs
  9. 29 0
      TEAMModelOS.Model/Core/Models/Region.cs
  10. 19 0
      TEAMModelOS.Model/Core/Models/Role.cs
  11. 14 0
      TEAMModelOS.Model/Core/Models/RoleIdentity.cs
  12. 15 0
      TEAMModelOS.Model/Core/Models/RoleSchool.cs
  13. 23 0
      TEAMModelOS.Model/Core/Models/RoleUser.cs
  14. 32 0
      TEAMModelOS.Model/Core/Models/School.cs
  15. 19 0
      TEAMModelOS.Model/Core/Models/SchoolCampus.cs
  16. 25 0
      TEAMModelOS.Model/Core/Models/SchoolClass.cs
  17. 24 0
      TEAMModelOS.Model/Core/Models/SchoolGrade.cs
  18. 25 0
      TEAMModelOS.Model/Core/Models/SchoolGradeSubject.cs
  19. 25 0
      TEAMModelOS.Model/Core/Models/SchoolGradeTerm.cs
  20. 21 0
      TEAMModelOS.Model/Core/Models/SchoolPeriod.cs
  21. 78 0
      TEAMModelOS.Model/Core/Models/TeamModelUser.cs
  22. 11 4
      TEAMModelOS.Model/Syllabus/Dtos/SyllabusTree.cs
  23. 2 2
      TEAMModelOS.Model/Syllabus/Models/TeachingResource.cs
  24. 4 0
      TEAMModelOS.Model/Syllabus/Models/KnowledgePoint.cs
  25. 2 2
      TEAMModelOS.Model/Syllabus/Models/Period.cs
  26. 2 0
      TEAMModelOS.Model/Syllabus/Models/PeriodSubject.cs
  27. 2 0
      TEAMModelOS.Model/Syllabus/Models/PeriodSubjectEdition.cs
  28. 2 0
      TEAMModelOS.Model/Syllabus/Models/PeriodSubjectEditionTerm.cs
  29. 1 1
      TEAMModelOS.Model/Syllabus/Models/SyllabusResource.cs
  30. 13 6
      TEAMModelOS.Model/Syllabus/Models/Textbook.cs
  31. 5 6
      TEAMModelOS.Model/Syllabus/Models/SyllabusNode.cs
  32. 24 0
      TEAMModelOS.Model/Syllabus/Models/TeacherTextbook.cs
  33. 0 21
      TEAMModelOS.Model/Syllabus/Models/TextbookStruct.cs
  34. 0 1
      TEAMModelOS.Model/TEAMModelOS.Model.csproj
  35. 83 0
      TEAMModelOS.SDK/Context/Filters/HttpGlobalExceptionFilter.cs
  36. 3 1
      TEAMModelOS.SDK/Extension/DataResult/JsonRpcRequest/JosnRPCRequest.cs
  37. 3 1
      TEAMModelOS.SDK/Extension/HttpClient/HttpClientExtension.cs
  38. 177 0
      TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientSchool.cs
  39. 40 37
      TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientService.cs
  40. 177 0
      TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientUserInfo.cs
  41. 6 6
      TEAMModelOS.SDK/Extension/JwtAuth/Filters/JwtAuthorizationFilter.cs
  42. 11 2
      TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs
  43. 16 7
      TEAMModelOS.SDK/Extension/JwtAuth/JwtHelper/JwtHelper.cs
  44. 6 0
      TEAMModelOS.SDK/Extension/JwtAuth/Models/ClaimModel.cs
  45. 14 0
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtBlackRecord.cs
  46. 5 3
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtResponse.cs
  47. 1 1
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtSetting.cs
  48. 15 0
      TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtTokenOptions.cs
  49. 44 0
      TEAMModelOS.SDK/Extension/JwtAuth/Requirements/ValidJtiHandler.cs
  50. 9 0
      TEAMModelOS.SDK/Extension/JwtAuth/Requirements/ValidJtiRequirement.cs
  51. 2 2
      TEAMModelOS.SDK/Extension/MessagePush/Implements/SendCloudService.cs
  52. 43 0
      TEAMModelOS.SDK/Helper/Common/CollectionHelper/CollectionHelper.cs
  53. 34 0
      TEAMModelOS.SDK/Helper/Common/JsonHelper/JsonSerialization.cs
  54. 0 32
      TEAMModelOS.SDK/Helper/Common/TreeList/ListToTree.cs
  55. 0 15
      TEAMModelOS.SDK/Helper/Common/TreeList/Node.cs
  56. 0 14
      TEAMModelOS.SDK/Helper/Common/TreeList/Tree.cs
  57. 26 0
      TEAMModelOS.SDK/Helper/Network/HttpHelper/HttpContextHelper.cs
  58. 173 0
      TEAMModelOS.SDK/Helper/Security/RSACrypt/RsaHelper.cs
  59. 63 8
      TEAMModelOS.SDK/Module/AzureCosmosDB/Implements/AzureCosmosDBRepository.cs
  60. 1 2
      TEAMModelOS.SDK/Module/AzureCosmosDB/Interfaces/IAzureCosmosDBRepository.cs
  61. 292 100
      TEAMModelOS.SDK/Module/AzureTable/Implements/AzureTableDBRepository.cs
  62. 3 3
      TEAMModelOS.SDK/Module/AzureTable/Interfaces/IAzureTableDBRepository.cs
  63. 189 0
      TEAMModelOS.Service/Core/Implements/LoginInfoService.cs
  64. 51 0
      TEAMModelOS.Service/Core/Implements/RoleService.cs
  65. 85 0
      TEAMModelOS.Service/Core/Implements/SchoolService.cs
  66. 1 1
      TEAMModelOS.Service/Common/Interfaces/IBusinessService.cs
  67. 13 0
      TEAMModelOS.Service/Core/Interfaces/ILoginInfoService.cs
  68. 16 0
      TEAMModelOS.Service/Core/Interfaces/IRoleService.cs
  69. 20 0
      TEAMModelOS.Service/Core/Interfaces/ISchoolService.cs
  70. 105 10
      TEAMModelOS.Service/Syllabus/Implements/SyllabusService.cs
  71. 42 4
      TEAMModelOS.Service/Syllabus/Interfaces/ISyllabusService.cs
  72. 0 1
      TEAMModelOS.Service/TEAMModelOS.Service.csproj
  73. 30 4
      TEAMModelOS/ClientApp/app.js
  74. BIN
      TEAMModelOS/ClientApp/assets/banner.jpg
  75. BIN
      TEAMModelOS/ClientApp/assets/icon/header_book.png
  76. BIN
      TEAMModelOS/ClientApp/assets/icon/header_detection.png
  77. BIN
      TEAMModelOS/ClientApp/assets/icon/header_interact.png
  78. BIN
      TEAMModelOS/ClientApp/assets/icon/header_preview.png
  79. BIN
      TEAMModelOS/ClientApp/assets/icon/header_synchronization.png
  80. BIN
      TEAMModelOS/ClientApp/assets/icon/header_task.png
  81. BIN
      TEAMModelOS/ClientApp/assets/icon/html50.png
  82. BIN
      TEAMModelOS/ClientApp/assets/icon/icon_audio.png
  83. BIN
      TEAMModelOS/ClientApp/assets/icon/icon_img.png
  84. BIN
      TEAMModelOS/ClientApp/assets/icon/icon_text.png
  85. BIN
      TEAMModelOS/ClientApp/assets/icon/icon_video.png
  86. BIN
      TEAMModelOS/ClientApp/assets/icon/pdf50.png
  87. BIN
      TEAMModelOS/ClientApp/assets/icon/pic50.png
  88. BIN
      TEAMModelOS/ClientApp/assets/icon/ppt50.png
  89. BIN
      TEAMModelOS/ClientApp/assets/icon/prelearn50.png
  90. BIN
      TEAMModelOS/ClientApp/assets/icon/swf50.png
  91. BIN
      TEAMModelOS/ClientApp/assets/icon/txt50.png
  92. BIN
      TEAMModelOS/ClientApp/assets/icon/video50.png
  93. BIN
      TEAMModelOS/ClientApp/assets/icon/word50.png
  94. BIN
      TEAMModelOS/ClientApp/assets/icon/xls50.png
  95. BIN
      TEAMModelOS/ClientApp/assets/icon/zip50.png
  96. BIN
      TEAMModelOS/ClientApp/assets/image/header_icon.png
  97. BIN
      TEAMModelOS/ClientApp/assets/image/header_icon1.png
  98. BIN
      TEAMModelOS/ClientApp/assets/logo.png
  99. BIN
      TEAMModelOS/ClientApp/assets/tmd_logo.png
  100. 0 0
      TEAMModelOS/ClientApp/boot-app.js

+ 13 - 0
TEAMModelOS.Model/Core/Dtos/LoginResult.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Extension.JwtAuth.Models;
+
+namespace TEAMModelOS.Model.Core.Dtos
+{
+    public class LoginResult
+    {
+        public JwtResponse JwtToken { get; set; }
+        public bool CheckTicket { get; set; } = false;
+    }
+}

+ 13 - 0
TEAMModelOS.Model/Core/Dtos/RootUser.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Core.Dtos
+{
+    public  class RootUser
+    {
+        public string NickName { get; set; }
+        public string TeamModelId { get; set; }
+        public string Phone { get; set; }
+    }
+}

+ 15 - 0
TEAMModelOS.Model/Core/Dtos/SchoolCode.cs

@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Core.Dtos
+{
+   public class SchoolCode
+    {
+        public string CountryId { get; set; }//国家
+
+        public string ProvinceId { get; set; }//省份
+
+        public string CityId { get; set; }//城市
+    }
+}

+ 20 - 0
TEAMModelOS.Model/Core/Dtos/TeamModelIdInfo.cs

@@ -0,0 +1,20 @@
+using MessagePack;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Core.Dtos
+{
+    /// <summary>
+    /// 对接醍摩豆ID封装信息
+    /// </summary>
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class TeamModelIdInfo
+    {
+        public string name { get; set; }
+        public string cellphone { get; set; }
+        public string countryCode { get; set; }
+        public string id { get; set; }
+        public string[] iesStation { get; set; }
+    }
+}

+ 22 - 0
TEAMModelOS.Model/Core/Dtos/TicketInfo.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace TEAMModelOS.Model.Core.Dtos
+{
+    /// <summary>
+    /// 前端返回获取的醍摩豆ID登录基本信息及ticket
+    /// </summary>
+    public class TicketInfo
+    {
+        //[Required(ErrorMessage = "{0} 必须填写")]
+        public string Ticket { get; set; }
+        //[Required(ErrorMessage = "{0} 必须填写")]
+        public string Name { get; set; }
+        //[Required(ErrorMessage = "{0} 必须填写")]
+        public string Sign { get; set; }
+        // [Required(ErrorMessage = "{0} 必须填写")]
+        public string TeamModelId { get; set; }
+        public string Token { get; set; }
+    }
+}

+ 14 - 0
TEAMModelOS.Model/Core/Models/JwtBlackRecord.cs

@@ -0,0 +1,14 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    public class JwtBlackRecord :TableEntity
+    {
+        public string Jti { get; set; } 
+    }
+}

+ 39 - 0
TEAMModelOS.Model/Core/Models/LoginInfo.cs

@@ -0,0 +1,39 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    /// <summary>
+    /// 登录信息
+    /// </summary>
+    [TableSpace(Name = "Core")]
+    public class LoginInfo : TableEntity
+    {
+        public string TeamModelId { get; set; }
+        public string Phone { get; set; }
+        public string Ticket { get; set; }
+        public string Name { get; set; }
+        public string Token { get; set; }
+        public string CountryCode { get; set; }
+        /// <summary>
+        /// 登录时间
+        /// </summary>
+        public long LoginTime { get; set; }
+        /// <summary>
+        /// 超时时间
+        /// </summary>
+        public long Timeout { get; set; }
+        /// <summary>
+        /// 到期时间
+        /// </summary>
+        public long Expires { get; set; }
+        /// <summary>
+        /// 作用域
+        /// </summary>
+        public string Scope { get; set; }
+        
+    }
+}

+ 22 - 0
TEAMModelOS.Model/Core/Models/Product.cs

@@ -0,0 +1,22 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+
+    [TableSpace(Name = "Core")]
+    public class Product : TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public int Type { get; set; }
+        public int Status { get; set; }
+        public string Icon { get; set; }
+        public string Url { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+    }
+}

+ 29 - 0
TEAMModelOS.Model/Core/Models/Region.cs

@@ -0,0 +1,29 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class Region :TableEntity
+    {
+        public int SysAddID { get; set; }
+        public string CountryId { get; set; }
+        public string CountryName { get; set; }
+        public string ProvinceId { get; set; }
+        public string ProvinceName { get; set; }
+        public string CityId { get; set; }
+        public string CityName { get; set; }
+        public string DistrictId { get; set; }
+        public string DistrictName { get; set; }
+        public string AreaType { get; set; }
+        public string Lang { get; set; }
+        public double Lng { get; set; }
+        public double Lat { get; set; }
+    }
+}

+ 19 - 0
TEAMModelOS.Model/Core/Models/Role.cs

@@ -0,0 +1,19 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    public class Role : TableEntity
+    {
+        public string Name { get; set; }
+        //public string Code { get; set; }
+        public int Level { get; set; }
+        public string LevelName { get; set; }
+        public string Remarks { get; set; }
+        public int Status { get; set; }
+    }
+}

+ 14 - 0
TEAMModelOS.Model/Core/Models/RoleIdentity.cs

@@ -0,0 +1,14 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    public class RoleIdentity :TableEntity
+    {
+        //public string 
+    }
+}

+ 15 - 0
TEAMModelOS.Model/Core/Models/RoleSchool.cs

@@ -0,0 +1,15 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    public class RoleSchool :Role
+    {
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+    }
+}

+ 23 - 0
TEAMModelOS.Model/Core/Models/RoleUser.cs

@@ -0,0 +1,23 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class RoleUser : TableEntity
+    {
+        public string Phone { get; set; }
+        public string NickName { get; set; }
+        public string TeamModelId { get; set; }
+        public string RoleCode { get; set; }
+        public string RoleName { get; set; }
+        //public string SchoolCode { get; set; }
+        //public string SchoolName { get; set; }
+    }
+}

+ 32 - 0
TEAMModelOS.Model/Core/Models/School.cs

@@ -0,0 +1,32 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class School :TableEntity
+    {
+        public string code { get; set; }
+        public string name { get; set; }
+        public string countryId { get; set; }
+        public string countryName { get; set; }
+        public string provinceId { get; set; }
+        public string provinceName { get; set; }
+        public string cityId { get; set; }
+        public string cityName { get; set; }
+        public string address { get; set; }
+        public string typeId { get; set; }
+        public string typeName { get; set; }
+        public string source { get; set; }
+        public string distId { get; set; }
+        public string distName { get; set; }
+        public string schoolDist { get; set; }
+        public string aliasName { get; set; }
+        public string shortCode { get; set; }
+    }
+}

+ 19 - 0
TEAMModelOS.Model/Core/Models/SchoolCampus.cs

@@ -0,0 +1,19 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolCampus : TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+    }
+}

+ 25 - 0
TEAMModelOS.Model/Core/Models/SchoolClass.cs

@@ -0,0 +1,25 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolClass :TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+        public string CampusCode { get; set; }
+        public string CampusName { get; set; }
+        public string PeriodCode { get; set; }
+        public string PeriodName { get; set; }
+        public string GradeCode { get; set; }
+        public string GradeName { get; set; }
+    }
+}

+ 24 - 0
TEAMModelOS.Model/Core/Models/SchoolGrade.cs

@@ -0,0 +1,24 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolGrade:TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+        public string CampusCode { get; set; }
+        public string CampusName { get; set; }
+        public string PeriodCode { get; set; }
+        public string PeriodName { get; set; }
+
+    }
+}

+ 25 - 0
TEAMModelOS.Model/Core/Models/SchoolGradeSubject.cs

@@ -0,0 +1,25 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolGradeSubject :TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+        public string CampusCode { get; set; }
+        public string CampusName { get; set; }
+        public string PeriodCode { get; set; }
+        public string PeriodName { get; set; }
+        public string GradeCode { get; set; }
+        public string GradeName { get; set; }
+    }
+}

+ 25 - 0
TEAMModelOS.Model/Core/Models/SchoolGradeTerm.cs

@@ -0,0 +1,25 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolGradeTerm :TableEntity
+    {
+            public string Name { get; set; }
+            public string Code { get; set; }
+            public string SchoolCode { get; set; }
+            public string SchoolName { get; set; }
+            public string CampusCode { get; set; }
+            public string CampusName { get; set; }
+            public string PeriodCode { get; set; }
+            public string PeriodName { get; set; }
+            public string GradeCode { get; set; }
+            public string GradeName { get; set; }
+    }
+}

+ 21 - 0
TEAMModelOS.Model/Core/Models/SchoolPeriod.cs

@@ -0,0 +1,21 @@
+using MessagePack;
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    [MessagePackObject(keyAsPropertyName: true)]
+    public class SchoolPeriod : TableEntity
+    {
+        public string Name { get; set; }
+        public string Code { get; set; }
+        public string SchoolCode { get; set; }
+        public string SchoolName { get; set; }
+        public string CampusCode { get; set; }
+        public string CampusName { get; set; }
+    }
+}

+ 78 - 0
TEAMModelOS.Model/Core/Models/TeamModelUser.cs

@@ -0,0 +1,78 @@
+using Microsoft.WindowsAzure.Storage.Table;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Core.Models
+{
+    [TableSpace(Name = "Core")]
+    public class TeamModelUser : TableEntity
+    {
+        /// <summary>
+        /// 真实姓名
+        /// </summary>
+        public string FullName { get; set; }
+        /// <summary>
+        /// 昵称
+        /// </summary>
+        public string NickName { get; set; }
+        /// <summary>
+        /// 性别
+        /// </summary>
+        public string Sex { get; set; }
+        /// <summary>
+        /// 手机号
+        /// </summary>
+        public string Cellphone { get; set; }
+        /// <summary>
+        /// 邮箱
+        /// </summary>
+        public string Email { get; set; }
+        /// <summary>
+        /// 醍摩豆ID
+        /// </summary>
+        public string TeamModelId { get; set; }
+        /// <summary>
+        /// 头像
+        /// </summary>
+        public string Header { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public string CountryId { get; set; }
+        /// <summary>
+        /// 国家
+        /// </summary>
+        public string CountryName { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public string ProvinceId { get; set; }
+        /// <summary>
+        /// 省
+        /// </summary>
+        public string ProvinceName { get; set; }
+        /// <summary>
+        /// 市
+        /// </summary>
+        public string CityId { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public string CityName { get; set; }
+        /// <summary>
+        /// 区县
+        /// </summary>
+        public string DistrictId { get; set; }
+        /// <summary>
+        /// 
+        /// </summary>
+        public string DistrictName { get; set; }
+        /// <summary>
+        /// 注册时间
+        /// </summary>
+        public long RegisterTime { get; set; }
+        public string CountryCode { get; set; }
+    }
+}

+ 11 - 4
TEAMModelOS.Model/Syllabus/Dtos/SyllabusTree.cs

@@ -2,6 +2,7 @@
 using Microsoft.WindowsAzure.Storage.Table;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Text;
 
 namespace TEAMModelOS.Model.Syllabus.Dtos
@@ -15,6 +16,7 @@ namespace TEAMModelOS.Model.Syllabus.Dtos
         /// <summary>
         /// 标题
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string Title { get; set; }
         /// <summary>
         /// 是否展开
@@ -23,10 +25,12 @@ namespace TEAMModelOS.Model.Syllabus.Dtos
         /// <summary>
         /// 排序
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public int Order { get; set; }
         /// <summary>
         /// 类型
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public int Type { get; set; }
         /// <summary>
         /// 备注
@@ -35,14 +39,17 @@ namespace TEAMModelOS.Model.Syllabus.Dtos
         /// <summary>
         /// 节点Key
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string NodeKey { get; set; }
-        /// <summary>
-        ///主键
-        /// </summary>
-        public string Id { get; set; }
+        ///// <summary>
+        /////主键
+        ///// </summary>
+        //[Required(ErrorMessage = "{0} 必须填写")]
+        //public string Id { get; set; }
         /// <summary>
         /// 父级
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string Pid { get; set; }
         public SyllabusTree() 
         {

+ 2 - 2
TEAMModelOS.Model/Syllabus/Models/TeachingResource.cs

@@ -5,9 +5,9 @@ using System.Text;
 namespace TEAMModelOS.Model.Syllabus.Models
 {
     /// <summary>
-    /// 教学资源
+    /// 课件  教学资源
     /// </summary>
-    public class TeachingResource
+    public class Courseware
     {
         public string Id { get; set; }
         public string SyResId { get; set; }

+ 4 - 0
TEAMModelOS.Model/Syllabus/Models/KnowledgePoint.cs

@@ -13,5 +13,9 @@ namespace TEAMModelOS.Model.Syllabus.Models
         public string Id { get; set; }
         public string Pid { get; set; }
         public string Name { get; set; }
+        /// <summary>
+        /// 语言版本
+        /// </summary>
+        public string Lang { get; set; }
     }
 }

+ 2 - 2
TEAMModelOS.Model/Syllabus/Models/Period.cs

@@ -6,7 +6,7 @@ using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
-    [TableSpaceAttribute(Name = "Syllabus")]
+    [TableSpace(Name = "Syllabus")]
     public  class Period : TableEntity
     {
 
@@ -17,7 +17,7 @@ namespace TEAMModelOS.Model.Syllabus.Models
         /// <summary>
         /// 编码
         /// </summary>
-        public string Code { get; set; }
+        //public string Code { get; set; }
 
         /// <summary>
         /// 类型

+ 2 - 0
TEAMModelOS.Model/Syllabus/Models/PeriodSubject.cs

@@ -2,9 +2,11 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
+    [TableSpace(Name = "Syllabus")]
     public  class PeriodSubject : Period
     {
         /// <summary>

+ 2 - 0
TEAMModelOS.Model/Syllabus/Models/PeriodSubjectEdition.cs

@@ -1,9 +1,11 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
+    [TableSpace(Name = "Syllabus")]
     public class PeriodSubjectEdition : PeriodSubject
     {
         /// <summary>

+ 2 - 0
TEAMModelOS.Model/Syllabus/Models/PeriodSubjectEditionTerm.cs

@@ -2,12 +2,14 @@
 using System;
 using System.Collections.Generic;
 using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
     /// <summary>
     /// 学段册别表
     /// </summary>
+    [TableSpace(Name = "Syllabus")]
     public class PeriodSubjectEditionTerm : PeriodSubjectEdition
     {
         /// <summary>

+ 1 - 1
TEAMModelOS.Model/Syllabus/Models/SyllabusResource.cs

@@ -8,7 +8,7 @@ namespace TEAMModelOS.Model.Syllabus.Models
     /// <summary>
     /// 课纲资源
     /// </summary>
-    public class SyllabusResource : TableEntity
+    public class Resource : TableEntity
     {
         public string Id { get; set; }
         public string Name { get; set; }

+ 13 - 6
TEAMModelOS.Model/Syllabus/Models/Textbook.cs

@@ -1,35 +1,42 @@
 using Microsoft.WindowsAzure.Storage.Table;
 using System;
 using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
 using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
     /// <summary>
-    /// 教材
+    /// 标准教材
     /// </summary>
-    public class Textbook : TableEntity
+    [TableSpace(Name = "Syllabus")]
+    public class StandardTextbook : TableEntity
     {
         /// <summary>
         /// 学段
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string Period { get; set; }
         /// <summary>
         /// 学科
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string Subject { get; set; }
         /// <summary>
         /// 版本
         /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
         public string Edition { get; set; }
         /// <summary>
-        /// 名称
+        /// 册别
         /// </summary>
-        public string Name { get; set; }
+        [Required(ErrorMessage = "{0} 必须填写")]
+        public string Term { get; set; }
         /// <summary>
-        /// 年级
+        /// 名称 默认 学段+科目+版本+册别   
         /// </summary>
-        public string Grade { get; set; }
+        public string Name { get; set; }
         /// <summary>
         /// 备注
         /// </summary>

+ 5 - 6
TEAMModelOS.Model/Syllabus/Models/SyllabusNode.cs

@@ -4,7 +4,6 @@ using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
 using System.Text;
-using TEAMModelOS.SDK.Helper.Common.TreeList;
 
 namespace TEAMModelOS.Model.Syllabus.Models
 {
@@ -42,11 +41,11 @@ namespace TEAMModelOS.Model.Syllabus.Models
         /// </summary>
         [Required(ErrorMessage = "{0} 必须填写")]
         public string NodeKey { get; set; }
-        /// <summary>
-        ///主键
-        /// </summary>
-        [Required(ErrorMessage = "{0} 必须填写")]
-        public string Id { get; set; }
+        ///// <summary>
+        /////主键
+        ///// </summary>
+        //[Required(ErrorMessage = "{0} 必须填写")]
+        //public string Id { get; set; }
         /// <summary>
         /// 父级
         /// </summary>

+ 24 - 0
TEAMModelOS.Model/Syllabus/Models/TeacherTextbook.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using TEAMModelOS.SDK.Context.Attributes.Table;
+
+namespace TEAMModelOS.Model.Syllabus.Models
+{
+    [TableSpace(Name = "Syllabus")]
+    public class TeacherTextbook : StandardTextbook
+    {
+        /// <summary>
+        /// 醍摩豆ID
+        /// </summary>
+        public string TeamModelId { get; set; }
+        /// <summary>
+        ///标准教材RowKey
+        /// </summary>
+        public string StandardRowKey { get; set; }
+        /// <summary>
+        ///添加时间
+        /// </summary>
+        public DateTimeOffset AddTime { get; set; }
+    }
+}

+ 0 - 21
TEAMModelOS.Model/Syllabus/Models/TextbookStruct.cs

@@ -1,21 +0,0 @@
-using MessagePack;
-using Microsoft.WindowsAzure.Storage.Table;
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace TEAMModelOS.Model.Syllabus.Models
-{
-    [MessagePackObject(keyAsPropertyName: true)]
-    public class TextbookStruct: TableEntity
-    {
-        /// <summary>
-        /// 1.学段,2.学科,3.版本,4.册别
-        /// </summary>
-        public string Type { get; set; }
-        public string PCode { get; set; }
-        public string Code { get; set; }
-        public string Name { get; set; }
-        public bool Template { get; set; }
-    }
-}

+ 0 - 1
TEAMModelOS.Model/TEAMModelOS.Model.csproj

@@ -6,7 +6,6 @@
 
   <ItemGroup>
     <Folder Include="Analysis\Dtos\" />
-    <Folder Include="Common\" />
   </ItemGroup>
   <ItemGroup>
     <PackageReference Include="WindowsAzure.Storage" Version="9.3.3" />

+ 83 - 0
TEAMModelOS.SDK/Context/Filters/HttpGlobalExceptionFilter.cs

@@ -0,0 +1,83 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.Filters;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Exception;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using static TEAMModelOS.SDK.Context.Filter.HttpGlobalExceptionInvoke;
+
+namespace TEAMModelOS.SDK.Context.Filters
+{
+    /// <summary>
+    /// 全局异常处理
+    /// </summary>
+    public class HttpGlobalExceptionFilter : IExceptionFilter
+    {
+        readonly ILoggerFactory _loggerFactory;
+        readonly IHostingEnvironment _env;
+        public HttpGlobalExceptionFilter(ILoggerFactory loggerFactory, IHostingEnvironment env)
+        {
+            _loggerFactory = loggerFactory;
+            _env = env;
+        }
+        /// <summary>
+        /// 异常拦截
+        /// </summary>
+        /// <param name="context"></param>
+        public async void OnException(ExceptionContext context)
+        {
+            int code = context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
+            if (context.Exception is BizException)
+            {
+                context.HttpContext.Response.StatusCode = 200;
+            }
+            var errorResponse = new ErrorResponse<string>(1, context.Exception.Message);
+            // errorResponse.devMessage = context.Exception.StackTrace;
+            context.Result = new ApplicationErrorResult(errorResponse, code);
+            context.ExceptionHandled = true;
+            if (context.HttpContext.Response.StatusCode != 200)//未捕捉过并且状态码不为200
+            {
+                string msg = "";
+                switch (context.HttpContext.Response.StatusCode)
+                {
+                    case 401:
+                        msg = "Unauthorized";
+                        break;
+                    case 404:
+                        msg = "Service Not Found";
+                        break;
+                    case 502:
+                        msg = "Request Erro";
+                        break;
+                    case 500:
+                        msg = context.Exception.Message;
+                        break;
+                    default:
+                        msg = "Unknown Error";
+                        break;
+                }
+                await HandleExceptionAsync(context.HttpContext, context.HttpContext.Response.StatusCode, msg, context.Exception == null ? "" : context.Exception.StackTrace);
+            }
+        }
+
+        private static async Task HandleExceptionAsync(HttpContext context, int statusCode, string msg, string devmsg)
+        {
+            var data = new ErrorResponse<string>(statusCode, msg, devmsg);
+            context.Response.ContentType = "application/json;charset=utf-8";
+            await context.Response.WriteAsync(MessagePackHelper.ObjectToJson(data));
+        }
+    }
+    public class ApplicationErrorResult : ObjectResult
+    {
+        public ApplicationErrorResult(object value, int code) : base(value)
+        {
+            StatusCode = code;
+        }
+    }
+}

+ 3 - 1
TEAMModelOS.SDK/Extension/DataResult/JsonRpcRequest/JosnRPCRequest.cs

@@ -1,9 +1,11 @@
-using System;
+using MessagePack;
+using System;
 using System.Collections.Generic;
 using System.Text;
 
 namespace TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest
 {
+    [MessagePackObject(keyAsPropertyName: true)]
     public class JosnRPCRequest<T>:BaseJosnRPCRequest
     {
         public T @params { get; set; }

+ 3 - 1
TEAMModelOS.SDK/Extension/HttpClient/HttpClientExtension.cs

@@ -9,7 +9,9 @@ namespace TEAMModelOS.SDK.Extension.HttpClient
         {
             //services.AddHttpClient();
             //services.AddSingleton<HttpClientService>();
-            services.AddHttpClient<HttpClientService>();
+            services.AddHttpClient<HttpClientSendCloud>();
+            services.AddHttpClient<HttpClientUserInfo>();
+            services.AddHttpClient<HttpClientSchool>();
         }
     }
 }

+ 177 - 0
TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientSchool.cs

@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant.Common;
+using HttpClientSpace = System.Net.Http;
+
+namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
+{
+    /// <summary>
+    /// 需要调整的  https://blog.yowko.com/httpclientfactory-dotnet-core-dotnet-framework/
+    /// </summary>
+    public class HttpClientSchool
+    {
+        HttpClientSpace.HttpClient client { get; }
+        public HttpClientSchool(HttpClientSpace.HttpClient _client)
+        {
+            // _client.BaseAddress =new Uri(BaseConfigModel.Configuration["HaBookAuth:AccountUrl"]);
+            _client.Timeout = new TimeSpan(0, 0, 1000);
+            _client.DefaultRequestHeaders.Add(Constants.AUTHORIZATION, BaseConfigModel.Configuration["HaBookAuth:SchoolCodeKey"]);
+            client = _client;
+        }
+
+        /// <summary>
+        /// 同步GET请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="headers"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <returns></returns>
+        public string HttpGet(string url)
+        {
+
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            byte[] resultBytes = client.GetByteArrayAsync(url).Result;
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步GET请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="headers"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <returns></returns>
+        public async Task<string> HttpGetAsync(string url)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            byte[] resultBytes = await client.GetByteArrayAsync(url);
+            return Encoding.Default.GetString(resultBytes);
+        }
+
+
+        /// <summary>
+        /// 同步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public string HttpPost(string url, string postData,  string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new StringContent(postData ?? "", encoding ?? Encoding.UTF8);
+
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = client.PostAsync(url, content).Result;
+            byte[] resultBytes = responseMessage.Content.ReadAsByteArrayAsync().Result;
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public async Task<string> HttpPostAsync(string url, string postData, string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new StringContent(postData ?? "", encoding ?? Encoding.UTF8);
+
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = await client.PostAsync(url, content);
+            byte[] resultBytes = await responseMessage.Content.ReadAsByteArrayAsync();
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public async Task<string> HttpPostAsync(string url, List<KeyValuePair<string, string>> postData,  string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new FormUrlEncodedContent(postData);
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = await client.PostAsync(url, content);
+            byte[] resultBytes = await responseMessage.Content.ReadAsByteArrayAsync();
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+    }
+}

+ 40 - 37
TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientService.cs

@@ -3,6 +3,8 @@ using System.Collections.Generic;
 using System.Net.Http;
 using System.Text;
 using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant.Common;
 using HttpClientSpace = System.Net.Http;
 
 namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
@@ -10,11 +12,12 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
     /// <summary>
     /// 需要调整的  https://blog.yowko.com/httpclientfactory-dotnet-core-dotnet-framework/
     /// </summary>
-    public class HttpClientService
+    public class HttpClientSendCloud
     {
         HttpClientSpace.HttpClient client { get; }
-        public HttpClientService(HttpClientSpace.HttpClient _client)
+        public HttpClientSendCloud(HttpClientSpace.HttpClient _client)
         {
+           // _client.DefaultRequestHeaders.Add(Constants.AUTHORIZATION, BaseConfigModel.Configuration["SmsSendCloud:UserInfoKey"]);
             client = _client;
         }
 
@@ -28,13 +31,13 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
         public string HttpGet(string url, Dictionary<string, string> headers = null, int timeout = 0)
         {
 
-            if (headers != null)
-            {
-                foreach (KeyValuePair<string, string> header in headers)
-                {
-                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
-                }
-            }
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
             if (timeout > 0)
             {
                 client.Timeout = new TimeSpan(0, 0, timeout);
@@ -52,13 +55,13 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
         /// <returns></returns>
         public async Task<string> HttpGetAsync(string url, Dictionary<string, string> headers = null, int timeout = 0)
         {
-            if (headers != null)
-            {
-                foreach (KeyValuePair<string, string> header in headers)
-                {
-                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
-                }
-            }
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
             if (timeout > 0)
             {
                 client.Timeout = new TimeSpan(0, 0, timeout);
@@ -80,13 +83,13 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
         /// <returns></returns>
         public string HttpPost(string url, string postData, Dictionary<string, string> headers = null, string contentType = null, int timeout = 0, Encoding encoding = null)
         {
-            if (headers != null)
-            {
-                foreach (KeyValuePair<string, string> header in headers)
-                {
-                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
-                }
-            }
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
             if (timeout > 0)
             {
                 client.Timeout = new TimeSpan(0, 0, timeout);
@@ -114,13 +117,13 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
         /// <returns></returns>
         public async Task<string> HttpPostAsync(string url, string postData, Dictionary<string, string> headers = null, string contentType = null, int timeout = 0, Encoding encoding = null)
         {
-            if (headers != null)
-            {
-                foreach (KeyValuePair<string, string> header in headers)
-                {
-                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
-                }
-            }
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
             if (timeout > 0)
             {
                 client.Timeout = new TimeSpan(0, 0, timeout);
@@ -148,13 +151,13 @@ namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
         /// <returns></returns>
         public async Task<string> HttpPostAsync(string url, List<KeyValuePair<string, string>> postData, Dictionary<string, string> headers = null, string contentType = null, int timeout = 0, Encoding encoding = null)
         {
-            if (headers != null)
-            {
-                foreach (KeyValuePair<string, string> header in headers)
-                {
-                    client.DefaultRequestHeaders.Add(header.Key, header.Value);
-                }
-            }
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
             if (timeout > 0)
             {
                 client.Timeout = new TimeSpan(0, 0, timeout);

+ 177 - 0
TEAMModelOS.SDK/Extension/HttpClient/Implements/HttpClientUserInfo.cs

@@ -0,0 +1,177 @@
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant.Common;
+using HttpClientSpace = System.Net.Http;
+
+namespace TEAMModelOS.SDK.Extension.HttpClient.Implements
+{
+    /// <summary>
+    /// 需要调整的  https://blog.yowko.com/httpclientfactory-dotnet-core-dotnet-framework/
+    /// </summary>
+    public class HttpClientUserInfo
+    {
+        HttpClientSpace.HttpClient client { get; }
+        public HttpClientUserInfo(HttpClientSpace.HttpClient _client)
+        {
+            // _client.BaseAddress =new Uri(BaseConfigModel.Configuration["HaBookAuth:AccountUrl"]);
+            _client.Timeout = new TimeSpan(0, 0, 1000);
+            _client.DefaultRequestHeaders.Add(Constants.AUTHORIZATION, BaseConfigModel.Configuration["HaBookAuth:UserInfoKey"]);
+            client = _client;
+        }
+
+        /// <summary>
+        /// 同步GET请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="headers"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <returns></returns>
+        public string HttpGet(string url)
+        {
+
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            byte[] resultBytes = client.GetByteArrayAsync(url).Result;
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步GET请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="headers"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <returns></returns>
+        public async Task<string> HttpGetAsync(string url)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            byte[] resultBytes = await client.GetByteArrayAsync(url);
+            return Encoding.Default.GetString(resultBytes);
+        }
+
+
+        /// <summary>
+        /// 同步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public string HttpPost(string url, string postData,  string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new StringContent(postData ?? "", encoding ?? Encoding.UTF8);
+
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = client.PostAsync(url, content).Result;
+            byte[] resultBytes = responseMessage.Content.ReadAsByteArrayAsync().Result;
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public async Task<string> HttpPostAsync(string url, string postData, string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new StringContent(postData ?? "", encoding ?? Encoding.UTF8);
+
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = await client.PostAsync(url, content);
+            byte[] resultBytes = await responseMessage.Content.ReadAsByteArrayAsync();
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+
+        /// <summary>
+        /// 异步POST请求
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="postData"></param>
+        /// <param name="headers"></param>
+        /// <param name="contentType"></param>
+        /// <param name="timeout">请求响应超时时间,单位/s(默认100秒)</param>
+        /// <param name="encoding">默认UTF8</param>
+        /// <returns></returns>
+        public async Task<string> HttpPostAsync(string url, List<KeyValuePair<string, string>> postData,  string contentType = null, Encoding encoding = null)
+        {
+            //if (headers != null)
+            //{
+            //    foreach (KeyValuePair<string, string> header in headers)
+            //    {
+            //        client.DefaultRequestHeaders.Add(header.Key, header.Value);
+            //    }
+            //}
+            //if (timeout > 0)
+            //{
+            //    client.Timeout = new TimeSpan(0, 0, timeout);
+            //}
+            HttpContent content = new FormUrlEncodedContent(postData);
+            if (contentType != null)
+            {
+                content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
+            }
+            HttpResponseMessage responseMessage = await client.PostAsync(url, content);
+            byte[] resultBytes = await responseMessage.Content.ReadAsByteArrayAsync();
+            return Encoding.UTF8.GetString(resultBytes);
+        }
+    }
+}

+ 6 - 6
TEAMModelOS.SDK/Extension/JwtAuth/Filters/JwtAuthorizationFilter.cs

@@ -29,16 +29,16 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth.Filters
                 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.ToString().Trim();
+                tokenHeader = tokenHeader.Trim();
             }
-            if (httpContext.Request.Headers.ContainsKey(HttpConstant.Authorization)) {
-                tokenHeader = httpContext.Request.Headers[HttpConstant.Authorization];
-                tokenHeader = tokenHeader.ToString().Substring("Bearer ".Length).Trim();
-            }
-
             ClaimModel claimModel = JwtHelper.JwtHelper.SerializeJWT(tokenHeader);
 
             //将tokenModel存入缓存中

+ 11 - 2
TEAMModelOS.SDK/Extension/JwtAuth/JwtAuthExtension.cs

@@ -6,8 +6,10 @@ using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.IdentityModel.Tokens;
 using System;
-using System.Text;
 using System.Threading.Tasks;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Helper.Security.RSACrypt;
+using TEAMModelOS.SDK.Extension.JwtAuth.Requirements;
 
 namespace TEAMModelOS.SDK.Extension.JwtAuth
 {
@@ -16,7 +18,11 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth
         public static void JwtAuth(this IServiceCollection services , IConfigurationSection configuration)
         {
             services.Configure<JwtSetting>(configuration);
-            var creds = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"]));
+            // 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 + "/JwtRsaFile/private.pem"));
+            //RsaSecurityKey creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["SecurityKey"])), SecurityAlgorithms.RsaSha256Signature);
             // 令牌验证参数
             var tokenValidationParameters = new TokenValidationParameters
             {
@@ -75,8 +81,11 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth
                 auth.AddPolicy("Bearer", new AuthorizationPolicyBuilder()
                     .AddAuthenticationSchemes(JwtBearerDefaults.AuthenticationScheme)
                     .RequireAuthenticatedUser()
+                    .AddRequirements(new ValidJtiRequirement()) // 添加上面的验证要求
                     .Build());
             });
+            // 注册验证要求的处理器,可通过这种方式对同一种要求添加多种验证
+            services.AddSingleton<IAuthorizationHandler, ValidJtiHandler>();
         }
         
     }

+ 16 - 7
TEAMModelOS.SDK/Extension/JwtAuth/JwtHelper/JwtHelper.cs

@@ -8,6 +8,9 @@ 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
 {
@@ -39,19 +42,21 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper
             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.ToArray().Select(s=>new Claim(JwtClaimTypes.Role,s)));
-            var creds = new SigningCredentials(new SymmetricSecurityKey(Encoding.UTF8.GetBytes(setting.SecurityKey)), SecurityAlgorithms.HmacSha512);
+            string path = BaseConfigModel.ContentRootPath;
+            RSACryptoServiceProvider provider = RsaHelper.LoadCertificateFile(path + "/JwtRsaFile/private.pem");
+            RsaSecurityKey rsaSecurity = new RsaSecurityKey(provider);
+            var creds =new SigningCredentials(rsaSecurity, SecurityAlgorithms.RsaSha256);
+
             var jwt = new JwtSecurityToken(
                 claims:claims,
                 signingCredentials:creds
                 );
             var jwtHandler = new JwtSecurityTokenHandler();
-              jwtHandler.WriteToken(jwt);
-
-
             return new JwtResponse {
-                access_token = jwtHandler.WriteToken(jwt),
-                scope = claimModel.Scope
+                Access_token = jwtHandler.WriteToken(jwt),
+                Scope = claimModel.Scope
             };
         }
         /// <summary>
@@ -61,12 +66,16 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper
         /// <returns></returns>
         public static ClaimModel SerializeJWT(string jwtStr)
         {
+
+            ///https://www.cnblogs.com/JacZhu/p/6837676.html#Update2.0  刷新     用户的 Token 在过期时间之内根本无法手动设置失效,随之而来的还有重放攻击等等问题
+
             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);
             claimModel.Claims = jwtToken.Claims.ToList();
-            jwtToken.Payload.TryGetValue("role", out role);
+            jwtToken.Payload.TryGetValue(JwtClaimTypes.Role, out role);
             if(role!=null)claimModel.Roles=role.ToString().Split(",").ToList();
             return claimModel;
         }

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

@@ -8,14 +8,20 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
     {
         public ClaimModel() {
             Claims = new List<Claim>();
+            Claim = new Dictionary<string, string>();
             Roles = new List<string>();
         }
 
+
         /// <summary>
         /// 用户身份信息
         /// </summary>
         public List<Claim> Claims { get; set; }
         /// <summary>
+        /// 用户身份信息
+        /// </summary>
+        public Dictionary<string ,string> Claim { get; set; }
+        /// <summary>
         /// 用户角色信息
         /// </summary>
         public List<string> Roles { get; set; }

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

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

+ 5 - 3
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtResponse.cs

@@ -1,13 +1,15 @@
 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 scope { get; set; }
+        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; }
     }
 }

+ 1 - 1
TEAMModelOS.SDK/Extension/JwtAuth/Models/JwtSetting.cs

@@ -25,6 +25,6 @@ namespace TEAMModelOS.SDK.Extension.JwtAuth.Models
         /// <summary>
         /// JWT Secret Key
         /// </summary>
-        public string SecurityKey { get; set; }
+        //public string SecurityKey { get; set; }
     }
 }

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

@@ -0,0 +1,15 @@
+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; }
+    }
+}

+ 44 - 0
TEAMModelOS.SDK/Extension/JwtAuth/Requirements/ValidJtiHandler.cs

@@ -0,0 +1,44 @@
+using Microsoft.AspNetCore.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.SDK.Extension.JwtAuth.Models;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+
+namespace TEAMModelOS.SDK.Extension.JwtAuth.Requirements
+{
+    public class ValidJtiHandler : AuthorizationHandler<ValidJtiRequirement>
+    {
+        private IAzureTableDBRepository _azureTableDBRepository;
+
+        public ValidJtiHandler(IAzureTableDBRepository azureTableDBRepository)
+        {
+            _azureTableDBRepository = azureTableDBRepository;
+        }
+        protected override  Task HandleRequirementAsync(AuthorizationHandlerContext context, ValidJtiRequirement requirement)
+        {
+            // 检查 Jti 是否存在
+            var jti = context.User.FindFirst("jti")?.Value;
+            if (jti == null)
+            {
+                context.Fail(); // 显式的声明验证失败
+                return Task.CompletedTask;
+            }
+
+            // 检查 jti 是否在黑名单
+            // 使用Redis  对于连续访问的token 进行限制
+            JwtBlackRecord record =  _azureTableDBRepository.FindOneByKey<JwtBlackRecord>("Jti",jti).Result;
+            if (record != null  && !string.IsNullOrEmpty(record.RowKey))
+            {
+                context.Fail();
+            }
+            else
+            {
+                context.Succeed(requirement); // 显式的声明验证成功
+            }
+            return Task.CompletedTask;
+
+        }
+    }
+}

+ 9 - 0
TEAMModelOS.SDK/Extension/JwtAuth/Requirements/ValidJtiRequirement.cs

@@ -0,0 +1,9 @@
+using Microsoft.AspNetCore.Authorization;
+
+namespace TEAMModelOS.SDK.Extension.JwtAuth.Requirements
+{
+    public class ValidJtiRequirement : IAuthorizationRequirement
+    {
+        
+    }
+}

+ 2 - 2
TEAMModelOS.SDK/Extension/MessagePush/Implements/SendCloudService.cs

@@ -20,8 +20,8 @@ namespace TEAMModelOS.SDK.Extension.MessagePush.Implements
         public SmsSendCloud smsSendCloud;
         public ILanguageService _languageService;
         public IAzureTableDBRepository _azureTableDBRepository;
-        public HttpClientService _httpClientService;
-        public SendCloudService(IOptions<SmsSendCloud> _option, ILanguageService languageService , IAzureTableDBRepository azureTableDBRepository ,HttpClientService httpClientService )
+        public HttpClientSendCloud _httpClientService;
+        public SendCloudService(IOptions<SmsSendCloud> _option, ILanguageService languageService , IAzureTableDBRepository azureTableDBRepository , HttpClientSendCloud httpClientService )
         {
             _azureTableDBRepository = azureTableDBRepository;
             _languageService = languageService;

+ 43 - 0
TEAMModelOS.SDK/Helper/Common/CollectionHelper/CollectionHelper.cs

@@ -0,0 +1,43 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using System.Text;
+
+namespace TEAMModelOS.SDK.Helper.Common.CollectionHelper
+{
+    public static class CollectionHelper
+    {
+        /// <summary>
+        /// 判断集合是否为空
+        /// </summary>
+        /// <param name="collection"></param>
+        /// <returns></returns>
+        public static bool IsEmpty(this ICollection collection)
+        {
+            if (collection != null && collection.Count > 0)
+            {
+                return false;
+            }
+            else {
+                return true;
+            }
+        }
+        /// <summary>
+        /// 判断集合是否不为空
+        /// </summary>
+        /// <param name="collection"></param>
+        /// <returns></returns>
+        public static bool IsNotEmpty(this ICollection collection)
+        {
+            if (collection != null && collection.Count > 0)
+            {
+                return true;
+            }
+            else
+            {
+                return false;
+            }
+        }
+    }
+}

+ 34 - 0
TEAMModelOS.SDK/Helper/Common/JsonHelper/JsonSerialization.cs

@@ -55,6 +55,40 @@ namespace TEAMModelOS.SDK.Helper.Common.JsonHelper
                 return default(T);
             }
         }
+
+
+        /// <summary>
+        /// 从字典获取对象
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="input"></param>
+        /// <param name="dateTimeFormat">默认null,即使用json.net默认的序列化机制</param>
+        /// <returns></returns>
+        public static T DictToObj<T>(this Dictionary<string,object> dict, string dateTimeFormat = "yyyy-MM-dd HH:mm:ss", bool ignoreNullValue = true)
+        {
+            try
+            {
+                string input= ToJson(dict);
+                return input.FromJson<T>(dateTimeFormat, ignoreNullValue);
+            }
+            catch
+            {
+                return default(T);
+            }
+        }
+        /// <summary>
+        /// 从对象获取字典
+        /// </summary>
+        /// <param name="obj"></param>
+        /// <param name="dateTimeFormat"></param>
+        /// <param name="ignoreNullValue"></param>
+        /// <returns></returns>
+        public static Dictionary<string ,object> ObjToDict(this object obj, string dateTimeFormat = "yyyy-MM-dd HH:mm:ss", bool ignoreNullValue = true)
+        {
+            string input = ToJson(obj);
+            return input.FromJson<Dictionary<string, object>>(dateTimeFormat, ignoreNullValue);
+        }
+
         /// <summary>
         /// 从序列化字符串里反序列化
         /// </summary>

+ 0 - 32
TEAMModelOS.SDK/Helper/Common/TreeList/ListToTree.cs

@@ -1,32 +0,0 @@
-using Microsoft.WindowsAzure.Storage.Table;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using TEAMModelOS.SDK.Helper.Common.JsonHelper;
-
-namespace TEAMModelOS.SDK.Helper.Common.TreeList
-{
-    public class ListToTree
-    {
-        public static List<N> Convert<N>(List<N> list) where N: Node , new() {
-            var lookup = list.ToDictionary(n => n.Id, n => n);
-            var rootNodes = new List<N>();
-            foreach (var node in list)
-            {
-                if (!string.IsNullOrEmpty(node.Pid))
-                {
-                    Tree<N> parent = new Tree<N>();
-                    bool  s=   lookup.TryGetValue(node.Pid ,out N ss);
-                    parent.Children.Add(MessagePackHelper.JsonToObject<Tree<N>>(MessagePackHelper.ObjectToJson(node)));
-                }
-                else
-                {
-                    rootNodes.Add(node);
-                }
-            }
-            return rootNodes;
-        }
-    }
-}

+ 0 - 15
TEAMModelOS.SDK/Helper/Common/TreeList/Node.cs

@@ -1,15 +0,0 @@
-using MessagePack;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using TEAMModelOS.SDK.Module.GrpcServer.Implements;
-
-namespace TEAMModelOS.SDK.Helper.Common.TreeList
-{
-    
-    public interface Node 
-    {
-         dynamic Id { get; set; }
-         dynamic Pid { get; set; }
-    }
-}

+ 0 - 14
TEAMModelOS.SDK/Helper/Common/TreeList/Tree.cs

@@ -1,14 +0,0 @@
-using MessagePack;
-using System;
-using System.Collections.Generic;
-
-namespace TEAMModelOS.SDK.Helper.Common.TreeList
-{
-    [MessagePackObject(keyAsPropertyName: true)]
-    public class Tree<N>
-    {
-        public dynamic Id { get; set; }
-        public dynamic Pid { get; set; }
-        public List<Tree<N>> Children { get; set; } = new List<Tree<N>>();
-    }
-}

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

@@ -1,7 +1,12 @@
 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
 {
@@ -92,5 +97,26 @@ namespace TEAMModelOS.SDK.Helper.Network.HttpHelper
             }
             return aktoken;
         }
+        public static 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.Trim();
+            }
+            if (string.IsNullOrEmpty(tokenHeader)) {
+                return "";
+            }
+            ClaimModel claimModel = JwtHelper.SerializeJWT(tokenHeader);
+            claimModel.Claim.TryGetValue(claimType, out var claimValue);
+            return claimValue; 
+        }
     }
 }

+ 173 - 0
TEAMModelOS.SDK/Helper/Security/RSACrypt/RsaHelper.cs

@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Security.Cryptography;
+using System.Text;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+
+namespace TEAMModelOS.SDK.Helper.Security.RSACrypt
+{
+    public static class RsaHelper
+    {
+        public static string RSASign(string data, string privateKeyPem)
+        {
+            RSACryptoServiceProvider rsaCsp = LoadCertificateFile(privateKeyPem);
+            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
+            byte[] signatureBytes = rsaCsp.SignData(dataBytes, "SHA1");
+            return Convert.ToBase64String(signatureBytes);
+        }
+
+        private static byte[] GetPem(string type, byte[] data)
+        {
+            string pem = Encoding.UTF8.GetString(data);
+            string header = String.Format("-----BEGIN {0}-----\\n", type);
+            string footer = String.Format("-----END {0}-----", type);
+            int start = pem.IndexOf(header) + header.Length;
+            int end = pem.IndexOf(footer, start);
+            string base64 = pem.Substring(start, (end - start));
+            return Convert.FromBase64String(base64);
+        }
+        public static string LoadCertificateFileToSting(string filename)
+        {
+            FileStream fs = System.IO.File.OpenRead(filename);
+            byte[] data = new byte[fs.Length];
+            byte[] res = null;
+            fs.Read(data, 0, data.Length);
+            if (data[0] != 0x30)
+            {
+                res = GetPem("RSA PRIVATE KEY", data);
+            }
+            return res.ToJson();
+        }
+        public static RSACryptoServiceProvider LoadCertificateFile(string filename)
+        {
+            FileStream fs = System.IO.File.OpenRead(filename);
+            byte[] data = new byte[fs.Length];
+            byte[] res = null;
+            fs.Read(data, 0, data.Length);
+            if (data[0] != 0x30)
+            {
+                res = GetPem("RSA PRIVATE KEY", data);
+            }
+            string ss = res.ToJson();
+            RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(res);
+            return rsa;
+        }
+
+        private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
+        {
+            byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
+
+            // --------- Set up stream to decode the asn.1 encoded RSA private key ------
+            MemoryStream mem = new MemoryStream(privkey);
+            BinaryReader binr = new BinaryReader(mem);  //wrap Memory Stream with BinaryReader for easy reading
+            byte bt = 0;
+            ushort twobytes = 0;
+            int elems = 0;
+            try
+            {
+                twobytes = binr.ReadUInt16();
+                if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
+                    binr.ReadByte();    //advance 1 byte
+                else if (twobytes == 0x8230)
+                    binr.ReadInt16();    //advance 2 bytes
+                else
+                    return null;
+
+                twobytes = binr.ReadUInt16();
+                if (twobytes != 0x0102) //version number
+                    return null;
+                bt = binr.ReadByte();
+                if (bt != 0x00)
+                    return null;
+
+
+                //------ all private key components are Integer sequences ----
+                elems = GetIntegerSize(binr);
+                MODULUS = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                E = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                D = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                P = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                Q = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                DP = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                DQ = binr.ReadBytes(elems);
+
+                elems = GetIntegerSize(binr);
+                IQ = binr.ReadBytes(elems);
+                // ------- create RSACryptoServiceProvider instance and initialize with public key -----
+                CspParameters CspParameters = new CspParameters
+                {
+                    Flags = CspProviderFlags.UseMachineKeyStore
+                };
+                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(1024, CspParameters);
+                RSAParameters RSAparams = new RSAParameters
+                {
+                    Modulus = MODULUS,
+                    Exponent = E,
+                    D = D,
+                    P = P,
+                    Q = Q,
+                    DP = DP,
+                    DQ = DQ,
+                    InverseQ = IQ
+                };
+                RSA.ImportParameters(RSAparams);
+                return RSA;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception("", ex);
+            }
+            finally
+            {
+                binr.Close();
+            }
+        }
+
+        private static int GetIntegerSize(BinaryReader binr)
+        {
+            byte bt = 0;
+            byte lowbyte = 0x00;
+            byte highbyte = 0x00;
+            int count = 0;
+            bt = binr.ReadByte();
+            if (bt != 0x02)        //expect integer
+                return 0;
+            bt = binr.ReadByte();
+
+            if (bt == 0x81)
+                count = binr.ReadByte();    // data size in next byte
+            else
+                if (bt == 0x82)
+            {
+                highbyte = binr.ReadByte();    // data size in next 2 bytes
+                lowbyte = binr.ReadByte();
+                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
+                count = BitConverter.ToInt32(modint, 0);
+            }
+            else
+            {
+                count = bt;        // we already have the data size
+            }
+
+            while (binr.ReadByte() == 0x00)
+            {    //remove high order zeros in data
+                count -= 1;
+            }
+            binr.BaseStream.Seek(-1, SeekOrigin.Current);        //last ReadByte wasn't a removed zero, so back up a byte
+            return count;
+        }
+    }
+}

+ 63 - 8
TEAMModelOS.SDK/Module/AzureCosmosDB/Implements/AzureCosmosDBRepository.cs

@@ -15,6 +15,10 @@ using TEAMModelOS.SDK.Context.Attributes.Table;
 
 namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
 {
+    /// <summary>
+    /// sdk 文档https://github.com/Azure/azure-cosmos-dotnet-v2/tree/master/samples
+    /// https://github.com/Azure/azure-cosmos-dotnet-v2/blob/530c8d9cf7c99df7300246da05206c57ce654233/samples/code-samples/DatabaseManagement/Program.cs#L72-L121
+    /// </summary>
     public class AzureCosmosDBRepository : IAzureCosmosDBRepository
     {
 
@@ -71,7 +75,7 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
 
 
         }
-        private async Task InitializeCollection<T>()
+        private async Task<DocumentCollection> InitializeCollection<T>()
         {
             Type t = typeof(T);
             if (CosmosCollection == null || !CosmosCollection.Id.Equals(t.Name))
@@ -87,15 +91,16 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
                 }
                 CosmosCollection = await this.CosmosClient.CreateDocumentCollectionIfNotExistsAsync(UriFactory.CreateDatabaseUri(_Database), collectionDefinition);
 
-
             }
+
+            return CosmosCollection;
         }
+
         private string GetPartitionKey<T>()
         {
             Type type = typeof(T);
             PropertyInfo[] properties = type.GetProperties();
             List<PropertyInfo> attrProperties = new List<PropertyInfo>();
-           
             foreach (PropertyInfo property in properties)
             {
                 object[] attributes = property.GetCustomAttributes(true);
@@ -124,10 +129,12 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
         public async Task<T> Save<T>(T entity) //where T : object, new()
         {
             Type t = typeof(T);
-            await InitializeCollection<T>();
+            DocumentCollection documentCollection = await InitializeCollection<T>();
             ResourceResponse<Document> doc =
                 await CosmosClient.CreateDocumentAsync(UriFactory.CreateDocumentCollectionUri(_Database, t.Name), entity);
             //Console.WriteLine(doc.ActivityId);
+
+
             return entity;
         }
 
@@ -161,10 +168,12 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
         public async Task<List<T>> FindAll<T>()
         {
             Type t = typeof(T);
+            Boolean open = true;
             List<T> objs = new List<T>();
+
             //await InitializeCollection<T>();
             //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };
+            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = open };
             var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_Database, t.Name), queryOptions).AsDocumentQuery();
             while (query.HasMoreResults)
             {
@@ -208,19 +217,66 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
 
         }
 
+        public async Task<List<T>> FindSQL<T>(string sql, bool IsPk)
+        {
+            Type t = typeof(T);
+            List<T> objs = new List<T>();
+            Boolean open = IsPk;
+            await InitializeCollection<T>();
+            //查询条数 -1是全部
+            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = open };
+            var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_Database, t.Name), sql, queryOptions);
+            foreach (var item in query)
+            {
+                objs.Add(item);
+            }
+            return objs;
+
+        }
+
+
+
         public async Task<List<T>> FindByparams<T>(Dictionary<string, object> dict)
         {
             //await InitializeCollection<T>();
+            Type t = typeof(T);
+            Boolean open = true;
             List<Filter> filters = new List<Filter>();
+
+            string PKname = "";
+            PropertyInfo[] properties = t.GetProperties();
+            List<PropertyInfo> attrProperties = new List<PropertyInfo>();
+            foreach (PropertyInfo property in properties)
+            {
+                object[] attributes = property.GetCustomAttributes(true);
+                foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
+                {
+                    if (attribute is PartitionAttribute)
+                    {
+                        PKname = property.Name;
+                        break;
+                    }
+                }
+            }
+
             foreach (string key in dict.Keys)
             {
+                //if (t.Name.Equals(key)) {
+                //    open = false;
+                //}
+
+                if (PKname.Equals(key))
+                {
+                    open = false;
+                }
                 filters.Add(new Filter { Key = key, Value = dict[key] != null ? dict[key].ToString() : throw new Exception("参数值不能为null") });
             }
-            Type t = typeof(T);
+
+
             //List<T> objs = new List<T>();
             await InitializeCollection<T>();
             //查询条数 -1是全部
-            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1 };
+            FeedOptions queryOptions = new FeedOptions { MaxItemCount = -1, EnableCrossPartitionQuery = open };
             var query = CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_Database, t.Name), queryOptions);
 
             List<T> list = DynamicLinq.GenerateFilter<T>(query, filters).ToList();
@@ -228,7 +284,6 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Implements
             //return CosmosClient.CreateDocumentQuery<T>(UriFactory.CreateDocumentCollectionUri(_Database, t.Name),sql);
 
         }
-
         public async Task<string> DeleteAsync<T>(string id)
         {
             Type t = typeof(T);

+ 1 - 2
TEAMModelOS.SDK/Module/AzureCosmosDB/Interfaces/IAzureCosmosDBRepository.cs

@@ -13,9 +13,8 @@ namespace TEAMModelOS.SDK.Module.AzureCosmosDB.Interfaces
         Task<string> ReplaceObject<T>(T entity, string key);
         Task<List<T>> FindAll<T>();
         Task<string> DeleteAsync<T>(string id);
-
         Task<List<T>> FindSQL<T>(string sql);
-
+        Task<List<T>> FindSQL<T>(string sql, bool isPK);
         Task<List<T>> FindLinq<T>(Func<IQueryable<object>, object> singleOrDefault);
         Task<List<T>> FindByparams<T>(Dictionary<string, object> dict);
     }

+ 292 - 100
TEAMModelOS.SDK/Module/AzureTable/Implements/AzureTableDBRepository.cs

@@ -12,6 +12,7 @@ using TEAMModelOS.SDK.Helper.Security.AESCrypt;
 using TEAMModelOS.SDK.Context.Exception;
 using System.Reflection;
 using TEAMModelOS.SDK.Context.Attributes.Table;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 
 namespace TEAMModelOS.SDK.Module.AzureTable.Implements
 {
@@ -64,9 +65,8 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
             object[] attributes = type.GetCustomAttributes(true);
             foreach (object attribute in attributes) //2.通过映射,找到成员属性上关联的特性类实例,
             {
-                if (attribute is TableSpaceAttribute)
+                if (attribute is TableSpaceAttribute tableSpace)
                 {
-                    TableSpaceAttribute tableSpace = (TableSpaceAttribute)attribute;
                     Name = tableSpace.Name + Name;
                 }
             }
@@ -75,12 +75,12 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
 
         public async Task<List<T>> FindAll<T>() where T : TableEntity, new()
         {
-            string TableName= await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
-            return await QueryList<T>(exQuery , TableName);
+            return await QueryList<T>(exQuery, TableName);
         }
 
-        private async Task<List<T>> QueryList<T>(TableQuery<T> exQuery ,string TableName) where T : TableEntity, new()
+        private async Task<List<T>> QueryList<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
         {
             TableContinuationToken continuationToken = null;
             List<T> entitys = new List<T>();
@@ -95,9 +95,9 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
             } while (continuationToken != null);
             return entitys;
         }
-      
 
-        private async Task<T> QueryObject<T>(TableQuery<T> exQuery ,string TableName) where T : TableEntity, new()
+
+        private async Task<T> QueryObject<T>(TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
         {
             TableContinuationToken continuationToken = null;
             T entity = new T();
@@ -113,7 +113,7 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
             return entity;
         }
 
-        public async Task<int> Count<T>(TableContinuationToken continuationToken ) where T : TableEntity, new()
+        public async Task<int> Count<T>(TableContinuationToken continuationToken) where T : TableEntity, new()
         {
             string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
@@ -132,7 +132,7 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
 
         public async Task<int> Count<T>() where T : TableEntity, new()
         {
-            string TableName =  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             TableContinuationToken continuationToken = null;
             var exQuery = new TableQuery<T>();
             List<T> entitys = new List<T>();
@@ -148,26 +148,28 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
             return entitys.Count;
         }
 
-        public async Task<T> FindById<T>(string id) where T : TableEntity, new()
+        public async Task<T> FindByRowKey<T>(string id) where T : TableEntity, new()
         {
             string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
             if (!string.IsNullOrEmpty(id))
             {
-                exQuery.Where(TableQuery.GenerateFilterCondition("Id", QueryComparisons.Equal, id));
-                return await QueryObject<T>(exQuery , TableName);
+                string typeStr = SwitchType(id, "RowKey");
+                exQuery.Where(typeStr);
+                // exQuery.Where(TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, id));
+                return await QueryObject<T>(exQuery, TableName);
             }
             else
             {
-                return null; 
+                return null;
             }
-           
+
 
         }
 
         public async Task<List<T>> FindListByDict<T>(Dictionary<string, object> dict) where T : TableEntity, new()
         {
-            string TableName=  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
             StringBuilder builder = new StringBuilder();
             if (null != dict && dict.Count > 0)
@@ -178,13 +180,19 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
                 {
                     if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
                     {
+                        string typeStr = SwitchType(dict[key], key);
+
                         if (index == 1)
                         {
-                            builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append(typeStr);
+
                         }
                         else
                         {
-                            builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            //builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append("  " + TableOperators.And + "  " + typeStr);
+
                         }
                         index++;
                     }
@@ -193,30 +201,35 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
                 exQuery.Where(builder.ToString());
                 return await QueryList<T>(exQuery, TableName);
             }
-            else {
-                return null; 
+            else
+            {
+                return null;
             }
         }
 
-        public async Task<List<T>> FindListByKey<T>(string key, string value) where T : TableEntity, new()
+        public async Task<List<T>> FindListByKey<T>(string key, object value) where T : TableEntity, new()
         {
             string TableName = await InitializeTable<T>();
 
             var exQuery = new TableQuery<T>();
-            if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
+            if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
             {
-                exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, value));
+
+                string typeStr = SwitchType(value, key);
+                exQuery.Where(typeStr);
+                //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, value));
                 return await QueryList<T>(exQuery, TableName);
             }
-            else {
-                return null; 
+            else
+            {
+                return null;
             }
-            
+
         }
 
         public async Task<T> FindOneByDict<T>(IDictionary<string, object> dict) where T : TableEntity, new()
         {
-            string TableName =  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
             StringBuilder builder = new StringBuilder();
             if (null != dict && dict.Count > 0)
@@ -227,47 +240,78 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
                 {
                     if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
                     {
+
+
+                        string typeStr = SwitchType(dict[key], key);
+
                         if (index == 1)
                         {
-                            builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append(typeStr);
                         }
                         else
                         {
-                            builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            // builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append("  " + TableOperators.And + "  " + typeStr);
                         }
                         index++;
                     }
                 }
                 exQuery.Where(builder.ToString());
-                return await QueryObject<T>(exQuery ,TableName);
+                return await QueryObject<T>(exQuery, TableName);
             }
             else
             {
-                return null; 
+                return null;
+            }
+
+        }
+
+        private static string SwitchType(object obj, string key)
+        {
+            Type s = obj.GetType();
+            TypeCode typeCode = Type.GetTypeCode(s);
+
+            switch (typeCode)
+            {
+
+                case TypeCode.String: return TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, obj.ToString());
+                case TypeCode.Int32: return TableQuery.GenerateFilterConditionForInt(key, QueryComparisons.Equal, (int)obj);
+                case TypeCode.Double: return TableQuery.GenerateFilterConditionForDouble(key, QueryComparisons.Equal, (double)obj);
+                case TypeCode.Byte: return TableQuery.GenerateFilterConditionForBinary(key, QueryComparisons.Equal, (byte[])obj);
+                case TypeCode.Boolean: return TableQuery.GenerateFilterConditionForBool(key, QueryComparisons.Equal, (bool)obj);
+                case TypeCode.DateTime: return TableQuery.GenerateFilterConditionForDate(key, QueryComparisons.Equal, (DateTimeOffset)obj);
+                case TypeCode.Int64: return TableQuery.GenerateFilterConditionForLong(key, QueryComparisons.Equal, (long)obj);
+
+                default: return null;
             }
-            
         }
 
-        public async Task<T> FindOneByKey<T>(string key, string value) where T : TableEntity, new()
+        public async Task<T> FindOneByKey<T>(string key, object value) where T : TableEntity, new()
         {
             string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
-            if (!string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(value))
+            if (!string.IsNullOrEmpty(key) && value != null && !string.IsNullOrEmpty(value.ToString()))
             {
-                exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal,
-                                                                          value));
-                return await QueryObject<T>(exQuery ,TableName );
+
+                string typeStr = SwitchType(value, key);
+                exQuery.Where(typeStr);
+                //exQuery.Where(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal,
+                //                                                          value));
+
+
+                return await QueryObject<T>(exQuery, TableName);
             }
             else
             {
                 return null;
             }
-            
+
         }
 
         public async Task<List<T>> GetEntities<T>(IDictionary<string, object> dict) where T : TableEntity, new()
         {
-           string TableName=  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
             StringBuilder builder = new StringBuilder();
             if (null != dict && dict.Count > 0)
@@ -278,22 +322,29 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
                 {
                     if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
                     {
+                        string typeStr = SwitchType(dict, key);
+
                         if (index == 1)
                         {
-                            builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            //builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append(typeStr);
+
                         }
                         else
                         {
-                            builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            // builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append("  " + TableOperators.And + "  " + typeStr);
+
                         }
                         index++;
                     }
                 }
                 exQuery.Where(builder.ToString());
-                return await QueryList<T>(exQuery,  TableName);
+                return await QueryList<T>(exQuery, TableName);
             }
-            else {
-                return null; 
+            else
+            {
+                return null;
             }
         }
 
@@ -301,73 +352,210 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
 
         public async Task<List<T>> SaveAll<T>(List<T> entitys) where T : TableEntity, new()
         {
-            await InitializeTable<T>();
-            IList<TableResult> result = null;
-            Parallel.ForEach(Partitioner.Create(0, entitys.Count, 100),
-                  async range =>
-                  {
-                      TableBatchOperation batchOperation = new TableBatchOperation();
-                      for (Int32 i = range.Item1; i < range.Item2; i++)
-                          batchOperation.Insert(entitys[i]);
-                      result = await Table.ExecuteBatchAsync(batchOperation);
-                  });
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            string TableName = await InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
+                    //  async range =>
+                    //  {
+                    //      TableBatchOperation batchOperation = new TableBatchOperation();
+                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
+                    //          batchOperation.Insert(values[i]);
+                    //      result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    //  });
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Insert(lists[j]);
+                        }
+                        result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
             return entitys;
         }
 
         public async Task<List<T>> UpdateAll<T>(List<T> entitys) where T : TableEntity, new()
         {
-            await InitializeTable<T>();
-            IList<TableResult> result = null;
-            Parallel.ForEach(Partitioner.Create(0, entitys.Count, 100),
-                  async range =>
-                  {
-                      TableBatchOperation batchOperation = new TableBatchOperation();
-                      for (Int32 i = range.Item1; i < range.Item2; i++)
-                          batchOperation.Replace(entitys[i]);
-                      result = await Table.ExecuteBatchAsync(batchOperation);
-                  });
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            string TableName = await InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
+                    //  async range =>
+                    //  {
+                    //      TableBatchOperation batchOperation = new TableBatchOperation();
+                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
+                    //          batchOperation.Replace(values[i]);
+                    //      result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    //  });
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Replace(lists[j]);
+                        }
+                        result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
             return entitys;
         }
 
-        public async Task<List<T>> SaveOrUpdateAll<T>(List<T> entitys) where T : TableEntity, new() {
-            await InitializeTable<T>();
-            IList<TableResult> result = null;
-            Parallel.ForEach(Partitioner.Create(0, entitys.Count, 100),
-                  async range =>
-                  {
-                      TableBatchOperation batchOperation = new TableBatchOperation();
-                      for (Int32 i = range.Item1; i < range.Item2; i++)
-                          batchOperation.InsertOrReplace(entitys[i]);
-                      result = await Table.ExecuteBatchAsync(batchOperation);
-                  });
+        public async Task<List<T>> SaveOrUpdateAll<T>(List<T> entitys) where T : TableEntity, new()
+        {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
+            string TableName = await InitializeTable<T>();
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 50),
+                    //  async range =>
+                    //  {
+                    //      TableBatchOperation batchOperation = new TableBatchOperation();
+                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
+                    //          batchOperation.InsertOrReplace(values[i]);
+                    //      result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    //  });
+                  
+                    int pageSize = 100; 
+                    int pages = (int)Math.Ceiling((double)values.Count/ pageSize);
+                    for (int i= 0; i < pages; i++) {
+                        List<T> lists=  values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.InsertOrReplace(lists[j]);
+                        }
+                        result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
             return entitys;
         }
+
+
+
+
         public async Task<List<T>> DeleteAll<T>(List<T> entitys) where T : TableEntity, new()
         {
+            if (entitys.IsEmpty())
+            {
+                return null;
+            }
             string TableName = await InitializeTable<T>();
-            IList<TableResult> result = null;
-            Parallel.ForEach(Partitioner.Create(0, entitys.Count, 100),
-                  async range =>
-                  {
-                      TableBatchOperation batchOperation = new TableBatchOperation();
-                      for (Int32 i = range.Item1; i < range.Item2; i++)
-                          batchOperation.Delete(entitys[i]);
-                      
-                      result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
-                  });
-            return (List<T>)result;
+            IList<Dictionary<string, List<T>>> listInfo = new List<Dictionary<string, List<T>>>();
+            foreach (IGrouping<string, T> group in entitys.GroupBy(c => c.PartitionKey))
+            {
+                Dictionary<string, List<T>> dictInfo = new Dictionary<string, List<T>>
+                {
+                    { group.Key, group.ToList() }
+                };
+                listInfo.Add(dictInfo);
+            }
+
+            foreach (Dictionary<string, List<T>> dict in listInfo)
+            {
+                IList<TableResult> result = null;
+                foreach (string key in dict.Keys)
+                {
+                    List<T> values = dict[key];
+                    //Parallel.ForEach(Partitioner.Create(0, values.Count, 100),
+                    //  async range =>
+                    //  {
+                    //      TableBatchOperation batchOperation = new TableBatchOperation();
+                    //      for (Int32 i = range.Item1; i < range.Item2; i++)
+                    //          batchOperation.Delete(values[i]);
+                    //      result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    //  });
+
+                    int pageSize = 100;
+                    int pages = (int)Math.Ceiling((double)values.Count / pageSize);
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<T> lists = values.Skip((i) * pageSize).Take(pageSize).ToList();
+                        TableBatchOperation batchOperation = new TableBatchOperation();
+                        for (int j = 0; j < lists.Count; j++)
+                        {
+                            batchOperation.Delete(lists[j]);
+                        }
+                        result = await tableClient.GetTableReference(TableName).ExecuteBatchAsync(batchOperation);
+                    }
+                }
+            }
+            return entitys;
         }
 
         public async Task<T> Save<T>(TableEntity entity) where T : TableEntity, new()
         {
-            string TableName= await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             TableOperation operation = TableOperation.Insert(entity);
             TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
             return (T)result.Result;
         }
         public async Task<T> SaveOrUpdate<T>(TableEntity entity) where T : TableEntity, new()
         {
-            string TableName =  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             TableOperation operation = TableOperation.InsertOrReplace(entity);
             TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
             return (T)result.Result;
@@ -383,8 +571,7 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
 
         public async Task<T> Delete<T>(TableEntity entity) where T : TableEntity, new()
         {
-
-            string TableName =  await InitializeTable<T>();
+            string TableName = await InitializeTable<T>();
             TableOperation operation = TableOperation.Delete(entity);
             TableResult result = await tableClient.GetTableReference(TableName).ExecuteAsync(operation);
             return (T)result.Result;
@@ -405,8 +592,9 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
         //{
         //    throw new NotImplementedException();
         //}
-        
-        public async Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzureTableToken azureTableToken) where T : TableEntity, new() {
+
+        public async Task<AzurePagination<T>> FindListByDict<T>(Dictionary<string, object> dict, AzureTableToken azureTableToken) where T : TableEntity, new()
+        {
             string TableName = await InitializeTable<T>();
             var exQuery = new TableQuery<T>();
             StringBuilder builder = new StringBuilder();
@@ -418,30 +606,35 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
                 {
                     if (dict[key] != null && !string.IsNullOrEmpty(dict[key].ToString()))
                     {
+                        string typeStr = SwitchType(dict, key);
                         if (index == 1)
                         {
-                            builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            // builder.Append(TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append(typeStr);
+
                         }
                         else
                         {
-                            builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
+                            builder.Append("  " + TableOperators.And + "  " + typeStr);
+                            //builder.Append("  " + TableOperators.And + "  " + TableQuery.GenerateFilterCondition(key, QueryComparisons.Equal, dict[key].ToString()));
                         }
                         index++;
                     }
                 }
                 exQuery.Where(builder.ToString());
-                return await QueryList<T>(azureTableToken, exQuery , TableName);
+                return await QueryList<T>(azureTableToken, exQuery, TableName);
             }
-            else {
-                return null; 
+            else
+            {
+                return null;
             }
-            
+
         }
-        private async Task<AzurePagination<T>> QueryList<T>(AzureTableToken azureTableToken, TableQuery<T> exQuery,string TableName) where T : TableEntity, new()
+        private async Task<AzurePagination<T>> QueryList<T>(AzureTableToken azureTableToken, TableQuery<T> exQuery, string TableName) where T : TableEntity, new()
         {
             TableContinuationToken tableToken = new HaBookTableContinuationToken(azureTableToken).GetContinuationToken();
             List<T> entitys = new List<T>();
-            
+
             var result = await tableClient.GetTableReference(TableName).ExecuteQuerySegmentedAsync(exQuery, tableToken);
             if (result.Results.Count > 0)
             {
@@ -455,6 +648,5 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Implements
             };
             return pagination;
         }
-
     }
 }

+ 3 - 3
TEAMModelOS.SDK/Module/AzureTable/Interfaces/IAzureTableDBRepository.cs

@@ -10,13 +10,13 @@ namespace TEAMModelOS.SDK.Module.AzureTable.Interfaces
     {
         Task<List<T>> GetEntities<T>(IDictionary<string, object> dict) where T : TableEntity, new();
         Task<T> FindOneByDict<T>(IDictionary<string, object> dict) where T : TableEntity, new();
-        Task<T> FindById<T>(string id) where T : TableEntity, new();
+        Task<T> FindByRowKey<T>(string RowKey) where T : TableEntity, new();
         Task<T> Save<T>(TableEntity entity) where T : TableEntity, new();
         Task<T> Update<T>(TableEntity entity) where T : TableEntity, new();
         Task<T> Delete<T>(TableEntity entity) where T : TableEntity, new();
-        Task<T> FindOneByKey<T>(string key, string value) where T : TableEntity, new();
+        Task<T> FindOneByKey<T>(string key, object value) where T : TableEntity, new();
         Task<List<T>> FindListByDict<T>(Dictionary<string, object> dict) where T : TableEntity, new();
-        Task<List<T>> FindListByKey<T>(string key, string value) where T : TableEntity, new();
+        Task<List<T>> FindListByKey<T>(string key, object value) where T : TableEntity, new();
         Task<List<T>> FindAll<T>() where T : TableEntity, new();
         Task<List<T>> DeleteAll<T>(List<T> entitys) where T : TableEntity, new();
         Task<List<T>> UpdateAll<T>(List<T> entitys) where T : TableEntity, new();

+ 189 - 0
TEAMModelOS.Service/Core/Implements/LoginInfoService.cs

@@ -0,0 +1,189 @@
+using IdentityModel;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Options;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Claims;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Core.Dtos;
+using TEAMModelOS.Model.Core.Models;
+using TEAMModelOS.SDK.Context.Configuration;
+using TEAMModelOS.SDK.Context.Constant.Common;
+using TEAMModelOS.SDK.Context.Exception;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
+using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
+using TEAMModelOS.SDK.Extension.HttpClient.Implements;
+using TEAMModelOS.SDK.Extension.JwtAuth.JwtHelper;
+using TEAMModelOS.SDK.Extension.JwtAuth.Models;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
+using TEAMModelOS.SDK.Helper.Common.DateTimeHelper;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.SDK.Helper.Network.HttpHelper;
+using TEAMModelOS.SDK.Helper.Security.BCryptHelper;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using TEAMModelOS.Service.Core.Interfaces;
+
+namespace TEAMModelOS.Service.Core.Implements
+{
+    public class LoginInfoService : ILoginInfoService
+    {
+        private IAzureTableDBRepository _repository;
+        private IOptions<JwtSetting> _options;
+        private IHttpContextAccessor _httpContextAccessor;
+        private HttpClientUserInfo _httpClientService;
+        public LoginInfoService(IAzureTableDBRepository repository, IOptions<JwtSetting> options, IHttpContextAccessor httpContextAccessor  , HttpClientUserInfo httpClientService)
+        {
+            _httpContextAccessor = httpContextAccessor;
+            _options = options;
+            _repository = repository;
+            _httpClientService = httpClientService;
+        }
+
+        public async Task<LoginResult> CheckLoginAsync(TicketInfo ticketInfo) {
+
+            string jtoken = HttpContextHelper.GetValueInHttp(_httpContextAccessor.HttpContext.Request, Constants.AUTHORIZATION);
+            if (string.IsNullOrEmpty(ticketInfo.Token))
+            {
+                LoginResult result = new LoginResult();
+                if (string.IsNullOrEmpty(ticketInfo.Ticket))
+                {
+                    result.CheckTicket = false;
+                    return result;
+                }
+                string code = BCryptHelper.Ecrypt(ticketInfo.Ticket + ticketInfo.TeamModelId);
+                bool f = BCryptHelper.Verify(ticketInfo.Ticket + ticketInfo.TeamModelId, ticketInfo.Sign);
+                LoginInfo login = _repository.FindOneByKey<LoginInfo>("Ticket", ticketInfo.Ticket).Result;
+                if (login != null && !string.IsNullOrEmpty(login.Token))
+                {
+                    result.CheckTicket = true;
+                    JwtResponse token = await CreateJwtToken(login);
+                    result.JwtToken = token;
+                    login.Token = token.Access_token;
+                    result.JwtToken.Scope = login.Scope;
+                    await _repository.Update<LoginInfo>(login);
+                    return result;
+                }
+                JosnRPCRequest<Dictionary<string, object>> request = new JosnRPCRequest<Dictionary<string, object>>
+                {
+                    method = "UserInfo"
+                };
+               
+                    Dictionary<string, object> ticket = new Dictionary<string, object>
+                {
+                    { "ticket", ticketInfo.Ticket }
+                };
+                request.@params = ticket;
+                string data = MessagePackHelper.ObjectToJson(request);
+                string jsonStr = _httpClientService.HttpPost(BaseConfigModel.Configuration["HaBookAuth:AccountUrl"], data,  Constants.CONTENT_TYPE_JSON, Encoding.UTF8);
+                if (!string.IsNullOrEmpty(jsonStr))
+                {
+                    JosnRPCResponse<TeamModelIdInfo> response = MessagePackHelper.JsonToObject<JosnRPCResponse<TeamModelIdInfo>>(jsonStr);
+                    if (response.error == null && response != null)
+                    {
+                        result.CheckTicket = true;
+                        LoginInfo loginInfo = new LoginInfo
+                        {
+                            PartitionKey = response.result.cellphone,
+                            Phone = response.result.cellphone,
+                            RowKey = Guid.NewGuid().ToString(),
+                            TeamModelId = response.result.id,
+                            Name = response.result.name,
+                            Ticket = ticketInfo.Ticket,
+                            CountryCode = response.result.countryCode
+                        };
+                        TeamModelUser user= await _repository.FindOneByKey<TeamModelUser>("TeamModelId", response.result.id);
+                        if (user == null || string.IsNullOrEmpty(user.RowKey))
+                        {
+                            user = new TeamModelUser { RowKey = Guid.NewGuid().ToString(), PartitionKey = loginInfo.CountryCode ,RegisterTime=DateTimeHelper.ConvertToTimeStamp13(DateTime.Now) };
+                        }
+                        user.Cellphone = response.result.cellphone;
+                        user.NickName = response.result.name;
+                        if (string.IsNullOrEmpty(user.FullName)) {
+                            user.FullName = response.result.name;
+                        }
+                        user.TeamModelId = response.result.id;
+                        user.CountryCode = response.result.countryCode;
+                        JwtResponse jwtToken = await CreateJwtToken(loginInfo);
+                        loginInfo.Token = jwtToken.Access_token;
+                        loginInfo.Scope = jwtToken.Scope;
+                        result.JwtToken = jwtToken;
+                        await _repository.Save<LoginInfo>(loginInfo);
+                        await _repository.SaveOrUpdate<TeamModelUser>(user);
+                        return result;
+                    }
+                    else
+                    {
+                        result.CheckTicket = false;
+                        return result;
+                    }
+                }
+                else
+                {
+                    result.CheckTicket = false;
+                    return result;
+                }
+            }
+            else
+            {
+                ClaimModel claimModel = JwtHelper.SerializeJWT(ticketInfo.Token);
+
+                var dateTime = DateTimeHelper.ConvertToTimeStamp10(DateTime.Now);
+                var expExt=claimModel.Claim.TryGetValue("exp",out var exp);
+                if (expExt==false || dateTime > long.Parse(exp))
+                {
+                    throw new BizException(401, "Unauthorized");
+                }
+               
+                Dictionary<string, object> msp = new Dictionary<string, object>
+                {
+                    { "Token", ticketInfo.Token }
+                };
+                LoginInfo loginInfo = _repository.FindOneByDict<LoginInfo>(msp).Result;
+                if (loginInfo != null && !string.IsNullOrEmpty(loginInfo.Token))
+                {
+                    return new LoginResult { JwtToken = new JwtResponse { Access_token=loginInfo.Token ,Scope=loginInfo.Scope}, CheckTicket = true };
+                }
+                else
+                {
+                    throw new BizException(401, "Unauthorized");
+                }
+            }
+        }
+        public async Task<JwtResponse> CreateJwtToken(LoginInfo loginInfo)
+        {
+            Dictionary<string, object> dict = new Dictionary<string, object>
+            {
+                { "Phone", loginInfo.CountryCode + loginInfo.Phone },
+                { "TeamModelId",  loginInfo.TeamModelId }
+            };
+            string role = "";
+            List<RoleUser> roleUsers = await _repository.FindListByDict<RoleUser>(dict);
+            if (roleUsers.IsNotEmpty()) {
+                foreach (RoleUser roleUser in roleUsers)
+                {
+                    role = role + roleUser.RoleCode + ",";
+                }
+            }
+            role= role.Substring(0, role.Length - 1);
+            ClaimModel model = new ClaimModel
+            {
+                Scope = "WebApp"
+            };
+            model.Claims.Add(new Claim(JwtClaimTypes.Name, loginInfo.Name));
+            model.Claims.Add(new Claim(JwtClaimTypes.Id, loginInfo.TeamModelId));
+            ////保护隐私
+            //model.Claims.Add(new Claim(JwtClaimTypes.PhoneNumber, loginInfo.Phone));
+            model.Roles.Add(role);
+            JwtResponse jwtResponse = JwtHelper.IssueJWT(model, _options.Value);
+            return jwtResponse;
+        }
+
+        public Task<LoginInfo> SaveLoginInfoAsync(LoginInfo loginInfo)
+        {
+            return _repository.Save<LoginInfo>(loginInfo);
+        }
+    }
+}

+ 51 - 0
TEAMModelOS.Service/Core/Implements/RoleService.cs

@@ -0,0 +1,51 @@
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Core.Models;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using TEAMModelOS.Service.Core.Interfaces;
+
+namespace TEAMModelOS.Service.Core.Implements
+{
+    public class RoleService : IRoleService
+    {
+        private IAzureTableDBRepository _repository;
+        private IHttpContextAccessor _httpContextAccessor;
+        public RoleService(IAzureTableDBRepository repository, IHttpContextAccessor httpContextAccessor)
+        {
+            _httpContextAccessor = httpContextAccessor;
+            _repository = repository;
+        }
+
+        public async Task<List<Role>> FindRolesByDict(Dictionary<string, object> dict)
+        {
+            if (dict.Count <= 0)
+            {
+                return await _repository.FindAll<Role>();
+            }
+            else
+            {
+                return await _repository.FindListByDict<Role>(dict);
+            }
+        }
+        public async Task<Role> FindRoleByDict(Dictionary<string, object> dict) {
+            return await _repository.FindOneByDict<Role>(dict);
+        }
+        public async Task<List<RoleSchool>> FindRolesSchoolByDict(Dictionary<string, object> dict)
+        {
+            if (dict.Count <= 0)
+            {
+                return await _repository.FindAll<RoleSchool>();
+            }
+            else
+            {
+                return await _repository.FindListByDict<RoleSchool>(dict);
+            }
+        }
+        public async Task<Role> FindRoleByRowKey(string rowKey) {
+            return await _repository.FindByRowKey<Role>(rowKey);
+        }
+    }
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 85 - 0
TEAMModelOS.Service/Core/Implements/SchoolService.cs


+ 1 - 1
TEAMModelOS.Service/Common/Interfaces/IBusinessService.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Text;
 
-namespace TEAMModelOS.Service.Common.Interfaces
+namespace TEAMModelOS.Service.Core.Interfaces
 {
     public interface IBusinessService
     {

+ 13 - 0
TEAMModelOS.Service/Core/Interfaces/ILoginInfoService.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Core.Dtos;
+
+namespace TEAMModelOS.Service.Core.Interfaces
+{
+    public interface ILoginInfoService :IBusinessService
+    {
+        Task<LoginResult> CheckLoginAsync(TicketInfo loginInfo);
+    }
+}

+ 16 - 0
TEAMModelOS.Service/Core/Interfaces/IRoleService.cs

@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Core.Models;
+
+namespace TEAMModelOS.Service.Core.Interfaces
+{
+    public interface IRoleService :IBusinessService
+    {
+        Task<List<Role>> FindRolesByDict(Dictionary<string ,object> dict);
+        Task<Role> FindRoleByDict(Dictionary<string, object> dict);
+        Task<List<RoleSchool>> FindRolesSchoolByDict(Dictionary<string, object> dict);
+        Task<Role> FindRoleByRowKey(string rowKey);
+    }
+}

+ 20 - 0
TEAMModelOS.Service/Core/Interfaces/ISchoolService.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Model.Core.Dtos;
+using TEAMModelOS.Model.Core.Models;
+
+namespace TEAMModelOS.Service.Core.Interfaces
+{
+   public interface ISchoolService :IBusinessService
+    {
+        /// <summary>
+        /// 查看各个地区城市学校信息
+        /// </summary>
+        /// <param name="getSchool"></param>
+        /// <returns></returns>
+        Task<List<School>> GetSchool(SchoolCode schoolCode);
+        Task<RoleUser> AuthorizedAISchoolAsync(Dictionary<string, object> @params);
+    }
+}

+ 105 - 10
TEAMModelOS.Service/Syllabus/Implements/SyllabusService.cs

@@ -1,9 +1,12 @@
-using System;
+using Microsoft.AspNetCore.Http;
+using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
 using TEAMModelOS.Model.Syllabus.Dtos;
 using TEAMModelOS.Model.Syllabus.Models;
+using TEAMModelOS.SDK.Context.Exception;
+using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
 using TEAMModelOS.SDK.Helper.Common.JsonHelper;
 using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
 using TEAMModelOS.Service.Syllabus.Interfaces;
@@ -13,9 +16,11 @@ namespace TEAMModelOS.Service.Syllabus.Implements
     public class SyllabusService : ISyllabusService
     {
 
-        IAzureTableDBRepository _azureTableDBRepository;
-        public SyllabusService(IAzureTableDBRepository azureTableDBRepository) {
+        private IAzureTableDBRepository _azureTableDBRepository;
+        private IHttpContextAccessor _httpContextAccessor;
+        public SyllabusService(IAzureTableDBRepository azureTableDBRepository , IHttpContextAccessor httpContextAccessor) {
             _azureTableDBRepository = azureTableDBRepository;
+            _httpContextAccessor = httpContextAccessor;
         }
 
 
@@ -24,12 +29,7 @@ namespace TEAMModelOS.Service.Syllabus.Implements
             List<SyllabusTree> nodes = new List<SyllabusTree>();
             TreeToList(trees, nodes);
             List<SyllabusNode> nods = MessagePackHelper.JsonToObject<List<SyllabusNode>>(MessagePackHelper.ObjectToJson(nodes));
-            string pk = Guid.NewGuid().ToString();
-            foreach (SyllabusNode node in nods) {
-                node.RowKey = node.Id;
-                node.PartitionKey = pk;
-            }
-             await _azureTableDBRepository.SaveOrUpdateAll<SyllabusNode>(nods);
+            await _azureTableDBRepository.SaveOrUpdateAll<SyllabusNode>(nods);
             List<SyllabusTree> treess = ListToTree(nods);
             return treess;
            // return Task.Factory.StartNew(() => { return treess; });
@@ -52,7 +52,7 @@ namespace TEAMModelOS.Service.Syllabus.Implements
         {
             List<SyllabusTree> list = MessagePackHelper.JsonToObject<List<SyllabusTree>>(MessagePackHelper.ObjectToJson(noes));
  
-            var lookup = list.ToDictionary(n => n.Id, n => n);
+            var lookup = list.ToDictionary(n => n.RowKey, n => n);
             return GetChild(list, lookup);
         }
 
@@ -76,5 +76,100 @@ namespace TEAMModelOS.Service.Syllabus.Implements
 
             return await _azureTableDBRepository.SaveOrUpdate<SyllabusNode>(node);
         }
+
+        /// <summary>
+        /// 获取教学段
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        public async Task<List<Period>> FindPeriodsByDict(Dictionary<string, object> dict){
+            if (dict.Count <= 0)
+            {
+                return await _azureTableDBRepository.FindAll<Period>();
+            }
+            else {
+                return await _azureTableDBRepository.FindListByDict<Period>(dict);
+            }
+            
+        }
+        /// <summary>
+        /// 获取科目
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        public async Task<List<PeriodSubject>> FindSubjectsByDict(Dictionary<string, object> dict)
+        {
+            return await _azureTableDBRepository.FindListByDict<PeriodSubject>(dict);
+        }
+        /// <summary>
+        /// 获取教材版本
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        public async Task<List<PeriodSubjectEdition>> FindEditionsByDict(Dictionary<string, object> dict)
+        {
+            return await _azureTableDBRepository.FindListByDict<PeriodSubjectEdition>(dict);
+        }
+
+        /// <summary>
+        /// 获取册别
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        public async Task<List<PeriodSubjectEditionTerm>> FindTermsByDict(Dictionary<string, object> dict)
+        {
+            return await _azureTableDBRepository.FindListByDict<PeriodSubjectEditionTerm>(dict);
+        }
+        /// <summary>
+        /// 获取标准教材
+        /// </summary>
+        /// <param name="params"></param>
+        /// <returns></returns>
+        public async Task<StandardTextbook> FindTextbooksByDict(Dictionary<string, object> dict) {
+
+            
+
+            Dictionary<string, object> parDict = new Dictionary<string, object>
+            {
+                { "Period", dict["Period"] },
+                { "Subject", dict["Subject"] },
+                { "Edition", dict["Edition"] },
+                { "Term", dict["Term"] }
+            };
+            List<StandardTextbook> standardTextbooks= await _azureTableDBRepository.FindListByDict<StandardTextbook>(parDict);
+            if (standardTextbooks != null && standardTextbooks.Count > 0)
+            {
+                int index = 0;
+                foreach (StandardTextbook textbook in standardTextbooks)
+                {
+                    if (index > 0)
+                    {
+                        await _azureTableDBRepository.Delete<StandardTextbook>(textbook);
+                    }
+                    index++;
+                }
+                return standardTextbooks[0];
+            }
+            else
+            {
+                // 校验 几个Code 是否存在
+                string RowKey = "RowKey";
+                StandardTextbook textbook = dict.DictToObj<StandardTextbook>();
+                List<Period> periods= await FindPeriodsByDict(new Dictionary<string, object> { { RowKey, textbook.Period} });
+                List<PeriodSubject> subjects = await FindSubjectsByDict(new Dictionary<string, object> { { RowKey, textbook.Subject } });
+                List<PeriodSubjectEdition> editions = await FindEditionsByDict(new Dictionary<string, object> { { RowKey, textbook.Edition } });
+                List<PeriodSubjectEditionTerm> terms = await FindTermsByDict(new Dictionary<string, object> { { RowKey, textbook.Term } });
+                if (periods.IsNotEmpty()&& subjects.IsNotEmpty()&& editions.IsNotEmpty()&& terms.IsNotEmpty())
+                {
+                    textbook.RowKey = Guid.NewGuid().ToString();
+                    textbook.PartitionKey = Guid.NewGuid().ToString();
+                    textbook = await _azureTableDBRepository.Save<StandardTextbook>(textbook);
+                    return textbook;
+                }
+                else {
+                    throw new BizException("Codes is required: Period,Subject,Edition,Term");
+                }
+            }
+        }
     }
 }

+ 42 - 4
TEAMModelOS.Service/Syllabus/Interfaces/ISyllabusService.cs

@@ -1,16 +1,54 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Collections.Generic;
 using System.Threading.Tasks;
 using TEAMModelOS.Model.Syllabus.Dtos;
 using TEAMModelOS.Model.Syllabus.Models;
-using TEAMModelOS.Service.Common.Interfaces;
+using TEAMModelOS.Service.Core.Interfaces;
 
 namespace TEAMModelOS.Service.Syllabus.Interfaces
 {
     public interface ISyllabusService : IBusinessService
     {
+        /// <summary>
+        /// 批量保存课纲结构树形
+        /// </summary>
+        /// <param name="trees"></param>
+        /// <returns></returns>
         Task<List<SyllabusTree>> SaveOrUpdateAll(List<SyllabusTree> trees);
+        /// <summary>
+        /// 保存单个课纲节点
+        /// </summary>
+        /// <param name="node"></param>
+        /// <returns></returns>
         Task<SyllabusNode> SaveOrUpdate(SyllabusNode node);
+        /// <summary>
+        /// 获取教学段
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        Task<List<Period>> FindPeriodsByDict(Dictionary<string ,object> dict);
+        /// <summary>
+        /// 获取科目
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        Task<List<PeriodSubject>> FindSubjectsByDict(Dictionary<string, object> dict);
+        /// <summary>
+        /// 获取教材版本
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        Task<List<PeriodSubjectEdition>> FindEditionsByDict(Dictionary<string, object> dict);
+        /// <summary>
+        /// 获取册别
+        /// </summary>
+        /// <param name="dict"></param>
+        /// <returns></returns>
+        Task<List<PeriodSubjectEditionTerm>> FindTermsByDict(Dictionary<string, object> dict);
+        /// <summary>
+        /// 获取标准教材
+        /// </summary>
+        /// <param name="params"></param>
+        /// <returns></returns>
+        Task<StandardTextbook> FindTextbooksByDict(Dictionary<string, object> dict);
     }
 }

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

@@ -7,7 +7,6 @@
   <ItemGroup>
     <Folder Include="Analysis\Implements\" />
     <Folder Include="Analysis\Interfaces\" />
-    <Folder Include="Common\Implements\" />
   </ItemGroup>
 
   <ItemGroup>

+ 30 - 4
TEAMModelOS/ClientApp/app.js

@@ -7,22 +7,48 @@ import App from 'components/app-root'
 import { FontAwesomeIcon } from './icons'
 import iView from 'iview';
 import 'iview/dist/styles/iview.css';
-import i18n from '@/locale'
+import i18n from '@/locale';
+import commons from "@/utils/public.js";
+import apiTools from '@/store/api.js';
+import { fetch, post } from '@/utils/http';
+import VideoPlayer from 'vue-video-player';
+import jwtDecode from 'jwt-decode';
+
+
+require('video.js/dist/video-js.css');
+require('vue-video-player/src/custom-theme.css');
+Vue.use(VideoPlayer);
 
 //新添加的
 import vuescroll from 'vue-scroll'
 import echarts from 'echarts'
-import { post, fetch } from './utils/http'
-
 
+//全局API请求
+Vue.prototype.$api = apiTools;
 Vue.prototype.$post = post;
 Vue.prototype.$get = fetch;
+
+
+Vue.prototype.$jwtDecode = jwtDecode;
+
 Vue.use(vuescroll)
 Vue.prototype.$echarts = echarts
 
+//ZXJ
+Vue.prototype.common = commons;
+
 // Registration of global components
-Vue.component('icon', FontAwesomeIcon)
+Vue.component('icon', FontAwesomeIcon);
 
+//使用钩子函数对路由进行权限跳转
+//router.beforeEach((to, from, next) => {
+//  const role = localStorage.getItem('token');
+//  if (!role && to.path !== '/') {
+//    next('/');
+//  } else {
+//    next();
+//  }
+//})
 //Vue.prototype.$http = axios
 
 Vue.use(iView, {

BIN
TEAMModelOS/ClientApp/assets/banner.jpg


BIN
TEAMModelOS/ClientApp/assets/icon/header_book.png


BIN
TEAMModelOS/ClientApp/assets/icon/header_detection.png


BIN
TEAMModelOS/ClientApp/assets/icon/header_interact.png


BIN
TEAMModelOS/ClientApp/assets/icon/header_preview.png


BIN
TEAMModelOS/ClientApp/assets/icon/header_synchronization.png


BIN
TEAMModelOS/ClientApp/assets/icon/header_task.png


BIN
TEAMModelOS/ClientApp/assets/icon/html50.png


BIN
TEAMModelOS/ClientApp/assets/icon/icon_audio.png


BIN
TEAMModelOS/ClientApp/assets/icon/icon_img.png


BIN
TEAMModelOS/ClientApp/assets/icon/icon_text.png


BIN
TEAMModelOS/ClientApp/assets/icon/icon_video.png


BIN
TEAMModelOS/ClientApp/assets/icon/pdf50.png


BIN
TEAMModelOS/ClientApp/assets/icon/pic50.png


BIN
TEAMModelOS/ClientApp/assets/icon/ppt50.png


BIN
TEAMModelOS/ClientApp/assets/icon/prelearn50.png


BIN
TEAMModelOS/ClientApp/assets/icon/swf50.png


BIN
TEAMModelOS/ClientApp/assets/icon/txt50.png


BIN
TEAMModelOS/ClientApp/assets/icon/video50.png


BIN
TEAMModelOS/ClientApp/assets/icon/word50.png


BIN
TEAMModelOS/ClientApp/assets/icon/xls50.png


BIN
TEAMModelOS/ClientApp/assets/icon/zip50.png


BIN
TEAMModelOS/ClientApp/assets/image/header_icon.png


BIN
TEAMModelOS/ClientApp/assets/image/header_icon1.png


BIN
TEAMModelOS/ClientApp/assets/logo.png


BIN
TEAMModelOS/ClientApp/assets/tmd_logo.png


+ 0 - 0
TEAMModelOS/ClientApp/boot-app.js


Vissa filer visades inte eftersom för många filer har ändrats