CrazyIter_Bin 3 年之前
父節點
當前提交
c63fcf1701
共有 26 個文件被更改,包括 425 次插入248 次删除
  1. 2 0
      TEAMModelAPI/Controllers/School/TeacherController.cs
  2. 1 1
      TEAMModelBI/Controllers/BISchool/SchoolController.cs
  3. 18 1
      TEAMModelOS.SDK/Extension/HttpContextExtensions.cs
  4. 3 2
      TEAMModelOS.SDK/Extension/JwtAuthExtension.cs
  5. 5 0
      TEAMModelOS.SDK/Models/Cosmos/School/School.cs
  6. 4 0
      TEAMModelOS.SDK/Models/Cosmos/Student/Student.cs
  7. 4 0
      TEAMModelOS.SDK/Models/Cosmos/Student/TmdUser.cs
  8. 5 2
      TEAMModelOS.SDK/Models/Cosmos/Teacher/Teacher.cs
  9. 9 10
      TEAMModelOS.SDK/Models/Service/Common/TeacherService.cs
  10. 70 0
      TEAMModelOS.SDK/Models/Service/LoginService.cs
  11. 7 1
      TEAMModelOS.SDK/Models/Service/StudentService.cs
  12. 29 0
      TEAMModelOS.SDK/Models/Service/Third/Xkw/XkwOAuthModel.cs
  13. 1 0
      TEAMModelOS.SDK/Models/Service/TmdUserService.cs
  14. 1 0
      TEAMModelOS/Controllers/Both/GroupListController.cs
  15. 3 2
      TEAMModelOS/Controllers/Client/HiTAControlller.cs
  16. 1 0
      TEAMModelOS/Controllers/Client/HiTeachController.cs
  17. 7 2
      TEAMModelOS/Controllers/Common/StudyController.cs
  18. 4 1
      TEAMModelOS/Controllers/School/SchoolController.cs
  19. 191 175
      TEAMModelOS/Controllers/School/SchoolTeacherController.cs
  20. 8 6
      TEAMModelOS/Controllers/Student/StudentController.cs
  21. 2 1
      TEAMModelOS/Controllers/Student/TmdUserController.cs
  22. 8 39
      TEAMModelOS/Controllers/Teacher/InitController.cs
  23. 36 3
      TEAMModelOS/Controllers/Third/OAuth2Controller.cs
  24. 1 0
      TEAMModelOS/Controllers/Third/Sc/ScController.cs
  25. 2 1
      TEAMModelOS/Controllers/XTest/TestController.cs
  26. 3 1
      TEAMModelOS/Filter/AuthTokenAttribute.cs

+ 2 - 0
TEAMModelAPI/Controllers/School/TeacherController.cs

@@ -135,6 +135,7 @@ namespace TEAMModelAPI.Controllers
             if (responseTch.Status == 200)
             {
                 teacher = JsonDocument.Parse(responseTch.Content).RootElement.Deserialize<Teacher>();
+                
             }
             else
             {
@@ -231,6 +232,7 @@ namespace TEAMModelAPI.Controllers
                 
                     teacher = new Teacher
                     {
+                        createTime= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = coreUser.id,
                         name = coreUser.name,
                         picture = coreUser.picture,

+ 1 - 1
TEAMModelBI/Controllers/BISchool/SchoolController.cs

@@ -662,7 +662,7 @@ namespace TEAMModelBI.Controllers.BISchool
                         name = $"{_adminTmdName}",
                         picture = "",
                         status = "join",
-                        createTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         pk = "Teacher",
                         ttl = -1
                     };

+ 18 - 1
TEAMModelOS.SDK/Extension/HttpContextExtensions.cs

@@ -86,7 +86,24 @@ namespace TEAMModelOS.SDK.Extension
 
             return (id?.ToString(), name?.ToString(), picture?.ToString(), school?.ToString());
         }
-
+        /// <summary>
+        /// 取得AuthToken權杖資訊
+        /// </summary>        
+        /// <param name="key">Key Name</param>
+        /// <returns></returns>
+        public static (string id, string name, string picture, string school,string area ,string keyData) GetAuthTokenKey(this HttpContext httpContext, string key = null)
+        {
+            object id = null, name = null, picture = null, school = null,area= null, keyData = null;
+            httpContext?.Items.TryGetValue("ID", out id);
+            httpContext?.Items.TryGetValue("Name", out name);
+            httpContext?.Items.TryGetValue("Picture", out picture);
+            httpContext?.Items.TryGetValue("School", out school);
+            httpContext?.Items.TryGetValue("Area", out area);
+            if (!string.IsNullOrWhiteSpace(key)) {
+                httpContext?.Items.TryGetValue(key, out keyData);
+            }
+            return (id?.ToString(), name?.ToString(), picture?.ToString(), school?.ToString(), area?.ToString(), keyData?.ToString());
+        }
         /// <summary>
         /// 取得User-Agent值
         /// </summary>       

+ 3 - 2
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -14,7 +14,7 @@ namespace TEAMModelOS.SDK.Extension
 {
     public static class JwtAuthExtension
     {
-        public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope,string Website, string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1)
+        public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope,string Website,string areaId="", string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1)
         {
             // 設定要加入到 JWT Token 中的聲明資訊(Claims)  
             var payload = new JwtPayload {
@@ -28,7 +28,8 @@ namespace TEAMModelOS.SDK.Extension
                 { "permissions",permissions}, //登入者的權限請求
                 { "standard",standard} ,//登入者的能力点标准
                 { "scope",scope},  //登入者的入口类型。 (teacher 教师端登录的醍摩豆ID、tmduser学生端登录的醍摩豆ID、student学生端登录校内账号的学生ID)
-                { JwtRegisteredClaimNames.Website,Website}, // 學校簡碼,如果有的話
+                { "area",areaId==null?"":areaId},
+                { JwtRegisteredClaimNames.Website,Website},  
             };
 
             // 建立一組對稱式加密的金鑰,主要用於 JWT 簽章之用

+ 5 - 0
TEAMModelOS.SDK/Models/Cosmos/School/School.cs

@@ -80,6 +80,11 @@ namespace TEAMModelOS.SDK.Models
         /// 规模数量
         /// </summary>
         public int scale { get; set; }
+
+        /// <summary>
+        /// 创建时间  十位 时间戳
+        /// </summary>
+        public long createTime { get; set; }
     }
     /// <summary>
     /// 课表计划

+ 4 - 0
TEAMModelOS.SDK/Models/Cosmos/Student/Student.cs

@@ -37,6 +37,10 @@ namespace TEAMModelOS.SDK.Models
         /// 保留当天的登录信息
         /// </summary>
         public List<LoginInfo> loginInfos { get; set; } = new List<LoginInfo>();
+        /// <summary>
+        /// 创建时间  十位 时间戳
+        /// </summary>
+        public long createTime { get; set; }
         //public List<StudentParent> parents { get; set; }= new List<StudentParent>();
     }
     public class StudentParent {

+ 4 - 0
TEAMModelOS.SDK/Models/Cosmos/Student/TmdUser.cs

@@ -16,6 +16,10 @@ namespace TEAMModelOS.SDK
         /// 保留当天的登录信息
         /// </summary>
         public List<LoginInfo> loginInfos { get; set; } = new List<LoginInfo>();
+        /// <summary>
+        /// 创建时间 十位 时间戳
+        /// </summary>
+        public long createTime { get; set; }
         public class School
         {
             public string schoolId { get; set; }

+ 5 - 2
TEAMModelOS.SDK/Models/Cosmos/Teacher/Teacher.cs

@@ -16,7 +16,10 @@ namespace TEAMModelOS.SDK.Models
         public List<ThirdBind> binds { get; set; } = new List<ThirdBind>();
         public int lessonLimit { get; set; } = 0;
         public List<string> lessonShow { get; set; } = new List<string>();
-
+        /// <summary>
+        /// 创建时间  十位 时间戳
+        /// </summary>
+        public long  createTime { get; set; } 
         /// <summary>
         /// 保留当天的登录信息
         /// </summary>
@@ -34,7 +37,7 @@ namespace TEAMModelOS.SDK.Models
             /// <summary>
             /// token到期时间
             /// </summary>
-            public long exp { get; set;}
+            public long expire { get; set;}
         }
         public class TeacherSchool
         {

+ 9 - 10
TEAMModelOS.SDK/Models/Service/Common/TeacherService.cs

@@ -210,15 +210,11 @@ namespace TEAMModelOS.Services
                                 teacher.defaultSchool = null;
                             }
                         }
-                        else {
-                           
-                        }
                     }
                     else {
                         teacher.defaultSchool = null;
                     }
-                }
-                await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, id, new PartitionKey("Base"));
+                } 
                 //預設學校ID
                 defaultschool = teacher.defaultSchool;
             }
@@ -229,6 +225,7 @@ namespace TEAMModelOS.Services
                     //如果沒有,則初始化Teacher基本資料到Cosmos
                     teacher = new Teacher
                     {
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = id,
                         pk = "Base",
                         code = "Base",
@@ -274,7 +271,9 @@ namespace TEAMModelOS.Services
                 }
             }
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray());
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray(),expire:1);
+
+            await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, id, new PartitionKey("Base"));
             //取得Teacher Blob 容器位置及SAS 
             await _azureStorage.GetBlobContainerClient(id).CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete);
@@ -467,8 +466,9 @@ namespace TEAMModelOS.Services
                 {
                     //如果沒有,則初始化Teacher基本資料到Cosmos
                       teacher = new Teacher
-                    {
-                        id = id,
+                      {
+                          createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                          id = id,
                         pk = "Base",
                         code = "Base",
                         name = name?.ToString(),
@@ -519,7 +519,7 @@ namespace TEAMModelOS.Services
                 }
             }
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray());
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray(),expire: 1);
             //取得Teacher Blob 容器位置及SAS 
             await _azureStorage.GetBlobContainerClient(id).CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(id, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List | BlobContainerSasPermissions.Delete);
@@ -564,6 +564,5 @@ namespace TEAMModelOS.Services
         public int tsize { get; set; }
         public List<AreaDto> areas { get; set; } = new List<AreaDto>();
         public Teacher teacher { get; set; }
-       
     }
 }

+ 70 - 0
TEAMModelOS.SDK/Models/Service/LoginService.cs

@@ -0,0 +1,70 @@
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using TEAMModelOS.Models;
+using TEAMModelOS.SDK.DI;
+using static TEAMModelOS.SDK.Models.Teacher;
+
+namespace TEAMModelOS.SDK.Models.Service
+{
+    public static class LoginService
+    {
+
+        public static List<LoginInfo> DoLoginInfo(List<LoginInfo> loginInfos,long  expire, long now ,string school,string scope, string id , string ip, string region) {
+            if (loginInfos.Any())
+            {
+                if (loginInfos.Count() >=5) {
+                    loginInfos= loginInfos.OrderBy(x => x.expire).ToList();
+                    loginInfos.RemoveRange(4, loginInfos.Count() - 4);
+                }
+                loginInfos.Add(new LoginInfo { expire = expire, ip = ip, time = now });
+            }
+            else {
+                loginInfos = new List<LoginInfo> { new LoginInfo { expire = expire,ip=ip,time= now } };
+            }
+            return loginInfos;
+        }
+
+        public static async Task<(string ip, string region)> LoginIp(HttpContext httpContext,IPSearcher _searcher)
+        {
+
+            var IpPort = httpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
+            if (string.IsNullOrEmpty(IpPort))
+            {
+                IpPort = httpContext.Connection.RemoteIpAddress.ToString();
+            }
+            if (IpPort.Contains("::"))
+            {
+                IpPort = "127.0.0.1";
+            }
+            string ip = IpPort.Split(":")[0];
+            string region = await _searcher.SearchIpAsync(ip);
+            return (ip, region);
+        }
+
+        public static   void LoginLog(HttpContext httpContext, Option _option, ILogger _logger, DingDing _dingDing,    string ip, string region, string id, string name, int status)
+        {
+            httpContext.Request.Headers.TryGetValue("referer", out var referer);
+            httpContext.Request.Headers.TryGetValue("sec-ch-ua", out var chua);
+            httpContext.Request.Headers.TryGetValue("sec-ch-ua-platform", out var platform);
+            httpContext.Request.Headers.TryGetValue("user-agent", out var useragent);
+            if (status == 200)
+            {
+                string msg = $"{_option.Location} -- {name}({id}):Login Succeed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " +
+                    $"--Browser Info( --referer:{referer}  --sec-ch-ua:{chua}  --sec-ch-ua-platform:{platform}  --user-agent:{useragent}  --ip:{ip} --region:{region} )";
+                _logger.LogInformation(msg);
+            }
+            else
+            {
+                string msg = $"{_option.Location} -- {name}({id}):Login Failed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " +
+                         $"--Browser Info( --referer:{referer}  --sec-ch-ua:{chua}  --sec-ch-ua-platform:{platform}  --user-agent:{useragent}  --ip:{ip} --region:{region} )";
+                _ = _dingDing.SendBotMsg($"IES5,{_option.Location},{msg}", GroupNames.醍摩豆服務運維群組);
+                _logger.LogError(msg);
+            }
+        }
+    }
+}

+ 7 - 1
TEAMModelOS.SDK/Models/Service/StudentService.cs

@@ -694,6 +694,7 @@ namespace TEAMModelOS.SDK
 
                 CosmosContainer cosmosContainer = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Student");
 
+                long now= DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                 //並行處理
                 foreach (var stud in sortedImpData.studs)
                 {
@@ -749,6 +750,7 @@ namespace TEAMModelOS.SDK
                     writerNew.WriteString("code", $"Base-{schoolId}");
                     writerNew.WriteString("schoolId", schoolId);
                     writerNew.WriteNumber("year", stud.Value.year);
+                    writerNew.WriteNumber("createTime", now);
                     writerNew.WriteString("salt", stud.Value.salt);
                     writerNew.WriteString("pw", stud.Value.pw);
                     if (string.IsNullOrWhiteSpace(stud.Value.name)) writerNew.WriteNull("name");
@@ -758,6 +760,7 @@ namespace TEAMModelOS.SDK
                     writerNew.WriteNull("mail");
                     writerNew.WriteNull("mobile");
                     writerNew.WriteNull("country");
+                
                     if (!string.IsNullOrWhiteSpace(stud.Value.periodId))
                     {
                         writerNew.WriteString("periodId", stud.Value.periodId);
@@ -898,11 +901,12 @@ namespace TEAMModelOS.SDK
                 if (string.IsNullOrWhiteSpace(studCreateInfo.periodId)) writer.WriteNull("periodId");
                 else writer.WriteString("periodId", studCreateInfo.periodId);
                 writer.WriteNumber("year", studCreateInfo.year);
+                writer.WriteNumber("createTime", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
                 writer.WriteNull("picture");
                 writer.WriteNull("mail");
                 writer.WriteNull("mobile");
                 writer.WriteNull("country");
-
+             
                 //Password,若沒給則使用學號當密碼
                 string salt = Utils.CreatSaltString(8);
                 string hashPw = string.IsNullOrWhiteSpace(studCreateInfo.pw)
@@ -928,6 +932,7 @@ namespace TEAMModelOS.SDK
 
                 writer.WriteEndObject();
                 writer.Flush();
+             
                 var response = await _azureCosmos
                                 .GetCosmosClient()
                                 .GetContainer(Constant.TEAMModelOS, "Student")
@@ -994,6 +999,7 @@ namespace TEAMModelOS.SDK
                 if (string.IsNullOrWhiteSpace(periodId)) writer.WriteNull("periodId");
                 else writer.WriteString("periodId", periodId);
                 writer.WriteNumber("year", classYear);
+                writer.WriteNumber("createTime", DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
                 writer.WriteNull("sn");
                 writer.WriteString("style", "smart");
                 writer.WriteString("openType", "1");

+ 29 - 0
TEAMModelOS.SDK/Models/Service/Third/Xkw/XkwOAuthModel.cs

@@ -60,6 +60,34 @@ namespace TEAMModelOS.SDK.Models
         public string Type { get; set; }
         public string Domain { get; set; }
     }
+    [TableName(Name = "IESOAuth")]
+    public class OAuthShow : TableEntity
+    {
+        //PartitionKey OAuthShow
+        //RowKey  {type}-tmdid,{type}-schoolId,{type}-areaId
+        /// <summary>
+        /// xkw axy
+        /// </summary>
+        public string Type { get; set; }
+        /// <summary>
+        /// 0  禁用,1允许使用
+        /// </summary>
+        public int Status { get; set; }
+        /// <summary>
+        /// 
+        ///个人开通 private,学校开通 school ,区级开通 area
+        /// </summary>
+        public string Scope { get; set; }
+        /// <summary>
+        /// tmdid  schoolId  areaId
+        /// </summary>
+        public string Code { get; set; }
+        /// <summary>
+        /// 域名
+        /// </summary>
+        public string Domain { get; set; }
+
+    }
     public class XkwBindModel
     {
         public int status { get; set; }
@@ -69,6 +97,7 @@ namespace TEAMModelOS.SDK.Models
         public string userId { get; set; }
         public string domain { get; set; }
     }
+    
     public record OAuthCode {
         public string code { get; set; }
         public string state { get; set; }

+ 1 - 0
TEAMModelOS.SDK/Models/Service/TmdUserService.cs

@@ -31,6 +31,7 @@ namespace TEAMModelOS.SDK
                 if (ex.Status == 404) {
                     tmdUser = new TmdUser()
                     {
+                        createTime=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = tmdid,
                         code = "Base",
                         schools = new List<TmdUser.School>() { 

+ 1 - 0
TEAMModelOS/Controllers/Both/GroupListController.cs

@@ -107,6 +107,7 @@ namespace TEAMModelOS.Controllers
                     //如果沒有,則初始化Teacher基本資料到Cosmos
                     TmdUser tmduser = new TmdUser
                     {
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = id,
                         pk = "Base",
                         code = "Base",

+ 3 - 2
TEAMModelOS/Controllers/Client/HiTAControlller.cs

@@ -129,8 +129,9 @@ namespace TEAMModelOS.Controllers.Client
                 {
                     //如果沒有,則初始化Teacher基本資料到Cosmos
                    teacher = new Teacher
-                    {
-                        id = id,
+                   {
+                       createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                       id = id,
                         pk = "Base",
                         code = "Base",
                         name = name?.ToString(),

+ 1 - 0
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -237,6 +237,7 @@ namespace TEAMModelOS.Controllers.Client
                     //如果沒有,則初始化Teacher基本資料到Cosmos
                     Teacher teacher = new Teacher
                     {
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = id,
                         pk = "Base",
                         code = "Base",

+ 7 - 2
TEAMModelOS/Controllers/Common/StudyController.cs

@@ -136,7 +136,7 @@ namespace TEAMModelOS.Controllers.Common
         [HttpPost("sign-in")]
         public async Task<IActionResult> Sign(JsonElement request)
         {
-            // await _dingDing.SendBotMsg($"OS,{_option.Location},study/sign-in()\n{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+          
             try
             {
                 if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
@@ -156,7 +156,12 @@ namespace TEAMModelOS.Controllers.Common
                 {
                     if (!string.IsNullOrWhiteSpace($"{tId}") && string.IsNullOrWhiteSpace(tmdid))
                     {
-                        tmdid = $"{tId}";
+                        var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{tId}" } }, _option.Location, _configuration);
+                        if (coreUser != null)
+                        {
+                            tmdid = coreUser.id;
+                        }
+                       
                     }
                 }
                 if (string.IsNullOrWhiteSpace(tmdid))

+ 4 - 1
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -1706,7 +1706,10 @@ namespace TEAMModelOS.Controllers
                                         await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReplaceItemAsync(teacherBase, teacherBase.id, new PartitionKey("Base"));
                                     }
                                     else {
-                                        Teacher teacherBase = new Teacher { id = t.id, name = t.name, picture = t.picture, size = 2,code="Base",pk="Base", schools = new List<TeacherSchool> {
+                                        Teacher teacherBase = new Teacher
+                                        {
+                                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                                            id = t.id, name = t.name, picture = t.picture, size = 2,code="Base",pk="Base", schools = new List<TeacherSchool> {
                                             new TeacherSchool {schoolId= schoolBase.id,name= schoolBase.name,picture= schoolBase.picture, areaId= schoolBase.areaId,time=now,status= "invite" },
                                         } };
                                         await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).CreateItemAsync(teacherBase, new PartitionKey("Base"));

+ 191 - 175
TEAMModelOS/Controllers/School/SchoolTeacherController.cs

@@ -40,9 +40,12 @@ namespace TEAMModelOS.Controllers
         private readonly NotificationService _notificationService;
         private readonly AzureServiceBusFactory _azureServiceBus;
         private readonly CoreAPIHttpService _coreAPIHttpService;
-        public SchoolTeacherController(CoreAPIHttpService coreAPIHttpService,AzureServiceBusFactory azureServiceBus,AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService)
+
+        private readonly DingDing _dingDing;
+        public SchoolTeacherController(DingDing dingDing,CoreAPIHttpService coreAPIHttpService,AzureServiceBusFactory azureServiceBus,AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService)
         {
-            _azureCosmos = azureCosmos;
+            _dingDing=dingDing; 
+               _azureCosmos = azureCosmos;
             _azureStorage = azureStorage;
             _option = option?.Value;
             _configuration = configuration;
@@ -67,109 +70,90 @@ namespace TEAMModelOS.Controllers
             //string status_str = (request.TryGetProperty("join_status", out JsonElement status_json)) ? status_json.ToString() : "join";
             //資料取得
             List<ScTeacher> teachers = new List<ScTeacher>();
-            await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ScTeacher>
-                (queryText: $"SELECT c.subjectIds, c.id, c.name,   c.picture ,c.status, c.job, c.createTime, ARRAY_LENGTH(c.permissions) as permissionCount,c.permissions,c.roles , c.size FROM c", 
+            try {
+                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ScTeacher>
+                (queryText: $"SELECT c.subjectIds, c.id, c.name,   c.picture ,c.status, c.job, c.createTime, ARRAY_LENGTH(c.permissions) as permissionCount,c.permissions,c.roles , c.size FROM c",
                 requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
-            {
-                if ($"{item.createTime}".Length > 10) {
-                    item.createTime = item.createTime / 1000;
-                }
-                teachers.Add(item);
-            }
-          
-            if (teachers.IsNotEmpty()) {
-                List<IdNameCode> groupLists = new List<IdNameCode>();
-                await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<IdNameCode>
-                    (queryText: $"SELECT c.id, c.name, m.id as code  FROM c join m in c.members  where  c.type='research' and m.id in ({string.Join(",",teachers.Select(x=>$"'{x.id}'"))}) ", 
-                    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school_code}") }))
-                {
-                    groupLists.Add(item);
-                }
-                if (groupLists.IsNotEmpty()) {
-                    teachers.ForEach(x => {
-                        List<IdNameCode> codes = groupLists.FindAll(g => g.code.Equals(x.id));
-                        if (codes.IsNotEmpty())
-                        {
-                            x.groups = codes;
-                        }
-                    });
-                }
-            }
-            Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync($"{school_code}", new PartitionKey("TeacherImport"));
-            IEnumerable<string> ids =null;
-            List<CoreUser> coreUsers = new List<CoreUser>();
-            if (response.Status == 200) {
-                TeacherImport teacherImport = JsonDocument.Parse(response.Content).RootElement.ToObject<TeacherImport>();
-                var idsIn = teacherImport.teachers.Where(x => !string.IsNullOrWhiteSpace(x.id));
-                //id是空 其他不是空的
-                var tmdidsi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.tmdid)).Select(z => z.tmdid);
-                var phonesi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.phone)).Select(z => z.phone);
-                var emailsi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.email)).Select(z => z.email);
-                List<string> skeys = new List<string>();
-                if (idsIn.Any()) {
-                    skeys.AddRange(idsIn.Select(x=>x.id));
-                }
-                if (tmdidsi.Any())
-                {
-                    skeys.AddRange(tmdidsi);
-                }
-                if (phonesi.Any())
                 {
-                    skeys.AddRange(phonesi);
-                }
-                if (emailsi.Any())
-                {
-                    skeys.AddRange(emailsi);
+                    if ($"{item.createTime}".Length > 10)
+                    {
+                        item.createTime = item.createTime / 1000;
+                    }
+                    teachers.Add(item);
                 }
-                if (skeys.Any())
+
+                if (teachers.IsNotEmpty())
                 {
-                    try
+                    List<IdNameCode> groupLists = new List<IdNameCode>();
+                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<IdNameCode>
+                        (queryText: $"SELECT c.id, c.name, m.id as code  FROM c join m in c.members  where  c.type='research' and m.id in ({string.Join(",", teachers.Select(x => $"'{x.id}'"))}) ",
+                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"GroupList-{school_code}") }))
                     {
-                        var content = new StringContent(skeys.ToJsonString(), Encoding.UTF8, "application/json");
-                        string json = await _coreAPIHttpService.GetUserInfos(content);
-                        if (!string.IsNullOrWhiteSpace(json))
-                        {
-                            coreUsers = json.ToObject<List<CoreUser>>();
-                            ids = coreUsers.Select(x => x.id);
-                        }
+                        groupLists.Add(item);
                     }
-                    catch (Exception ex)
+                    if (groupLists.IsNotEmpty())
                     {
-                        //await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n{skeys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                        teachers.ForEach(x => {
+                            List<IdNameCode> codes = groupLists.FindAll(g => g.code.Equals(x.id));
+                            if (codes.IsNotEmpty())
+                            {
+                                x.groups = codes;
+                            }
+                        });
                     }
                 }
-                if (coreUsers.Any())
+                Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync($"{school_code}", new PartitionKey("TeacherImport"));
+                IEnumerable<string> ids = null;
+                List<CoreUser> coreUsers = new List<CoreUser>();
+                if (response.Status == 200)
                 {
-                    teacherImport.teachers.ForEach(t =>
+                    TeacherImport teacherImport = JsonDocument.Parse(response.Content).RootElement.ToObject<TeacherImport>();
+                    var idsIn = teacherImport.teachers.Where(x => !string.IsNullOrWhiteSpace(x.id));
+                    //id是空 其他不是空的
+                    var tmdidsi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.tmdid)).Select(z => z.tmdid);
+                    var phonesi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.phone)).Select(z => z.phone);
+                    var emailsi = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id) && !string.IsNullOrWhiteSpace(x.email)).Select(z => z.email);
+                    List<string> skeys = new List<string>();
+                    if (idsIn.Any())
+                    {
+                        skeys.AddRange(idsIn.Select(x => x.id));
+                    }
+                    if (tmdidsi.Any())
+                    {
+                        skeys.AddRange(tmdidsi);
+                    }
+                    if (phonesi.Any())
+                    {
+                        skeys.AddRange(phonesi);
+                    }
+                    if (emailsi.Any())
                     {
-                        if (!string.IsNullOrWhiteSpace(t.id))
+                        skeys.AddRange(emailsi);
+                    }
+                    if (skeys.Any())
+                    {
+                        try
                         {
-                            CoreUser coreUser = coreUsers.Find(x => x.searchKey.Equals(t.id) || x.id.Equals(t.id));
-                            if (coreUser != null)
-                            {
-                                t.id = coreUser.id;
-                                t.name = coreUser.name;
-                                t.picture = coreUser.picture;
-                                t.tmdid = coreUser.id;
-                                if (!string.IsNullOrWhiteSpace(coreUser.mobile))
-                                {
-                                    t.phone = coreUser.mobile;
-                                }
-                                if (!string.IsNullOrWhiteSpace(coreUser.mail))
-                                {
-                                    t.email = coreUser.mail;
-                                }
-                            }
-                            else
+                            var content = new StringContent(skeys.ToJsonString(), Encoding.UTF8, "application/json");
+                            string json = await _coreAPIHttpService.GetUserInfos(content);
+                            if (!string.IsNullOrWhiteSpace(json))
                             {
-                                t.id = null;
+                                coreUsers = json.ToObject<List<CoreUser>>();
+                                ids = coreUsers.Select(x => x.id);
                             }
                         }
-                        if (string.IsNullOrWhiteSpace(t.id))
+                        catch (Exception ex)
+                        {
+                            //await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n{skeys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                        }
+                    }
+                    if (coreUsers.Any())
+                    {
+                        teacherImport.teachers.ForEach(t =>
                         {
-                            if (!string.IsNullOrWhiteSpace(t.tmdid))
+                            if (!string.IsNullOrWhiteSpace(t.id))
                             {
-                                CoreUser coreUser = coreUsers.Find(x => x.id.Equals(t.tmdid));
+                                CoreUser coreUser = coreUsers.Find(x => x.searchKey.Equals(t.id) || x.id.Equals(t.id));
                                 if (coreUser != null)
                                 {
                                     t.id = coreUser.id;
@@ -185,12 +169,16 @@ namespace TEAMModelOS.Controllers
                                         t.email = coreUser.mail;
                                     }
                                 }
+                                else
+                                {
+                                    t.id = null;
+                                }
                             }
                             if (string.IsNullOrWhiteSpace(t.id))
                             {
-                                if (!string.IsNullOrWhiteSpace(t.phone))
+                                if (!string.IsNullOrWhiteSpace(t.tmdid))
                                 {
-                                    CoreUser coreUser = coreUsers.Find(x => x.mobile.Equals(t.phone));
+                                    CoreUser coreUser = coreUsers.Find(x => x.id.Equals(t.tmdid));
                                     if (coreUser != null)
                                     {
                                         t.id = coreUser.id;
@@ -207,41 +195,93 @@ namespace TEAMModelOS.Controllers
                                         }
                                     }
                                 }
-                            }
-                            if (string.IsNullOrWhiteSpace(t.id))
-                            {
-                                if (!string.IsNullOrWhiteSpace(t.email))
+                                if (string.IsNullOrWhiteSpace(t.id))
                                 {
-                                    CoreUser coreUser = coreUsers.Find(x =>!string.IsNullOrWhiteSpace(x.mail)  && x.mail.Equals(t.email));
-                                    if (coreUser != null)
+                                    if (!string.IsNullOrWhiteSpace(t.phone))
                                     {
-                                        t.id = coreUser.id;
-                                        t.name = coreUser.name;
-                                        t.picture = coreUser.picture;
-                                        t.tmdid = coreUser.id;
-                                        if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                        CoreUser coreUser = coreUsers.Find(x => x.mobile.Equals(t.phone));
+                                        if (coreUser != null)
                                         {
-                                            t.phone = coreUser.mobile;
+                                            t.id = coreUser.id;
+                                            t.name = coreUser.name;
+                                            t.picture = coreUser.picture;
+                                            t.tmdid = coreUser.id;
+                                            if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                            {
+                                                t.phone = coreUser.mobile;
+                                            }
+                                            if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                            {
+                                                t.email = coreUser.mail;
+                                            }
                                         }
-                                        if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                    }
+                                }
+                                if (string.IsNullOrWhiteSpace(t.id))
+                                {
+                                    if (!string.IsNullOrWhiteSpace(t.email))
+                                    {
+                                        CoreUser coreUser = coreUsers.Find(x => !string.IsNullOrWhiteSpace(x.mail) && x.mail.Equals(t.email));
+                                        if (coreUser != null)
                                         {
-                                            t.email = coreUser.mail;
+                                            t.id = coreUser.id;
+                                            t.name = coreUser.name;
+                                            t.picture = coreUser.picture;
+                                            t.tmdid = coreUser.id;
+                                            if (!string.IsNullOrWhiteSpace(coreUser.mobile))
+                                            {
+                                                t.phone = coreUser.mobile;
+                                            }
+                                            if (!string.IsNullOrWhiteSpace(coreUser.mail))
+                                            {
+                                                t.email = coreUser.mail;
+                                            }
                                         }
                                     }
                                 }
                             }
-                        }
-                        if (!string.IsNullOrWhiteSpace(t.id))
-                        {
-                            var tch = teachers.Find(x => x.id.Equals(t.id));
-                            if (tch == null)
+                            if (!string.IsNullOrWhiteSpace(t.id))
+                            {
+                                var tch = teachers.Find(x => x.id.Equals(t.id));
+                                if (tch == null)
+                                {
+                                    tch = new ScTeacher
+                                    {
+                                        id = t.id,
+                                        iname = t.iname,
+                                        name = t.name,
+                                        picture = t.picture,
+                                        status = "import",
+                                        createTime = t.time,
+                                        permissionCount = 0,
+                                        size = 0,
+                                        permissions = new List<string>(),
+                                        roles = new List<string>(),
+                                        subjectIds = new List<string>(),
+                                        groups = new List<IdNameCode>(),
+                                        note = t.note,
+                                        phone = t.phone,
+                                        email = t.email,
+                                    };
+                                    teachers.Add(tch);
+                                }
+                                else
+                                {
+                                    tch.iname = t.iname;
+                                    tch.note = t.note;
+                                    tch.phone = t.phone;
+                                    tch.email = t.email;
+                                }
+                            }
+                            else
                             {
-                                tch = new ScTeacher
+                                //teachers.Add();
+                                var tch = new ScTeacher
                                 {
                                     id = t.id,
+                                    picture = t.picture,
                                     iname = t.iname,
                                     name = t.name,
-                                    picture = t.picture,
                                     status = "import",
                                     createTime = t.time,
                                     permissionCount = 0,
@@ -256,18 +296,15 @@ namespace TEAMModelOS.Controllers
                                 };
                                 teachers.Add(tch);
                             }
-                            else
-                            {
-                                tch.iname = t.iname;
-                                tch.note = t.note;
-                                tch.phone = t.phone;
-                                tch.email = t.email;
-                            }
-                        }
-                        else
+                        });
+                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync(teacherImport, $"{school_code}", new PartitionKey("TeacherImport"));
+                    }
+                    else
+                    {
+                        var noids = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id));
+                        foreach (var t in noids)
                         {
-                            //teachers.Add();
-                            var tch = new ScTeacher
+                            teachers.Add(new ScTeacher
                             {
                                 id = t.id,
                                 picture = t.picture,
@@ -284,70 +321,49 @@ namespace TEAMModelOS.Controllers
                                 note = t.note,
                                 phone = t.phone,
                                 email = t.email,
-                            };
-                            teachers.Add(tch);
+                            });
                         }
-                    });
-                    await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReplaceItemAsync(teacherImport, $"{school_code}", new PartitionKey("TeacherImport"));
+                    }
                 }
-                else {
-                    var noids = teacherImport.teachers.Where(x => string.IsNullOrWhiteSpace(x.id));
-                    foreach (var t in noids)
+                IEnumerable<string> coreids = null;
+                coreids = teachers.Where(z => !string.IsNullOrWhiteSpace(z.id)).Select(x => x.id);
+                List<CoreUser> users = new List<CoreUser>();
+                if (coreids != null && coreids.Any())
+                {
+                    try
                     {
-                        teachers.Add(new ScTeacher
+                        var content = new StringContent(coreids.ToJsonString(), Encoding.UTF8, "application/json");
+                        string json = await _coreAPIHttpService.GetUserInfos(content);
+                        if (!string.IsNullOrWhiteSpace(json))
                         {
-                            id = t.id,
-                            picture = t.picture,
-                            iname = t.iname,
-                            name = t.name,
-                            status = "import",
-                            createTime = t.time,
-                            permissionCount = 0,
-                            size = 0,
-                            permissions = new List<string>(),
-                            roles = new List<string>(),
-                            subjectIds = new List<string>(),
-                            groups = new List<IdNameCode>(),
-                            note = t.note,
-                            phone = t.phone,
-                            email = t.email,
-                        });
+                            users = json.ToObject<List<CoreUser>>();
+                        }
                     }
-                }
-            }
-            IEnumerable<string> coreids = null;
-            coreids = teachers.Where(z => !string.IsNullOrWhiteSpace(z.id)).Select(x => x.id);
-            List<CoreUser> users = new List<CoreUser>();
-            if (coreids != null && coreids.Any()) {
-                try
-                {
-                    var content = new StringContent(coreids.ToJsonString(), Encoding.UTF8, "application/json");
-                    string json = await _coreAPIHttpService.GetUserInfos(content);
-                    if (!string.IsNullOrWhiteSpace(json))
+                    catch (Exception ex)
                     {
-                        users = json.ToObject<List<CoreUser>>();
+                        //await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n{skeys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
                     }
                 }
-                catch (Exception ex)
+                if (users.Any())
                 {
-                    //await _dingDing.SendBotMsg($"{_option.Location},导入名单时,查验key信息错误{ex.Message}\n{ex.StackTrace}\n{skeys.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
-                }
-            }
-            if (users.Any()) {
-                teachers.ForEach(x => {
-                    if (!string.IsNullOrWhiteSpace(x.id)) {
-                        CoreUser coreUser = users.Find(u => u.id.Equals(x.id));
-                        if (coreUser != null)
-                        {
-                            x.phone = coreUser.mobile;
-                            x.email = coreUser.mail;
-                        }
-                        else
+                    teachers.ForEach(x => {
+                        if (!string.IsNullOrWhiteSpace(x.id))
                         {
-                            x.status = "delete";
+                            CoreUser coreUser = users.Find(u => u.id.Equals(x.id));
+                            if (coreUser != null)
+                            {
+                                x.phone = coreUser.mobile;
+                                x.email = coreUser.mail;
+                            }
+                            else
+                            {
+                                x.status = "delete";
+                            }
                         }
-                    }
-                });
+                    });
+                }
+            } catch (Exception ex) {
+               await _dingDing.SendBotMsg($"{_option.Location},{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
             }
             return Ok(new { teachers });
         }

+ 8 - 6
TEAMModelOS/Controllers/Student/StudentController.cs

@@ -324,6 +324,7 @@ namespace TEAMModelOS.Controllers
             //權限token
             jwt.Payload.TryGetValue("name", out object _name);
             jwt.Payload.TryGetValue("picture", out object _picture);
+            School school = await schoolClient.ReadItemAsync<School>($"{school_code}", new PartitionKey("Base"));
             var response = await studentClient.ReadItemStreamAsync(id, new PartitionKey($"Base-{school_code.ToLower()}"));
             if (response.Status == 200)
             {
@@ -336,7 +337,7 @@ namespace TEAMModelOS.Controllers
                 rjson.RootElement.TryGetProperty("no", out JsonElement no);
                 rjson.RootElement.TryGetProperty("groupId", out JsonElement groupId);
                 rjson.RootElement.TryGetProperty("groupName", out JsonElement groupName);
-                (string auth_token, string blob_uri, string blob_sas, object classinfo, List<object> courses, AuthenticationResult token) = await StudentCheck($"{id}", $"{classId}", $"{school_code}", $"{picture}", $"{name}", schoolClient, teacherClient);
+                (string auth_token, string blob_uri, string blob_sas, object classinfo, List<object> courses, AuthenticationResult token) = await StudentCheck($"{id}", $"{classId}", $"{school_code}", $"{picture}", $"{name}", schoolClient, teacherClient, school.areaId);
                 return Ok(new { location = _option.Location, error = 0, auth_token, blob_uri, blob_sas, classinfo, courses, token = new { access_token = token.AccessToken, expires_in = token.ExpiresOn, id_token = auth_token, token_type = token.TokenType } });
             }
             else
@@ -364,7 +365,7 @@ namespace TEAMModelOS.Controllers
                 if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
                 if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
                 if (!request.TryGetProperty("pw", out JsonElement pw)) return BadRequest();
-
+                School  school  = await schoolClient.ReadItemAsync<School>($"{school_code}", new PartitionKey("Base"));
                 var response = await studentClient.ReadItemStreamAsync(id.GetString(), new PartitionKey($"Base-{school_code.GetString().ToLower()}"));
                 if (response.Status == 200)
                 {
@@ -381,7 +382,7 @@ namespace TEAMModelOS.Controllers
                     var HashedPW = Utils.HashedPassword(pw.ToString(), salt.ToString());
                     if (HashedPW.Equals(dbpw.GetString()))
                     {
-                        (string auth_token, string blob_uri, string blob_sas, object classinfo, List<object> courses, AuthenticationResult token) =await StudentCheck($"{id}", $"{classId}", $"{school_code}", $"{picture}", $"{name}", schoolClient, teacherClient);
+                        (string auth_token, string blob_uri, string blob_sas, object classinfo, List<object> courses, AuthenticationResult token) =await StudentCheck($"{id}", $"{classId}", $"{school_code}", $"{picture}", $"{name}", schoolClient, teacherClient ,school.areaId);
                         return Ok(new { location = _option.Location, error = 0, auth_token, blob_uri, blob_sas, classinfo, courses,token =new { access_token = token.AccessToken, expires_in = token.ExpiresOn, id_token = auth_token, token_type = token.TokenType }  });
                     }
                     else
@@ -400,7 +401,7 @@ namespace TEAMModelOS.Controllers
                 return BadRequest();
             }
         }
-        private async Task<(string auth_token,string blob_uri,string blob_sas, object classinfo, List<object>  courses, AuthenticationResult token)> StudentCheck(string id ,string classId,string school_code ,string picture,string name , CosmosContainer schoolClient, CosmosContainer teacherClient) {
+        private async Task<(string auth_token,string blob_uri,string blob_sas, object classinfo, List<object>  courses, AuthenticationResult token)> StudentCheck(string id ,string classId,string school_code ,string picture,string name , CosmosContainer schoolClient, CosmosContainer teacherClient, string  areaId) {
             //班級課程
             object classinfo = null;
             List<object> courses = new List<object>();
@@ -528,7 +529,7 @@ namespace TEAMModelOS.Controllers
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(school_code.ToLower(), BlobContainerSasPermissions.Read);
 
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name, picture, _option.JwtSecretKey, scope: Constant.ScopeStudent, Website: "IES", schoolID: school_code, roles: new[] { "student" });
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name, picture, _option.JwtSecretKey, scope: Constant.ScopeStudent, Website: "IES",areaId: areaId, schoolID: school_code, roles: new[] { "student" },expire: 1);
             var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
             var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
             var token = await CoreTokenExtensions.CreateAccessToken(clientID, clientSecret, _option.Location.Replace("-Dep", "").Replace("-Test", ""));
@@ -634,6 +635,7 @@ namespace TEAMModelOS.Controllers
                     var HashedPW = Utils.HashedPassword(pw.ToString(), salt.ToString());
                     if (HashedPW.Equals(dbpw.GetString()))
                     {
+                        School schoolInfo = await schoolClient.ReadItemAsync<School>($"{school_code}", new PartitionKey("Base"));
                         //取得所屬預設班級信息
                         object classinfo = null;
                         if (!classId.ValueKind.Equals(JsonValueKind.Null) && classId.ValueKind.Equals(JsonValueKind.String))
@@ -652,7 +654,7 @@ namespace TEAMModelOS.Controllers
                             }
                         }
                         //換取AuthToken,提供給前端
-                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" });
+                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey, Website: "IES",areaId: schoolInfo.areaId, scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" }, expire: 1);
                         //其他訊息
                         dynamic school = new ExpandoObject();
                         //回傳

+ 2 - 1
TEAMModelOS/Controllers/Student/TmdUserController.cs

@@ -125,6 +125,7 @@ namespace TEAMModelOS.Controllers
                         //如果沒有,則初始化Teacher基本資料到Cosmos
                         TmdUser teacher = new TmdUser
                         {
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                             id = id,
                             pk = "Base",
                             code = "Base",
@@ -139,7 +140,7 @@ namespace TEAMModelOS.Controllers
                     }
                 }
                 //換取AuthToken,提供給前端
-                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTmdUser, roles: new[] { "student" });
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTmdUser, roles: new[] { "student" }, expire: 1);
                 if (!string.IsNullOrEmpty(defaultschool)) { 
 
                 }

+ 8 - 39
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -255,13 +255,14 @@ namespace TEAMModelOS.Controllers
             var id = jwt.Payload.Sub;
             jwt.Payload.TryGetValue("name", out object name);
             jwt.Payload.TryGetValue("picture", out object picture);
+            (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
             try
             {
                
                 Teacher teacher = null;
                 TeacherInfo teacherInfo= await TeacherService.TeacherInfo(_azureCosmos, teacher, $"{name}", $"{picture}", id, _azureStorage, _option);
                 teacherInfo.areas.ForEach(x => { if (x.setting != null) { x.setting.accessConfig=x.setting.accessConfig; } });
-                LoginLog(id, $"{name}", 200);
+                LoginService.LoginLog(HttpContext,_option,_logger,_dingDing,ip,region, id, $"{name}", 200);
                 int lessonLimit = teacherInfo.teacher.lessonLimit;
                 if (teacherInfo.teacher.lessonLimit == 0)
                 {
@@ -280,52 +281,18 @@ namespace TEAMModelOS.Controllers
             }
             catch (CosmosException ex)
             {
-                LoginLog(id, $"{name}", 500);
+                LoginService.LoginLog(HttpContext, _option, _logger, _dingDing, ip, region, id, $"{name}", 500);
                 await _dingDing.SendBotMsg($"IES5,{_option.Location},Teacher/GetTeacherInfo()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                 return BadRequest();
             }
             catch (Exception ex)
             {
-                LoginLog(id, $"{name}", 500);
+                LoginService.LoginLog(HttpContext, _option, _logger, _dingDing, ip, region, id, $"{name}", 500);
                 _ = _dingDing.SendBotMsg($"IES5,{_option.Location},Teacher/GetTeacherInfo()\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
                 return BadRequest();
             }
         }
-
-
-        private   async void LoginLog(string id, string name, int status) {
-            HttpContext.Request.Headers.TryGetValue("referer", out var referer);
-            HttpContext.Request.Headers.TryGetValue("sec-ch-ua", out var chua);
-            HttpContext.Request.Headers.TryGetValue("sec-ch-ua-platform", out var platform);
-            HttpContext.Request.Headers.TryGetValue("user-agent", out var useragent);
-       
-            var IpPort = HttpContext.Request.Headers["X-Forwarded-For"].FirstOrDefault();
-            if (string.IsNullOrEmpty(IpPort))
-            {
-                IpPort = HttpContext.Connection.RemoteIpAddress.ToString();
-            }
-            if (IpPort.Contains("::")) 
-            {
-                IpPort = "127.0.0.1";
-            }
-            string ip = IpPort.Split(":")[0];
-            string region= await _searcher.SearchIpAsync(ip);
-          
-            if (status == 200)
-            {
-                string msg = $"{_option.Location} -- {name}({id}):Login Succeed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " +
-                    $"--Browser Info( --referer:{referer}  --sec-ch-ua:{chua}  --sec-ch-ua-platform:{platform}  --user-agent:{useragent}  --ip:{IpPort} --region:{region} )";
-                _logger.LogInformation(msg);
-            }
-            else
-            {
-                string msg = $"{_option.Location} -- {name}({id}):Login Failed! --Time:{DateTimeOffset.UtcNow.ToString("yyyy-MM-dd HH:mm:ss")} " +
-                         $"--Browser Info( --referer:{referer}  --sec-ch-ua:{chua}  --sec-ch-ua-platform:{platform}  --user-agent:{useragent}  --ip:{IpPort} --region:{region} )";
-                _ = _dingDing.SendBotMsg($"IES5,{_option.Location},{msg}",GroupNames.醍摩豆服務運維群組);
-                _logger.LogError(msg);
-            }
-            
-        }
+      
         //TODO 此API需處理對應前端返回的相關數據
         [ProducesDefaultResponseType]
         [Authorize(Roles = "IES")]
@@ -467,6 +434,7 @@ namespace TEAMModelOS.Controllers
                         }
                     }
                 }
+                string currAreaId = "";
                 dynamic currArea = new ExpandoObject();
                 if (!string.IsNullOrEmpty(school_base.areaId)) {
                     try
@@ -499,6 +467,7 @@ namespace TEAMModelOS.Controllers
                             //submitType=accessConfig?.submitType,
                             homeworkType = accessConfig!=null && accessConfig.homeworkType.IsNotEmpty()?accessConfig.homeworkType:new List<string> { "pdf"}, 
                         };
+                        currAreaId = area?.id;
                     }
                     catch (CosmosException)
                     {
@@ -511,7 +480,7 @@ namespace TEAMModelOS.Controllers
                     roles.Add("area");
                 }
                 //TODO JJ,更新Token时,在取得学校资讯时,没有传入schoolId
-                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray());
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, schoolID: school_code.ToString(),areaId: currAreaId, standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), expire: 1);
 
                 //取得班级
                 List<object> school_classes = new List<object>();

+ 36 - 3
TEAMModelOS/Controllers/Third/OAuth2Controller.cs

@@ -33,6 +33,8 @@ using TEAMModelOS.Filter;
 using TEAMModelOS.Controllers.Third.Xkw;
 using Microsoft.Extensions.Primitives;
 using System.Net.Http;
+using Microsoft.Azure.Cosmos.Table;
+
 namespace TEAMModelOS.Controllers.Third
 {
     
@@ -96,13 +98,44 @@ namespace TEAMModelOS.Controllers.Third
         [HttpPost("check-bind")]
         [Authorize(Roles = "IES")]
         [AuthToken(Roles = "teacher,admin,area,student")]
-        public async Task<IActionResult> Bind(JsonElement json)
+        public async Task<IActionResult> CheckBind(JsonElement json)
         {
             string domain = HttpContext?.Request?.Host.Host;
-            var (tmdid, _, _, school) = HttpContext.GetAuthTokenInfo();
+            var (tmdid, _, _, school,area,keyData) = HttpContext.GetAuthTokenKey();
             var table = _azureStorage.GetCloudTableClient().GetTableReference("IESOAuth");
+
+            
+            List<string> RowKeys = new List<string>();
+            if (!string.IsNullOrWhiteSpace(tmdid)) {
+                RowKeys.Add($" Code {QueryComparisons.Equal} '{tmdid}' ");
+            }
+            if (!string.IsNullOrWhiteSpace(school))
+            {
+                RowKeys.Add($" Code {QueryComparisons.Equal} '{school}' ");
+            }
+            if (!string.IsNullOrWhiteSpace(area))
+            {
+                RowKeys.Add($" Code {QueryComparisons.Equal} '{area}' ");
+            }
+         
+            string qurey = $"PartitionKey {QueryComparisons.Equal} 'OAuthShow'  and ( { string.Join(" or ", RowKeys)} )  ";
+
+            var result=  await table.ExecuteQuerySegmentedAsync(new TableQuery<OAuthShow>().Where(qurey),null) ;
+            List<OAuthShow> shows = result.Results;
+            List<OAuthShow> schoolShow = new List<OAuthShow>();
+            var schoolShows = shows?.Where(y => !y.Scope.Equals("private"));
+            if (schoolShows.Any()) {
+                schoolShows.ToList().ForEach(y => { y.Scope = "school";y.Code = school; });
+                schoolShows.GroupBy(x => $"{x.Type}{x.Scope}").Select(s => new { key = s.Key, list = s.ToList() }).ToList().ForEach(z => {
+                    schoolShow.Add(z.list.First());
+                });
+            }
             List<OAuthUser> authUsers = await table.FindListByDict<OAuthUser>(new Dictionary<string, object>() { { "RowKey", tmdid },{ "Domain" ,domain} });
-            return Ok(new { auth = authUsers.Select(x => new { type = x.Type, tmdid = x.RowKey, time = x.Time }) });
+            return Ok(new { 
+                auth = authUsers.Select(x => new { type = x.Type, tmdid = x.RowKey, time = x.Time }),
+                privateShows = shows?.FindAll(x=>x.Scope.Equals("private")).Select(x=>new { x.Type,x.Status,x.Scope,x.Code}),
+                schoolShows= schoolShow.Select(x => new { x.Type, x.Status, x.Scope, x.Code })
+            });
         }
     }
 }

+ 1 - 0
TEAMModelOS/Controllers/Third/Sc/ScController.cs

@@ -401,6 +401,7 @@ namespace TEAMModelOS.Controllers
                 {
                     teacher = new Teacher
                     {
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
                         id = id,
                         pk = "Teacher",
                         code = "Base",

+ 2 - 1
TEAMModelOS/Controllers/XTest/TestController.cs

@@ -727,7 +727,8 @@ namespace TEAMModelOS.Controllers
                     {
                         Teacher teacher = new Teacher
                         {
-                            pk="Base",
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                            pk ="Base",
                             code = "Base",
                             id = id,
                             name = scBindData.username,

+ 3 - 1
TEAMModelOS/Filter/AuthTokenAttribute.cs

@@ -38,7 +38,7 @@ namespace TEAMModelOS.Filter
             public void OnResourceExecuting(ResourceExecutingContext context)
             {
                 bool pass = false;
-                string id = string.Empty, name = string.Empty, picture = string.Empty, school = string.Empty, standard = string.Empty,scope=string.Empty,  website=string.Empty;
+                string id = string.Empty, name = string.Empty, picture = string.Empty, school = string.Empty, standard = string.Empty,scope=string.Empty,  website=string.Empty, area=string.Empty;
                 List<string> _role = new List<string>();
                 var authtoken = context.HttpContext.GetXAuth("AuthToken");
                 if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateAuthToken(authtoken, _option.JwtSecretKey))
@@ -51,6 +51,7 @@ namespace TEAMModelOS.Filter
                     standard = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("standard"))?.Value;
                     scope = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("scope"))?.Value;
                     website = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("website"))?.Value;
+                    area = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("area"))?.Value;
                     if (!string.IsNullOrWhiteSpace(_roles))
                     {
                         var roles = jwt.Claims.Where(c => c.Type.Equals("roles"));
@@ -88,6 +89,7 @@ namespace TEAMModelOS.Filter
                     context.HttpContext.Items.Add("Roles", _role);
                     context.HttpContext.Items.Add("Scope", scope);
                     context.HttpContext.Items.Add("Website", website);
+                    context.HttpContext.Items.Add("Area", area);
                 }
                 else
                     context.Result = new UnauthorizedResult();