CrazyIter_Bin 1 vuosi sitten
vanhempi
commit
a698ff5e09

+ 1 - 1
TEAMModelOS.SDK/Extension/JwtAuthExtension.cs

@@ -15,7 +15,7 @@ namespace TEAMModelOS.SDK.Extension
 {
 {
     public static class JwtAuthExtension
     public static class JwtAuthExtension
     {
     {
-        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,int year=-1)
+        public static string CreateAuthToken(string issuer, string id, string name, string picture, string salt, string scope, string Website,int timezone, string areaId = "", string schoolID = "", string standard = "", string[] roles = null, string[] permissions = null, int expire = 1,int year=-1)
         {
         {
             // 設定要加入到 JWT Token 中的聲明資訊(Claims)  
             // 設定要加入到 JWT Token 中的聲明資訊(Claims)  
             var payload = new JwtPayload {
             var payload = new JwtPayload {

+ 4 - 4
TEAMModelOS.SDK/Models/Service/Common/TeacherService.cs

@@ -31,7 +31,7 @@ namespace TEAMModelOS.Services
     public static class TeacherService
     public static class TeacherService
     {
     {
         public static async Task<TeacherInfo> TeacherInfoLite(AzureCosmosFactory _azureCosmos,  string name, string picture, string id,
         public static async Task<TeacherInfo> TeacherInfoLite(AzureCosmosFactory _azureCosmos,  string name, string picture, string id,
-           AzureStorageFactory _azureStorage, Option _option, AzureRedisFactory _azureRedis, string ip, HttpTrigger _httpTrigger, string lang)
+           AzureStorageFactory _azureStorage, Option _option, AzureRedisFactory _azureRedis, string ip, HttpTrigger _httpTrigger, string lang,int timezone)
         {
         {
             Teacher teacher = null;
             Teacher teacher = null;
             string defaultschool = null;
             string defaultschool = null;
@@ -189,7 +189,7 @@ namespace TEAMModelOS.Services
             catch { }
             catch { }
 
 
             //換取AuthToken,提供給前端
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, standard:  "", roles: roles.ToArray(), expire: 1);
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTeacher, standard:  "", roles: roles.ToArray(), expire: 1);
 
 
             //取得Teacher Blob 容器位置及SAS 
             //取得Teacher Blob 容器位置及SAS 
             await _azureStorage.GetBlobContainerClient(id).CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
             await _azureStorage.GetBlobContainerClient(id).CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
@@ -204,7 +204,7 @@ namespace TEAMModelOS.Services
             };
             };
         }
         }
         public static async Task<TeacherInfo> TeacherInfo(AzureCosmosFactory _azureCosmos, Teacher teacher, string name, string picture, string id,
         public static async Task<TeacherInfo> TeacherInfo(AzureCosmosFactory _azureCosmos, Teacher teacher, string name, string picture, string id,
-            AzureStorageFactory _azureStorage, Option _option, AzureRedisFactory _azureRedis, string ip, HttpTrigger _httpTrigger, string lang)
+            AzureStorageFactory _azureStorage, Option _option, AzureRedisFactory _azureRedis, string ip, HttpTrigger _httpTrigger, string lang,int timezone)
         {
         {
             List<object> schools = new List<object>();
             List<object> schools = new List<object>();
             List<AreaDto> areas = new List<AreaDto>();
             List<AreaDto> areas = new List<AreaDto>();
@@ -489,7 +489,7 @@ namespace TEAMModelOS.Services
                 }
                 }
             }
             }
             //換取AuthToken,提供給前端
             //換取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(), expire: 1);
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTeacher, standard: areaa != null ? areaa.standard : "", roles: roles.ToArray(), expire: 1);
 
 
             //用户在线记录
             //用户在线记录
             try
             try

+ 31 - 3
TEAMModelOS/Controllers/Client/AClassONEController.cs

@@ -25,6 +25,7 @@ using System.Linq;
 using System.Net;
 using System.Net;
 using System.Net.Http;
 using System.Net.Http;
 using System.Reflection;
 using System.Reflection;
+using System.Security.Policy;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
@@ -160,6 +161,11 @@ namespace TEAMModelOS.Controllers
                 {
                 {
                     head_lang = $"{_lang}";
                     head_lang = $"{_lang}";
                 }
                 }
+                int timezone = 8;
+                if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone,out int tz))
+                {
+                    timezone=tz;
+                }
                 if (!json.TryGetProperty("code", out JsonElement _code)) return BadRequest("code is null");
                 if (!json.TryGetProperty("code", out JsonElement _code)) return BadRequest("code is null");
                 var phoneInfo = await GetWeChatPhoneNumber(_code.ToString());
                 var phoneInfo = await GetWeChatPhoneNumber(_code.ToString());
                 //phoneInfo.code=200;
                 //phoneInfo.code=200;
@@ -172,7 +178,7 @@ namespace TEAMModelOS.Controllers
                     {
                     {
                         (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
                         (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
                         Teacher teacher = null;
                         Teacher teacher = null;
-                        TeacherInfo teacherInfo = await TeacherService.TeacherInfo(_azureCosmos, teacher, $"{coreUser.name}", $"{coreUser.picture}", coreUser.id, _azureStorage, _option, _azureRedis, ip, _httpTrigger, $"{_lang}");
+                        TeacherInfo teacherInfo = await TeacherService.TeacherInfo(_azureCosmos, teacher, $"{coreUser.name}", $"{coreUser.picture}", coreUser.id, _azureStorage, _option, _azureRedis, ip, _httpTrigger, $"{_lang}",timezone);
                         return Ok(new
                         return Ok(new
                         {
                         {
                             teacherInfo.auth_token,
                             teacherInfo.auth_token,
@@ -365,8 +371,30 @@ namespace TEAMModelOS.Controllers
                 roles.Add("area");
                 roles.Add("area");
             }
             }
             areas.ForEach(x => { { if (x.setting != null) { x.setting.accessConfig = x.setting.accessConfig; } } });
             areas.ForEach(x => { { if (x.setting != null) { x.setting.accessConfig = x.setting.accessConfig; } } });
-
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName,teacher. id, teacher.name, teacher.picture, _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);
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
+            if (!string.IsNullOrWhiteSpace(school_base.timeZone?.value)) 
+            {
+                string timeZoneOffsetString = school_base.timeZone.value;
+                bool plus = true;
+                if (timeZoneOffsetString.Contains("-"))
+                {
+                    plus=false;
+                }
+               
+                // 去除时区偏移字符串中的正负号
+                timeZoneOffsetString = timeZoneOffsetString.Replace("+", "").Replace("-", "");
+                // 尝试解析格式化后的时区偏移字符串
+                if (TimeSpan.TryParse(timeZoneOffsetString, out TimeSpan timeZoneOffset))
+                {
+                    // 将时区偏移转换为小时数
+                    timezone = plus ? (int)timeZoneOffset.TotalHours : -(int)timeZoneOffset.TotalHours;
+                }
+            }
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName,teacher. id, teacher.name, teacher.picture, _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), areaId: currAreaId, standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), expire: 1);
             string school_code_blob = school_code.ToLower();
             string school_code_blob = school_code.ToLower();
             var container = _azureStorage.GetBlobContainerClient(school_code_blob);
             var container = _azureStorage.GetBlobContainerClient(school_code_blob);
             await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建School容器,如存在則不做任何事,保障容器一定存在
             await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建School容器,如存在則不做任何事,保障容器一定存在

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

@@ -231,6 +231,29 @@ namespace TEAMModelOS.Controllers.Client
                     });
                     });
                 }
                 }
             }
             }
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
+            if (!string.IsNullOrWhiteSpace(school.timeZone?.value))
+            {
+                string timeZoneOffsetString = school.timeZone.value;
+                bool plus = true;
+                if (timeZoneOffsetString.Contains("-"))
+                {
+                    plus=false;
+                }
+
+                // 去除时区偏移字符串中的正负号
+                timeZoneOffsetString = timeZoneOffsetString.Replace("+", "").Replace("-", "");
+                // 尝试解析格式化后的时区偏移字符串
+                if (TimeSpan.TryParse(timeZoneOffsetString, out TimeSpan timeZoneOffset))
+                {
+                    // 将时区偏移转换为小时数
+                    timezone = plus ? (int)timeZoneOffset.TotalHours : -(int)timeZoneOffset.TotalHours;
+                }
+            }
             var id_token = new JwtSecurityToken($"{join.id_token}");
             var id_token = new JwtSecurityToken($"{join.id_token}");
             var auth_token = string.Empty;
             var auth_token = string.Empty;
             var response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(id_token.Payload.Sub, new PartitionKey($"Teacher-{join.school}"));
             var response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(id_token.Payload.Sub, new PartitionKey($"Teacher-{join.school}"));
@@ -238,7 +261,7 @@ namespace TEAMModelOS.Controllers.Client
                 id_token.Payload.TryGetValue("name", out object name);
                 id_token.Payload.TryGetValue("name", out object name);
                 id_token.Payload.TryGetValue("picture", out object picture);
                 id_token.Payload.TryGetValue("picture", out object picture);
                 SchoolTeacher schoolTeacher =   JsonDocument.Parse(response.ContentStream).RootElement.ToObject<SchoolTeacher>();
                 SchoolTeacher schoolTeacher =   JsonDocument.Parse(response.ContentStream).RootElement.ToObject<SchoolTeacher>();
-                auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id_token.Payload.Sub, $"{name}",$"{picture}", _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTeacher, schoolID: join.school, areaId: school.areaId, standard: school.standard, roles: schoolTeacher.roles.ToArray(), permissions:schoolTeacher.permissions.ToArray(), expire: 1);
+                auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id_token.Payload.Sub, $"{name}",$"{picture}", _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTeacher, schoolID: join.school, areaId: school.areaId, standard: school.standard, roles: schoolTeacher.roles.ToArray(), permissions:schoolTeacher.permissions.ToArray(), expire: 1);
 
 
             }
             }
             await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client="hita", count=1, id=school.id, key="teacher_login", name=school.name, scope="school", target=school.id });
             await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client="hita", count=1, id=school.id, key="teacher_login", name=school.name, scope="school", target=school.id });
@@ -250,6 +273,11 @@ namespace TEAMModelOS.Controllers.Client
         [HttpGet("check-login")]
         [HttpGet("check-login")]
         public async Task<IActionResult> CheckLogin([FromQuery] HiTAJoinSchool join)
         public async Task<IActionResult> CheckLogin([FromQuery] HiTAJoinSchool join)
         {
         {
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
             var data = await _azureRedis.GetRedisClient(8).StringGetAsync($"HiTA:Login:{join.code}");
             var data = await _azureRedis.GetRedisClient(8).StringGetAsync($"HiTA:Login:{join.code}");
             if (data.HasValue)
             if (data.HasValue)
             {
             {
@@ -275,7 +303,7 @@ namespace TEAMModelOS.Controllers.Client
                 jwt.Payload.TryGetValue("picture", out picture);
                 jwt.Payload.TryGetValue("picture", out picture);
                 jwt.Payload.TryGetValue("lang", out object _jwtlang);
                 jwt.Payload.TryGetValue("lang", out object _jwtlang);
                 (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
                 (string ip, string region) = await LoginService.LoginIp(HttpContext, _searcher);
-                TeacherInfo teacherInfo=  await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", $"{jwt.Payload.Sub}", _azureStorage, _option, _azureRedis, "", _httpTrigger, $"{_jwtlang}");
+                TeacherInfo teacherInfo=  await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", $"{jwt.Payload.Sub}", _azureStorage, _option, _azureRedis, "", _httpTrigger, $"{_jwtlang}",timezone);
                 string x_auth_token = string.Empty;
                 string x_auth_token = string.Empty;
                 if (teacherInfo!=null) {
                 if (teacherInfo!=null) {
                     x_auth_token= teacherInfo.auth_token;
                     x_auth_token= teacherInfo.auth_token;

+ 6 - 1
TEAMModelOS/Controllers/Common/ActivityController.cs

@@ -2732,6 +2732,11 @@ namespace TEAMModelOS.Controllers
         [HttpPost("login-portal")]
         [HttpPost("login-portal")]
         public async Task<IActionResult> LoginPortal(JsonElement request)
         public async Task<IActionResult> LoginPortal(JsonElement request)
         {
         {
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
             string tmdid = null;
             string tmdid = null;
             if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
             if (!request.TryGetProperty("route", out JsonElement _route)) return BadRequest();
             request.TryGetProperty("ticket", out JsonElement _ticket);
             request.TryGetProperty("ticket", out JsonElement _ticket);
@@ -2784,7 +2789,7 @@ namespace TEAMModelOS.Controllers
                 else { return Ok(new { code = 3, msg = "凭证验证失败" }); }
                 else { return Ok(new { code = 3, msg = "凭证验证失败" }); }
             }
             }
 
 
-            teacherInfo = await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", tmdid, _azureStorage, _option, _azureRedis, ip, _httpTrigger, head_lang);
+            teacherInfo = await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", tmdid, _azureStorage, _option, _azureRedis, ip, _httpTrigger, head_lang,timezone);
             string sql = $"select value c from c where c.route='{_route}'";
             string sql = $"select value c from c where c.route='{_route}'";
             var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsite>(sql, "ActivityWebsite");
             var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Normal).GetList<ActivityWebsite>(sql, "ActivityWebsite");
             ActivityWebsite website = null;
             ActivityWebsite website = null;

+ 7 - 1
TEAMModelOS/Controllers/OpenApi/Init/BizUsersController.cs

@@ -115,9 +115,15 @@ namespace TEAMModelOS.Controllers
                     }
                     }
                 }
                 }
                 else return Ok(new { state = RespondCode.NotFound, msg = "未找到该用户!" });
                 else return Ok(new { state = RespondCode.NotFound, msg = "未找到该用户!" });
+                int timezone = 8;
+                if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+                {
+                    timezone=tz;
+                }
+                 
                 if (businessUsers.id != null)
                 if (businessUsers.id != null)
                 {
                 {
-                    var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, businessUsers.id, businessUsers.name, businessUsers.picture, _option.JwtSecretKey, scope: "business", Website: "IES", roles: new[] { "business" }, expire: 1);
+                    var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, businessUsers.id, businessUsers.name, businessUsers.picture, _option.JwtSecretKey, scope: "business", Website: "IES", timezone: timezone, roles: new[] { "business" }, expire: 1);
                     var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
                     var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
                     var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                     var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
                     var token = await CoreTokenExtensions.CreateAccessToken(clientID, clientSecret, _option.Location.Replace("-Dep", "").Replace("-Test", ""));
                     var token = await CoreTokenExtensions.CreateAccessToken(clientID, clientSecret, _option.Location.Replace("-Dep", "").Replace("-Test", ""));

+ 48 - 2
TEAMModelOS/Controllers/Student/StudentController.cs

@@ -717,9 +717,31 @@ namespace TEAMModelOS.Controllers
 
 
             // BLOB(學校,唯讀)
             // BLOB(學校,唯讀)
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(school_code.ToLower(), BlobContainerSasPermissions.Read);
             var (blob_uri, blob_sas) = _azureStorage.GetBlobContainerSAS(school_code.ToLower(), BlobContainerSasPermissions.Read);
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
+            if (!string.IsNullOrWhiteSpace(schoolBase.timeZone?.value))
+            {
+                string timeZoneOffsetString = schoolBase.timeZone.value;
+                bool plus = true;
+                if (timeZoneOffsetString.Contains("-"))
+                {
+                    plus=false;
+                }
 
 
+                // 去除时区偏移字符串中的正负号
+                timeZoneOffsetString = timeZoneOffsetString.Replace("+", "").Replace("-", "");
+                // 尝试解析格式化后的时区偏移字符串
+                if (TimeSpan.TryParse(timeZoneOffsetString, out TimeSpan timeZoneOffset))
+                {
+                    // 将时区偏移转换为小时数
+                    timezone = plus ? (int)timeZoneOffset.TotalHours : -(int)timeZoneOffset.TotalHours;
+                }
+            }
             //換取AuthToken,提供給前端
             //換取AuthToken,提供給前端
-            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: 4,year: student.year);
+            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name, picture, _option.JwtSecretKey, scope: Constant.ScopeStudent, Website: "IES", timezone: timezone, areaId: areaId, schoolID: school_code, roles: new[] { "student" }, expire: 4,year: student.year);
 
 
             //用户在线记录
             //用户在线记录
             try
             try
@@ -1287,8 +1309,32 @@ namespace TEAMModelOS.Controllers
                                 }
                                 }
                             }
                             }
                         }
                         }
+
+                        int timezone = 8;
+                        if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+                        {
+                            timezone=tz;
+                        }
+                        if (!string.IsNullOrWhiteSpace(schoolInfo.timeZone?.value))
+                        {
+                            string timeZoneOffsetString = schoolInfo.timeZone.value;
+                            bool plus = true;
+                            if (timeZoneOffsetString.Contains("-"))
+                            {
+                                plus=false;
+                            }
+
+                            // 去除时区偏移字符串中的正负号
+                            timeZoneOffsetString = timeZoneOffsetString.Replace("+", "").Replace("-", "");
+                            // 尝试解析格式化后的时区偏移字符串
+                            if (TimeSpan.TryParse(timeZoneOffsetString, out TimeSpan timeZoneOffset))
+                            {
+                                // 将时区偏移转换为小时数
+                                timezone = plus ? (int)timeZoneOffset.TotalHours : -(int)timeZoneOffset.TotalHours;
+                            }
+                        }
                         //換取AuthToken,提供給前端
                         //換取AuthToken,提供給前端
-                        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: 4);
+                        var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id.GetString(), name.GetString(), picture.GetString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, areaId: schoolInfo.areaId, scope: Constant.ScopeStudent, schoolID: school_code.GetString(), roles: new[] { "student" }, expire: 4);
                         
                         
                         //用户在线记录
                         //用户在线记录
                         try
                         try

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

@@ -157,8 +157,14 @@ namespace TEAMModelOS.Controllers
                         teacher = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Student").CreateItemAsync<TmdUser>(teacher, new PartitionKey("Base"));
                         teacher = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Student").CreateItemAsync<TmdUser>(teacher, new PartitionKey("Base"));
                     }
                     }
                 }
                 }
+                int timezone = 8;
+                if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+                {
+                    timezone=tz;
+                }
+                 
                 //換取AuthToken,提供給前端
                 //換取AuthToken,提供給前端
-                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", scope: Constant.ScopeTmdUser, roles: new[] { "student" }, expire: 1);
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTmdUser, roles: new[] { "student" }, expire: 1);
 
 
                 //用户在线记录
                 //用户在线记录
                 try
                 try

+ 30 - 2
TEAMModelOS/Controllers/Teacher/InitController.cs

@@ -491,6 +491,11 @@ namespace TEAMModelOS.Controllers
             if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang)) {
             if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang)) {
                 head_lang = $"{_lang}";
                 head_lang = $"{_lang}";
             }
             }
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
             string OAuthShow_domain = HttpContext?.Request?.Host.Host;
             string OAuthShow_domain = HttpContext?.Request?.Host.Host;
             if (OAuthShow_domain.Equals("teammodelos.chinacloudsites.cn"))
             if (OAuthShow_domain.Equals("teammodelos.chinacloudsites.cn"))
             {
             {
@@ -516,7 +521,7 @@ namespace TEAMModelOS.Controllers
             try
             try
             {
             {
                 Teacher teacher = null;
                 Teacher teacher = null;
-                TeacherInfo teacherInfo = await TeacherService.TeacherInfo(_azureCosmos, teacher, $"{name}", $"{picture}", id, _azureStorage, _option, _azureRedis, ip, _httpTrigger, $"{_lang}");
+                TeacherInfo teacherInfo = await TeacherService.TeacherInfo(_azureCosmos, teacher, $"{name}", $"{picture}", id, _azureStorage, _option, _azureRedis, ip, _httpTrigger, $"{_lang}",timezone);
                 teacherInfo.areas.ForEach(x => { if (x.setting != null) { x.setting.accessConfig = x.setting.accessConfig; } });
                 teacherInfo.areas.ForEach(x => { if (x.setting != null) { x.setting.accessConfig = x.setting.accessConfig; } });
                 LoginService.LoginLog(HttpContext, _option, _logger, _dingDing, ip, region, id, $"{name}", 200);
                 LoginService.LoginLog(HttpContext, _option, _logger, _dingDing, ip, region, id, $"{name}", 200);
                 int lessonLimit = teacherInfo.teacher.lessonLimit;
                 int lessonLimit = teacherInfo.teacher.lessonLimit;
@@ -820,8 +825,31 @@ namespace TEAMModelOS.Controllers
                 {
                 {
                     roles.Add("area");
                     roles.Add("area");
                 }
                 }
+                int timezone = 8;
+                if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+                {
+                    timezone=tz;
+                }
+                if (!string.IsNullOrWhiteSpace(school_base.timeZone?.value))
+                {
+                    string timeZoneOffsetString = school_base.timeZone.value;
+                    bool plus = true;
+                    if (timeZoneOffsetString.Contains("-"))
+                    {
+                        plus=false;
+                    }
+
+                    // 去除时区偏移字符串中的正负号
+                    timeZoneOffsetString = timeZoneOffsetString.Replace("+", "").Replace("-", "");
+                    // 尝试解析格式化后的时区偏移字符串
+                    if (TimeSpan.TryParse(timeZoneOffsetString, out TimeSpan timeZoneOffset))
+                    {
+                        // 将时区偏移转换为小时数
+                        timezone = plus ? (int)timeZoneOffset.TotalHours : -(int)timeZoneOffset.TotalHours;
+                    }
+                }
                 //TODO JJ,更新Token时,在取得学校资讯时,没有传入schoolId
                 //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(), areaId: currAreaId, standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), expire: 1);
+                var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES",timezone: timezone, scope: Constant.ScopeTeacher, schoolID: school_code.ToString(), areaId: currAreaId, standard: school_base.standard, roles: roles.ToArray(), permissions: permissions.ToArray(), expire: 1);
 
 
                 //取得班级
                 //取得班级
                 (List < Class > school_classes,_) = await SchoolService.DoGraduateClasses(_httpTrigger, _azureCosmos, null, school_base, _option,_dingDing);
                 (List < Class > school_classes,_) = await SchoolService.DoGraduateClasses(_httpTrigger, _azureCosmos, null, school_base, _option,_dingDing);

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

@@ -1856,9 +1856,15 @@ namespace TEAMModelOS.Controllers
             if (!request.TryGetProperty("picture", out JsonElement picture)) return BadRequest();
             if (!request.TryGetProperty("picture", out JsonElement picture)) return BadRequest();
             if (!request.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
             if (!request.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
             if (!request.TryGetProperty("school", out JsonElement school)) return BadRequest();
             if (!request.TryGetProperty("school", out JsonElement school)) return BadRequest();
+            int timezone = 8;
+            if (HttpContext.Request.Headers.TryGetValue("Time-Zone", out var Time_Zone) && int.TryParse(Time_Zone, out int tz))
+            {
+                timezone=tz;
+            }
+            
             var auth_token = JwtAuthExtension.CreateAuthToken(host.ToString(), id.ToString(), name.ToString(), 
             var auth_token = JwtAuthExtension.CreateAuthToken(host.ToString(), id.ToString(), name.ToString(), 
                 picture.ToString(), _option.JwtSecretKey,
                 picture.ToString(), _option.JwtSecretKey,
-                scope: "student", Website: "IES", areaId: areaId.ToString(),schoolID: school.ToString(), roles: new[] { "student" }, expire: 1);
+                scope: "student", Website: "IES",timezone, areaId: areaId.ToString(),schoolID: school.ToString(), roles: new[] { "student" }, expire: 1);
             //var techs= teachers.Where(t => string.IsNullOrWhiteSpace(t.tmdid));
             //var techs= teachers.Where(t => string.IsNullOrWhiteSpace(t.tmdid));
             return Ok(auth_token);
             return Ok(auth_token);
         }
         }

+ 14 - 2
TEAMModelOS/Filter/AuthTokenAttribute.cs

@@ -12,6 +12,8 @@ using TEAMModelOS.SDK.DI;
 using Microsoft.AspNetCore.Http;
 using Microsoft.AspNetCore.Http;
 using static OpenXmlPowerTools.RevisionProcessor;
 using static OpenXmlPowerTools.RevisionProcessor;
 using TEAMModelOS.SDK.Models;
 using TEAMModelOS.SDK.Models;
+using Microsoft.Extensions.Primitives;
+using System.Net.Http;
 
 
 namespace TEAMModelOS.Filter
 namespace TEAMModelOS.Filter
 {
 {
@@ -47,11 +49,15 @@ namespace TEAMModelOS.Filter
                 
                 
 
 
                 bool pass = false;
                 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, area = 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, timzone = string.Empty ;
                 List<string> _role = new List<string>();
                 List<string> _role = new List<string>();
                 List<string> _permission = new List<string>();
                 List<string> _permission = new List<string>();
                 var authtoken = context.HttpContext.GetXAuth("AuthToken");
                 var authtoken = context.HttpContext.GetXAuth("AuthToken");
-               
+                var TimeZone = 8;
+                if (context.HttpContext.Request.Headers.TryGetValue("Time-Zone", out StringValues value)  && int.TryParse($"{value}",out int tz)) 
+                {
+                    TimeZone=tz;
+                }
                 if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateAuthToken(authtoken, _option.JwtSecretKey))
                 if (!string.IsNullOrWhiteSpace(authtoken) && JwtAuthExtension.ValidateAuthToken(authtoken, _option.JwtSecretKey))
                 {
                 {
                     var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authtoken);
                     var jwt = new JwtSecurityTokenHandler().ReadJwtToken(authtoken);
@@ -63,6 +69,11 @@ namespace TEAMModelOS.Filter
                     scope = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("scope"))?.Value;
                     scope = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("scope"))?.Value;
                     website = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("website"))?.Value;
                     website = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("website"))?.Value;
                     area = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("area"))?.Value;
                     area = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("area"))?.Value;
+                    timzone = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("timzone"))?.Value;
+                    if (!string.IsNullOrEmpty(timzone)  && int.TryParse(timzone, out int _tz))
+                    {
+                        TimeZone= _tz;
+                    }
                     if (!string.IsNullOrWhiteSpace(_roles))
                     if (!string.IsNullOrWhiteSpace(_roles))
                     {
                     {
                         var roles = jwt.Claims.Where(c => c.Type.Equals("roles"));
                         var roles = jwt.Claims.Where(c => c.Type.Equals("roles"));
@@ -163,6 +174,7 @@ namespace TEAMModelOS.Filter
                         context.HttpContext.Items.Add("Website", website);
                         context.HttpContext.Items.Add("Website", website);
                         context.HttpContext.Items.Add("Area", area);
                         context.HttpContext.Items.Add("Area", area);
                         context.HttpContext.Items.Add("Permissions", _permission);
                         context.HttpContext.Items.Add("Permissions", _permission);
+                        context.HttpContext.Items.Add("TimeZone", TimeZone);
                     }
                     }
                     else {
                     else {
                         context.Result = new BadRequestObjectResult(new { }) { StatusCode = 501 };
                         context.Result = new BadRequestObjectResult(new { }) { StatusCode = 501 };