huanghb 4 月之前
父节点
当前提交
d469ed13bd

+ 57 - 44
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/IndexController.cs

@@ -173,7 +173,7 @@ namespace IES.ExamServer.Controllers
                                 string randomCode = $"{json["randomCode"]}";
                                 string randomCode = $"{json["randomCode"]}";
                                 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
                                 System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12;
 
 
-                                var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/hita/check-login?code={randomCode}&school={school?.id}");
+                                var response = await _httpClientFactory.CreateClient().GetAsync($"{CenterUrl}/core/qrcode/check?code={randomCode}&school={school?.id}");
                                 if (response.IsSuccessStatusCode)
                                 if (response.IsSuccessStatusCode)
                                 {
                                 {
                                     string content = await response.Content.ReadAsStringAsync();
                                     string content = await response.Content.ReadAsStringAsync();
@@ -268,59 +268,72 @@ namespace IES.ExamServer.Controllers
             var type = json["type"];
             var type = json["type"];
             string qrcode = string.Empty;
             string qrcode = string.Empty;
             string randomCode = "";
             string randomCode = "";
-            switch (true)
+            _memoryCache.TryGetValue(Constant._KeyServerDevice, out ServerDevice? server);
+            School? school = null;
+            if (server != null)
             {
             {
-                case bool when $"{type}".Equals("qrcode"):
-                    {
-                        //.NET Core使用SkiaSharp快速生成二维码  https://cloud.tencent.com/developer/article/2336486
-
-                        // 生成二维码图片
-                        Random random = new Random();
-                        randomCode = $"{random.Next(1000, 9999)}";
-                        string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
-                        CenterUrl= CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn":CenterUrl;
-                        string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1";
-                        var  str= QRCodeHelper.GenerateQRCode(content, 300, 300,QRCodeHelper.logo);
-                        qrcode = $"data:image/png;base64,{str}";
-                        return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
-                    }
-                case bool when $"{type}".Equals("xqrcode"):
-                    {
-                        // 生成二维码图片
-                        Random random = new Random();
-                        randomCode = $"{random.Next(1000, 9999)}";
-                        string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
-                        CenterUrl= CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
-                        string content = $"{CenterUrl}/joinSchool?schoolCode=login:{randomCode}&m=%E7%99%BB%E5%BD%95&o=1";
-                        Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200);
-                        using (MemoryStream stream = new MemoryStream())
+                school = server.school;
+            }
+            if (school != null)
+            {
+                switch (true)
+                {
+                    case bool when $"{type}".Equals("qrcode"):
                         {
                         {
-                            qrCodeImage.Save(stream, ImageFormat.Png);
-                            byte[] data = stream.ToArray();
-                            qrcode=$"data:image/png;base64,{Convert.ToBase64String(data)}";
+                            //.NET Core使用SkiaSharp快速生成二维码  https://cloud.tencent.com/developer/article/2336486
+
+                            // 生成二维码图片
+                            Random random = new Random();
+                            randomCode = $"{random.Next(1000, 9999)}";
+                            string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
+                            CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
+                            string content = $"{CenterUrl}/qrcodelogin?code=login:{school?.id}:{randomCode}&m=%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95&o=1";
+                            var str = QRCodeHelper.GenerateQRCode(content, 300, 300, QRCodeHelper.logo);
+                            qrcode = $"data:image/png;base64,{str}";
+                            return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
                         }
                         }
-                        return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
-                    }
-                case bool when $"{type}".Equals("smspin"):
-                    {
-                        int send = 0;
-                        if (!string.IsNullOrWhiteSpace($"{json["area"]}") &&  !string.IsNullOrWhiteSpace($"{json["to"]}"))
+                    case bool when $"{type}".Equals("xqrcode"):
                         {
                         {
+                            // 生成二维码图片
+                            Random random = new Random();
+                            randomCode = $"{random.Next(1000, 9999)}";
                             string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
                             string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
-                            string url = $"{CenterUrl}/core/sendsms/pin";
-                            HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area=json["area"], to = json["to"], lang="zh-cn" });
-                            if (message.IsSuccessStatusCode)
+                            CenterUrl = CenterUrl.Equals("https://localhost:5001") ? "https://www.teammodel.cn" : CenterUrl;
+                            string content = $"{CenterUrl}/qrcodelogin?code=login:{school?.id}:{randomCode}&m=%E6%89%AB%E7%A0%81%E7%99%BB%E5%BD%95&o=1";
+                            Bitmap qrCodeImage = QRCodeHelper.GetBitmap(content, 200, 200);
+                            using (MemoryStream stream = new MemoryStream())
                             {
                             {
-                                string content = await message.Content.ReadAsStringAsync();
-                                JsonNode? jsonNode = content?.ToObject<JsonNode>();
-                                if (jsonNode!=null && int.TryParse($"{jsonNode["send"]}", out int s))
+                                qrCodeImage.Save(stream, ImageFormat.Png);
+                                byte[] data = stream.ToArray();
+                                qrcode = $"data:image/png;base64,{Convert.ToBase64String(data)}";
+                            }
+                            return Ok(new { code = 200, randomCode = randomCode, qrcode, type });
+                        }
+                    case bool when $"{type}".Equals("smspin"):
+                        {
+                            int send = 0;
+                            if (!string.IsNullOrWhiteSpace($"{json["area"]}") && !string.IsNullOrWhiteSpace($"{json["to"]}"))
+                            {
+                                string? CenterUrl = _configuration.GetValue<string>("ExamServer:CenterUrl");
+                                string url = $"{CenterUrl}/core/sendsms/pin";
+                                HttpResponseMessage message = await _httpClientFactory.CreateClient().PostAsJsonAsync(url, new { area = json["area"], to = json["to"], lang = "zh-cn" });
+                                if (message.IsSuccessStatusCode)
                                 {
                                 {
-                                    send = s;
+                                    string content = await message.Content.ReadAsStringAsync();
+                                    JsonNode? jsonNode = content?.ToObject<JsonNode>();
+                                    if (jsonNode != null && int.TryParse($"{jsonNode["send"]}", out int s))
+                                    {
+                                        send = s;
+                                    }
                                 }
                                 }
                             }
                             }
+                            return Ok(new { code = 200, send, type });
                         }
                         }
-                        return Ok(new { code = 200, send, type });
-                    }
+                }
+            }
+            else if (school == null) 
+            {
+                return Ok(new { code = 400,msg="未绑定学校" });
             }
             }
             return Ok(new { code = 400 });
             return Ok(new { code = 400 });
         }
         }

+ 18 - 3
TEAMModelOS.Extension/IES.Exam/IES.ExamServer/Controllers/ManageController.cs

@@ -50,7 +50,7 @@ namespace IES.ExamServer.Controllers
         /// <param name="json"></param>
         /// <param name="json"></param>
         /// <returns></returns>
         /// <returns></returns>
         [HttpPost("clean-cache")]
         [HttpPost("clean-cache")]
-        [AuthToken("admin", "teacher")]
+        [AuthToken("admin", "teacher", "visitor")]
         public async Task<IActionResult> CleanCache(JsonNode json) 
         public async Task<IActionResult> CleanCache(JsonNode json) 
         {
         {
             return Ok();
             return Ok();
@@ -578,7 +578,7 @@ namespace IES.ExamServer.Controllers
         }
         }
 
 
         /// <summary>
         /// <summary>
-        /// 激活考试
+        /// 激活或者取消激活考试
         /// </summary>
         /// </summary>
         /// <param name="json"></param>
         /// <param name="json"></param>
         /// <returns></returns>
         /// <returns></returns>
@@ -588,12 +588,27 @@ namespace IES.ExamServer.Controllers
         {
         {
             string id = $"{json["id"]}";
             string id = $"{json["id"]}";
             string shortCode = $"{json["shortCode"]}";
             string shortCode = $"{json["shortCode"]}";
+            string activateStr = $"{json["activate"]}";
             if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(shortCode)) 
             if (!string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(shortCode)) 
             {
             {
                 EvaluationClient? evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x => x.id!.Equals(id) && !string.IsNullOrWhiteSpace(x.shortCode) && x.shortCode.Equals(shortCode));
                 EvaluationClient? evaluationClient = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().FindOne(x => x.id!.Equals(id) && !string.IsNullOrWhiteSpace(x.shortCode) && x.shortCode.Equals(shortCode));
                 if (evaluationClient != null)
                 if (evaluationClient != null)
                 {
                 {
-
+                    IEnumerable<EvaluationClient> evaluationClients = _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Find(x=>x.activate==1);
+                    if (evaluationClients != null && evaluationClients.Count() > 0) 
+                    {
+                        foreach(EvaluationClient item in evaluationClients)
+                        {
+                            item.activate = 0;
+                            _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Upsert(item);
+                        }
+                    }
+                    int activate = 0;
+                    if (int.TryParse(activateStr, out int _activate)) {
+                        activate = _activate;
+                    }
+                    evaluationClient.activate = activate;
+                    _liteDBFactory.GetLiteDatabase().GetCollection<EvaluationClient>().Upsert(evaluationClient);
                 }
                 }
             }
             }
             return Ok();
             return Ok();

+ 13 - 0
TEAMModelOS.Extension/IES.ExamLib/Models/EvaluationCommon.cs

@@ -146,6 +146,19 @@ namespace IES.ExamServer.Models
         /// 激活状态0未激活,1 激活
         /// 激活状态0未激活,1 激活
         /// </summary>
         /// </summary>
         public int activate { get; set; }
         public int activate { get; set; }
+       
+        /// <summary>
+        /// 倒计时类型 0 未设置,1统一以服务器时间为基准介绍,2,以开始作答为基准,开始作答向局域网端发送请求,返回开始作答时间。
+        /// </summary>
+        public int countdownType {  get; set; }
+        /// <summary>
+        /// 倒计时,时长,按毫秒为单位
+        /// </summary>
+        public long countdown { get; set; }
+        /// <summary>
+        /// 截至时间,countdownType=1 时有值
+        /// </summary>
+        public long deadline {  get; set; }
 
 
     }
     }
     public class SubjectExam
     public class SubjectExam

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

@@ -19,8 +19,8 @@ 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,
-           AzureStorageFactory _azureStorage, Option _option, AzureRedisFactory _azureRedis, string ip, HttpTrigger _httpTrigger, string lang,int timezone)
+        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, int timezone, string school = null)
         {
         {
             Teacher teacher = null;
             Teacher teacher = null;
             string defaultschool = null;
             string defaultschool = null;
@@ -180,7 +180,7 @@ namespace TEAMModelOS.Services
             //catch { }
             //catch { }
 
 
             //換取AuthToken,提供給前端
             //換取AuthToken,提供給前端
-            var auth_token = JwtAuthExtension.CreateAuthToken(_option.HostName, id, name?.ToString(), picture?.ToString(), _option.JwtSecretKey, Website: "IES", timezone: timezone, scope: Constant.ScopeTeacher,schoolID: defaultschool, 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,schoolID:!string.IsNullOrWhiteSpace(school)? school: defaultschool, 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私有容器,如存在則不做任何事,保障容器一定存在

+ 1 - 1
TEAMModelOS/Controllers/Client/HiTAControlller.cs

@@ -121,7 +121,7 @@ namespace TEAMModelOS.Controllers.Client
                     var jwt = new JwtSecurityToken(join.id_token);
                     var jwt = new JwtSecurityToken(join.id_token);
                     //await _dingDing.SendBotMsg(join.ToJsonString(), GroupNames.成都开发測試群組);
                     //await _dingDing.SendBotMsg(join.ToJsonString(), GroupNames.成都开发測試群組);
                     var id = jwt.Payload.Sub;
                     var id = jwt.Payload.Sub;
-                    await _azureRedis.GetRedisClient(8).StringSetAsync($"HiTA:Login:{join.school.Replace("login:", "")}", id, expiry: new TimeSpan(0, 0, 10));
+                    await _azureRedis.GetRedisClient(8).StringSetAsync($"HiTA:Login:{join.school.Replace("login:", "")}", id, expiry: new TimeSpan(0, 0, 30));
                     return Ok(new { name = ",关闭弹窗以获取登录信息", school = "tmd" });
                     return Ok(new { name = ",关闭弹窗以获取登录信息", school = "tmd" });
                 }
                 }
                 if (!string.IsNullOrWhiteSpace(join.id_token) && !string.IsNullOrWhiteSpace(join.school))
                 if (!string.IsNullOrWhiteSpace(join.id_token) && !string.IsNullOrWhiteSpace(join.school))

+ 291 - 7
TEAMModelOS/Controllers/System/CoreController.cs

@@ -45,6 +45,8 @@ using static TEAMModelOS.SDK.CoreAPIHttpService;
 using Pipelines.Sockets.Unofficial.Arenas;
 using Pipelines.Sockets.Unofficial.Arenas;
 using System.Text.Json.Nodes;
 using System.Text.Json.Nodes;
 using TEAMModelOS.Services;
 using TEAMModelOS.Services;
+using static TEAMModelOS.Controllers.Client.HiTAControlller;
+using DocumentFormat.OpenXml.Office2010.Excel;
 
 
 namespace TEAMModelOS.Controllers
 namespace TEAMModelOS.Controllers
 {
 {
@@ -412,6 +414,197 @@ namespace TEAMModelOS.Controllers
             }
             }
         }
         }
         /// <summary>
         /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="json"></param>
+        /// <returns></returns>
+        [ProducesDefaultResponseType]
+        [HttpPost("qrcode/login")]
+        //[Authorize(Roles = "HiTA")]
+        public async Task<IActionResult> SchoolJoin(HiTAJoinSchool join)
+        {
+            try
+            {
+                Dictionary<string, object> dict = new Dictionary<string, object>();
+                Dictionary<string, object> qure = new Dictionary<string, object>();
+                foreach (var a in HttpContext.Request.Query)
+                {
+                    qure.Add(a.Key, a.Value);
+                }
+                foreach (var a in HttpContext.Request.Headers)
+                {
+                    dict.Add(a.Key, a.Value);
+                }
+                //await _dingDing.SendBotMsg(join.ToJsonString()+ dict.ToJsonString(), GroupNames.成都开发測試群組);
+
+                if (!string.IsNullOrWhiteSpace(join.id_token) && !string.IsNullOrWhiteSpace(join.school) && join.school.Contains("login:"))
+                {
+                    var jwt = new JwtSecurityToken(join.id_token);
+                    //await _dingDing.SendBotMsg(join.ToJsonString(), GroupNames.成都开发測試群組);
+                    var id = jwt.Payload.Sub;
+                    await _azureRedis.GetRedisClient(8).StringSetAsync($"HiTA:Login:{join.school.Replace("login:", "")}", id, expiry: new TimeSpan(0, 0, 30));
+                    return Ok(new { name = "关闭弹窗以获取登录信息" });
+                }
+                else { return Ok(new { error = 400, msg = "参数错误" }); }
+                
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"{ex.Message},{ex.StackTrace}", GroupNames.成都开发測試群組);
+                return Ok(new { error = 400, msg = "参数错误" });
+            }
+        }
+
+        [ProducesDefaultResponseType]
+        [HttpGet("qrcode/check")]
+        public async Task<IActionResult> QRCodeCheck([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;
+            }
+            string tmdid = string.Empty;
+            string school = join.school;
+            if (!string.IsNullOrWhiteSpace(join.code)&& !string.IsNullOrWhiteSpace(school))
+            {
+                
+                var data = await _azureRedis.GetRedisClient(8).StringGetAsync($"HiTA:Login:{school}:{join.code}");
+                if (data.HasValue)
+                {
+                    tmdid = data.ToString();
+                }
+            }
+
+            if (!string.IsNullOrWhiteSpace(tmdid))
+            {
+                var location = _option.Location;
+                var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                TmdidImplicit implicit_token = await _coreAPIHttpService.Implicit(new Dictionary<string, string>()
+                        {
+                        { "grant_type", "implicit" },
+                        { "client_id",clientID },
+                        { "account",tmdid },
+                        { "nonce",Guid.NewGuid().ToString()}
+                        }, location, _configuration);
+                IEnumerable<dynamic> schools = new List<dynamic>();
+               
+                object name = null, picture = null;
+                var jwt = new JwtSecurityToken(implicit_token.id_token);
+                jwt.Payload.TryGetValue("name", out name);
+                jwt.Payload.TryGetValue("picture", out picture);
+                jwt.Payload.TryGetValue("lang", out object _jwtlang);
+
+                School schoolBase = null;
+                if (!string.IsNullOrWhiteSpace(school))
+                {
+                    ResponseMessage responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(school, new PartitionKey("Base"));
+                    if (responseSchool.IsSuccessStatusCode)
+                    {
+                        schoolBase = JsonDocument.Parse(responseSchool.Content).RootElement.ToObject<School>();
+                    }
+                }
+                Teacher teacher = null;
+                ResponseMessage response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey("Base"));
+                if (response.IsSuccessStatusCode)
+                {
+                    teacher = JsonDocument.Parse(response.Content).RootElement.ToObject<Teacher>();
+                    if (schoolBase != null)
+                    {
+                        // teacher.defaultSchool = school;
+                        var sch = teacher.schools.Find(x => x.schoolId.Equals(school));
+                        if (sch == null)
+                        {
+                            teacher.schools.Add(new Teacher.TeacherSchool
+                            {
+                                areaId = schoolBase.areaId,
+                                schoolId = schoolBase.id,
+                                status = "join",
+                                name = schoolBase.name,
+                                picture = schoolBase.picture,
+                                roles = new List<string> { "teacher" },
+                                time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                            });
+                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<Teacher>(teacher, new PartitionKey("Base"));
+                        }
+                    }
+                    schools = teacher.schools.Where(x => x.status.Equals("join")).Select(x => new { id = x.schoolId, name = x.name, picture = x.picture });
+                }
+                else
+                {
+
+                    //如果沒有,則初始化Teacher基本資料到Cosmos
+                    teacher = new Teacher
+                    {
+                        createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                        id = tmdid,
+                        pk = "Base",
+                        code = "Base",
+                        name = name?.ToString(),
+                        picture = picture?.ToString(),
+                        //创建账号并第一次登录IES5则默认赠送1G
+                        size = 1,
+                        defaultSchool = null,
+                        schools = new List<Teacher.TeacherSchool>(),
+                        lang = "zh-cn",
+                        timezone = timezone,
+                    };
+                    if (schoolBase != null)
+                    {
+                        teacher.defaultSchool = school;
+                        teacher.schools.Add(new Teacher.TeacherSchool
+                        {
+                            areaId = schoolBase.areaId,
+                            schoolId = schoolBase.id,
+                            status = "join",
+                            name = schoolBase.name,
+                            picture = schoolBase.picture,
+                            roles = new List<string> { "teacher" },
+                            time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                        });
+                    }
+                    var container = _azureStorage.GetBlobContainerClient(tmdid);
+                    await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
+                    teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
+                }
+                if (schoolBase != null)
+                {
+                    school = schoolBase.id;
+                    ResponseMessage responseTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(tmdid, new PartitionKey($"Teacher-{school}"));
+                    if (!responseTeacher.IsSuccessStatusCode)
+                    {
+                        SchoolTeacher schoolTeacher = new SchoolTeacher
+                        {
+                            id = tmdid,
+                            code = $"Teacher-{school}",
+                            name = teacher.name,
+                            picture = teacher.picture,
+                            status = "join",
+                            pk = "Teacher",
+                            roles = new List<string> { "teacher" },
+                            ttl = -1,
+                            periodId = schoolBase.period.FirstOrDefault()?.id,
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                        };
+                        await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(schoolTeacher, new PartitionKey($"Teacher-{school}"));
+                    }
+                }
+                else
+                {
+                    school = null;
+                }
+                (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}", timezone,school);
+                string x_auth_token = string.Empty;
+                if (teacherInfo != null)
+                {
+                    x_auth_token = teacherInfo.auth_token;
+                }
+                return Ok(new { code = 200, implicit_token, schools, x_auth_token });
+            }
+            return Ok(new { code = 400 });
+        }
+        /// <summary>
         ///{"grant_type":"create","client_id":"c7317f88-7cea-4e48-ac57-a16071f7b884","nonce":"habook","name":"User","pin_code":"985395","account":"+86-15283771540"}
         ///{"grant_type":"create","client_id":"c7317f88-7cea-4e48-ac57-a16071f7b884","nonce":"habook","name":"User","pin_code":"985395","account":"+86-15283771540"}
         ///{"error":2,"message":"帳號已存在"}
         ///{"error":2,"message":"帳號已存在"}
         ///{"error":3,"message":"驗證PIN碼失敗"}
         ///{"error":3,"message":"驗證PIN碼失敗"}
@@ -436,6 +629,7 @@ namespace TEAMModelOS.Controllers
             }
             }
             var pin_code = request["pin_code"];
             var pin_code = request["pin_code"];
             var account = request["account"];
             var account = request["account"];
+            var school = $"{request["school"]}";
             TmdidImplicit implicit_token = null;
             TmdidImplicit implicit_token = null;
             var loginData= await _coreAPIHttpService.Auth2Login($"{pin_code}", $"{account}", _option.Location, _configuration, _dingDing);
             var loginData= await _coreAPIHttpService.Auth2Login($"{pin_code}", $"{account}", _option.Location, _configuration, _dingDing);
             if (loginData.code.Equals(HttpStatusCode.OK))
             if (loginData.code.Equals(HttpStatusCode.OK))
@@ -470,7 +664,7 @@ namespace TEAMModelOS.Controllers
                         msg=$"验证失败!{loginData.content}";
                         msg=$"验证失败!{loginData.content}";
                     }
                     }
                 }
                 }
-                if (implicit_token!=null)
+                if (implicit_token != null)
                 {
                 {
                     object name = null, picture = null;
                     object name = null, picture = null;
                     var jwt = new JwtSecurityToken(implicit_token.id_token);
                     var jwt = new JwtSecurityToken(implicit_token.id_token);
@@ -479,15 +673,104 @@ namespace TEAMModelOS.Controllers
                     jwt.Payload.TryGetValue("lang", out object _jwtlang);
                     jwt.Payload.TryGetValue("lang", out object _jwtlang);
                     var tmdid = jwt.Payload.Sub;
                     var tmdid = jwt.Payload.Sub;
                     IEnumerable<dynamic> schools = new List<dynamic>();
                     IEnumerable<dynamic> schools = new List<dynamic>();
-                    var response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey("Base"));
-                    if (response.StatusCode==System.Net.HttpStatusCode.OK)
+                    School schoolBase = null;
+                    if (!string.IsNullOrWhiteSpace(school))
+                    {
+                        ResponseMessage responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(school, new PartitionKey("Base"));
+                        if (responseSchool.IsSuccessStatusCode)
+                        {
+                             schoolBase = JsonDocument.Parse(responseSchool.Content).RootElement.ToObject<School>();
+                        }
+                    }
+                    Teacher teacher = null;
+                    ResponseMessage response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemStreamAsync(tmdid, new PartitionKey("Base"));
+                    if (response.IsSuccessStatusCode)
                     {
                     {
-                        Teacher teacher = JsonDocument.Parse(response.Content).RootElement.ToObject<Teacher>();
-                        schools= teacher.schools.Where(x => x.status.Equals("join")).Select(x => new { id = x.schoolId, name = x.name, picture = x.picture });
+                        teacher = JsonDocument.Parse(response.Content).RootElement.ToObject<Teacher>();
+                        if (schoolBase != null) 
+                        {
+                           // teacher.defaultSchool = school;
+                            var sch = teacher.schools.Find(x => x.schoolId.Equals(school));
+                            if (sch == null)
+                            {
+                                teacher.schools.Add(new Teacher.TeacherSchool
+                                {
+                                    areaId = schoolBase.areaId,
+                                    schoolId = schoolBase.id,
+                                    status = "join",
+                                    name = schoolBase.name,
+                                    picture = schoolBase.picture,
+                                    roles = new List<string> { "teacher" },
+                                    time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                                });
+                                await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<Teacher>(teacher, new PartitionKey("Base"));
+                            }
+                        }
+                        schools = teacher.schools.Where(x => x.status.Equals("join")).Select(x => new { id = x.schoolId, name = x.name, picture = x.picture });
                     }
                     }
+                    else {
 
 
+                        //如果沒有,則初始化Teacher基本資料到Cosmos
+                        teacher = new Teacher
+                        {
+                            createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
+                            id = tmdid,
+                            pk = "Base",
+                            code = "Base",
+                            name = name?.ToString(),
+                            picture = picture?.ToString(),
+                            //创建账号并第一次登录IES5则默认赠送1G
+                            size = 1,
+                            defaultSchool = null,
+                            schools = new List<Teacher.TeacherSchool>() ,
+                            lang = "zh-cn",
+                            timezone = timezone,
+                        };
+                        if (schoolBase != null)
+                        {
+                            teacher.defaultSchool = school;
+                            teacher.schools.Add(new Teacher.TeacherSchool
+                            {
+                                areaId = schoolBase.areaId,
+                                schoolId = schoolBase.id,
+                                status = "join",
+                                name = schoolBase.name,
+                                picture = schoolBase.picture,
+                                roles = new List<string> { "teacher" },
+                                time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                            });
+                        }
+                        var container = _azureStorage.GetBlobContainerClient(tmdid);
+                        await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
+                        teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
+                    }
+                    if (schoolBase != null)
+                    {
+                        school = schoolBase.id;
+                        ResponseMessage responseTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(tmdid, new PartitionKey($"Teacher-{school}"));
+                        if (!responseTeacher.IsSuccessStatusCode)
+                        {
+                            SchoolTeacher schoolTeacher = new SchoolTeacher
+                            {
+                                id = tmdid,
+                                code = $"Teacher-{school}",
+                                name = teacher.name,
+                                picture = teacher.picture,
+                                status = "join",
+                                pk = "Teacher",
+                                roles = new List<string> { "teacher" },
+                                ttl = -1,
+                                periodId = schoolBase.period.FirstOrDefault()?.id,
+                                createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
+                            };
+                            await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).UpsertItemAsync(schoolTeacher, new PartitionKey($"Teacher-{school}"));
+                        }
+                    }
+                    else {
+                        school =null;
+                    }
                     (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}", timezone);
+                    TeacherInfo teacherInfo = await TeacherService.TeacherInfoLite(_azureCosmos, $"{name}", $"{picture}", $"{jwt.Payload.Sub}", _azureStorage, _option, _azureRedis, "", _httpTrigger, $"{_jwtlang}", timezone,school);
                     string x_auth_token = string.Empty;
                     string x_auth_token = string.Empty;
                     if (teacherInfo!=null)
                     if (teacherInfo!=null)
                     {
                     {
@@ -1003,7 +1286,8 @@ namespace TEAMModelOS.Controllers
     }
     }
 
 
 
 
-
+    public class QRCodeLoginCheck
+    { }
     public record ApplySchool
     public record ApplySchool
     {
     {
         /// <summary>
         /// <summary>