Преглед изворни кода

調整學習記錄共用的寫法

upon пре 1 година
родитељ
комит
54e08976a9

+ 4 - 21
TEAMModelOS.SDK/DI/AzureCosmos/AzureCosmosFactory.cs

@@ -10,10 +10,9 @@ namespace TEAMModelOS.SDK.DI
     {
         private readonly IServiceProvider _services;
         private readonly IOptionsMonitor<AzureCosmosFactoryOptions> _optionsMonitor;
-        private static  IOptionsMonitor<AzureCosmosFactoryOptions> _optionsMonitorStatic;
+        
         //private Option _option;
-        private ConcurrentDictionary<string, CosmosClient> CosmosClients { get; } = new ConcurrentDictionary<string, CosmosClient>();
-        private static ConcurrentDictionary<string, CosmosClient> CosmosClientsStatic { get; } = new ConcurrentDictionary<string, CosmosClient>();
+        private ConcurrentDictionary<string, CosmosClient> CosmosClients { get; } = new ConcurrentDictionary<string, CosmosClient>();        
 
         //   private CosmosDatabase database { get; set; }
 
@@ -23,8 +22,7 @@ namespace TEAMModelOS.SDK.DI
             if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
 
             _services = services;
-            _optionsMonitor = optionsMonitor;
-            _optionsMonitorStatic = optionsMonitor;
+            _optionsMonitor = optionsMonitor;            
         }
 
         /// <summary>
@@ -46,22 +44,7 @@ namespace TEAMModelOS.SDK.DI
             {
                 return null;
             }
-        }
-
-        public static CosmosClient GetCosmosClientStatic(string region = null, string name = "Default")
-        {
-            try
-            {
-                //CosmosClientOptions 的 SerializerOptions = new CosmosSerializationOptions() { PropertyNamingPolicy = CosmosPropertyNamingPolicy.CamelCase } 
-                //需等待官方修正
-                var cm = CosmosClientsStatic.GetOrAdd(name, x => new CosmosClient(_optionsMonitorStatic.Get(name).CosmosConnectionString, new CosmosClientOptions() { ApplicationRegion = region }));
-                return cm;
-            }
-            catch (Exception e)
-            {
-                return null;
-            }
-        }
+        }        
 
     }
 }

+ 3 - 17
TEAMModelOS.SDK/DI/AzureStorage/AzureStorageFactory.cs

@@ -22,16 +22,14 @@ namespace TEAMModelOS.SDK.DI
     public class AzureStorageFactory
     {
         private readonly IServiceProvider _services;
-        private readonly IOptionsMonitor<AzureStorageFactoryOptions> _optionsMonitor;
-        private static IOptionsMonitor<AzureStorageFactoryOptions> _optionsMonitorStatic;
+        private readonly IOptionsMonitor<AzureStorageFactoryOptions> _optionsMonitor;        
         public AzureStorageFactory(IServiceProvider services, IOptionsMonitor<AzureStorageFactoryOptions> optionsMonitor)
         {
             if (services == null) throw new ArgumentNullException(nameof(services));
             if (optionsMonitor == null) throw new ArgumentNullException(nameof(optionsMonitor));
 
             _services = services;
-            _optionsMonitor = optionsMonitor;
-            _optionsMonitorStatic = optionsMonitor;
+            _optionsMonitor = optionsMonitor;            
         }
 
         public BlobServiceClient GetBlobServiceClient(string name = "Default")
@@ -59,19 +57,7 @@ namespace TEAMModelOS.SDK.DI
             {
                 return null;
             }
-        }
-        public static BlobContainerClient GetBlobContainerClientStatic(string containerName, string name = "Default")
-        {
-            try
-            {
-                var options = _optionsMonitorStatic.Get(name);
-                return new BlobContainerClient(options.StorageAccountConnectionString, containerName.ToLower());
-            }
-            catch (OptionsValidationException e)
-            {
-                return null;
-            }
-        }
+        }        
 
         public BlobBatchClient GetBlobBatchClient(string name = "Default")
         {

+ 4 - 347
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -142,7 +142,7 @@ namespace TEAMModelOS.Controllers.Client
                 messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
                 //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} 更新事件,{msg}", GroupNames.醍摩豆服務運維群組);
                 await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
-                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope);
+                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope, _azureCosmos, _azureStorage);
                 return Ok(new { status = 200 });
             }
             catch (CosmosException ex) when (ex.Status == 404)
@@ -595,7 +595,7 @@ namespace TEAMModelOS.Controllers.Client
                 if (!request.TryGetProperty("tmdid", out JsonElement _tmdid)) return BadRequest();
                 request.TryGetProperty("school", out JsonElement _school);
 
-                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope);
+                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope, _azureCosmos, _azureStorage);
 
                 return Ok(new { status = 200 });
             }
@@ -622,7 +622,7 @@ namespace TEAMModelOS.Controllers.Client
                 request.TryGetProperty("school", out JsonElement _school);
                 request.TryGetProperty("scope", out JsonElement _scope);
 
-                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope, false);
+                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope, _azureCosmos, _azureStorage, false);
 
                 return Ok(new { status = 200 });
             }
@@ -631,350 +631,7 @@ namespace TEAMModelOS.Controllers.Client
                 return BadRequest();
             }
         }
-
-        /// <summary>
-        /// 設定及儲存學習紀錄
-        /// </summary>
-        /// <param name="_school"></param>
-        /// <param name="_tmdid"></param>
-        /// <param name="_lessonId"></param>
-        /// <param name="_scope"></param>
-        /// <returns></returns>
-        private async Task SetLearnRecordContentbak(JsonElement _school, JsonElement _tmdid, JsonElement _lessonId, JsonElement _scope, bool _isIES = true)
-        {
-            try
-            {
-                var client = _azureCosmos.GetCosmosClient();
-                string school = $"{_school}";
-                string tmdid = _tmdid.GetString();
-                string lessonId = _lessonId.GetString();
-                string rootName = "";
-                List<LearnRecordItem> learnRecordItems = new List<LearnRecordItem>();
-
-                // 判斷個人或是學校課堂以及是否為本地課程  來取blob的容器位置
-                if (_scope.ValueKind == JsonValueKind.Undefined)
-                {// 本地課堂
-                    rootName = tmdid;
-                }
-                else
-                {
-                    if (_scope.GetString().Equals("school") && !string.IsNullOrWhiteSpace(_school.GetString()))
-                    {// 學校課堂
-                        rootName = school;
-                    }
-                    else if ($"{_scope}".Equals("private"))
-                    {// 個人課堂
-                        rootName = tmdid;
-                    }
-                }
-
-                // 本地路徑 1524738018 / temp / records / 1334aa30868520170580732778614850743
-                string blobTimeLineUrl = "";
-                string blobIRSUrl = "";
-                string blobbaseUrl = "";
-                string blobTaskUrl = "";
-                // 處理資料是由IES5或是hiteach本地來的邏輯
-                if (_isIES)
-                {
-                    blobTimeLineUrl = $"/records/{lessonId}/IES/TimeLine.json";
-                    blobIRSUrl = $"/records/{lessonId}/IES/IRS.json";
-                    blobbaseUrl = $"/records/{lessonId}/IES/base.json";
-                    blobTaskUrl = $"/records/{lessonId}/IES/Task.json";
-                }
-                else
-                {
-                    blobTimeLineUrl = $"/temp/records/{lessonId}/IES/TimeLine.json";
-                    blobIRSUrl = $"/temp/records/{lessonId}/IES/IRS.json";
-                    blobbaseUrl = $"/temp/records/{lessonId}/IES/base.json";
-                    blobTaskUrl = $"/temp/records/{lessonId}/IES/Task.json";
-                }
-                // 檢查 TimeLine 是否存在blob
-                if (_azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTimeLineUrl).Exists() &&
-                    _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobIRSUrl).Exists() &&
-                    _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobbaseUrl).Exists())
-                {
-                    // 開啟 base.json
-                    BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobbaseUrl).DownloadContentAsync();
-                    ScoreLessonBase lessonBase = baseblobDownload.Content.ToObjectFromJson<ScoreLessonBase>();
-                    //取得學校學生名單                    
-                    List<string> stuIdForSql = new List<string>();
-                    if (lessonBase.student.Count > 0)
-                    {
-                        foreach (LessonStudent stu in lessonBase.student)
-                        {
-                            if (!string.IsNullOrWhiteSpace(stu.id) && !stuIdForSql.Contains(stu.id))
-                            {
-                                stuIdForSql.Add(stu.id);
-                            }
-                        }
-                    }
-
-                    // 開啟 TimeLine.json
-                    BlobDownloadResult TimeLineblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTimeLineUrl).DownloadContentAsync();
-                    TimeLineEvents timeLineEvents = TimeLineblobDownload.Content.ToObjectFromJson<TimeLineEvents>();
-
-                    // 開啟 IRS.json
-                    BlobDownloadResult IRSblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobIRSUrl).DownloadContentAsync();
-                    List<IRSItem> iRSItems = IRSblobDownload.Content.ToObjectFromJson<List<IRSItem>>();
-
-                    // 開啟 Task.json
-                    BlobDownloadResult taskblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTaskUrl).DownloadContentAsync();
-                    List<TaskItem> taskItems = taskblobDownload.Content.ToObjectFromJson<List<TaskItem>>();
-                    if (timeLineEvents.events.Count > 0)
-                    {
-
-                        for (int i = 0; i < timeLineEvents.events.Count; i++)
-                        {
-                            switch (timeLineEvents.events[i].Event)
-                            {
-                                // 互動
-                                case "PopQuesLoad":
-                                case "QuesLoad":
-                                    for (int j = 0; j < iRSItems.Count; j++)
-                                    {
-                                        if (timeLineEvents.events[i].Pgid == iRSItems[j].pageID) // 比對 Pgid 找到 IRS.json 該活動的詳細資料
-                                        {
-                                            switch (iRSItems[j].question.exercise.type)
-                                            {
-                                                // 單選
-                                                case "single":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSingle", learnRecordItems);
-                                                    break;
-                                                // 複選
-                                                case "multiple":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsMultiple", learnRecordItems);
-                                                    break;
-                                                // 是非
-                                                case "judge":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsJudge", learnRecordItems);
-                                                    break;
-                                                // 填充
-                                                case "complete":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsComplete", learnRecordItems);
-                                                    break;
-                                                // 問答
-                                                case "subjective":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSubjective", learnRecordItems);
-                                                    break;
-                                            }
-                                        }
-                                    }
-                                    break;
-                                // 搶權
-                                case "BuzrAns":
-                                    for (int j = 0; j < iRSItems.Count; j++)
-                                    {
-                                        if (timeLineEvents.events[i].Pgid == iRSItems[j].pageID && iRSItems[j].isBuzz) // 比對 Pgid 找到 IRS.json 該活動的詳細資料
-                                        {
-                                            for (int k = 0; k < iRSItems[j].buzzClients.Count; k++)
-                                            {
-                                                LearnRecordItem learnRecordItem = new();
-                                                for (int m = 0; m < lessonBase.student.Count; m++)
-                                                {// 比對學生座號 取學號
-                                                    if (lessonBase.student[m].seatID.ToString() == iRSItems[j].buzzClients[k])
-                                                    {
-                                                        if (lessonBase.student[k].type == 2)
-                                                        {// 校內帳號
-                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
-                                                        }
-                                                        else
-                                                        {// 非校內帳號
-                                                            learnRecordItem.actor = setActor(school, lessonBase.student[k].id);
-                                                        }
-                                                    }
-                                                }
-                                                string[] arrymd = lessonBase.summary.date.Split('.');
-                                                string[] arrhms = lessonBase.summary.startTime.Split(':');
-                                                DateTime dt = new DateTime(int.Parse(arrymd[0]), int.Parse(arrymd[1]), int.Parse(arrymd[2]), int.Parse(arrhms[0]), int.Parse(arrhms[1]), int.Parse(arrhms[2]));
-                                                dt = dt.AddSeconds(timeLineEvents.events[i].Time);
-                                                learnRecordItem.verb = "AnsBuzzin";
-                                                learnRecordItem.time = dt.ToUnixTimestamp();
-                                                learnRecordItem.ID = timeLineEvents.events[i].Pgid;
-                                                if (iRSItems[j].question.item[0].question == "_popquiz_" || iRSItems[j].question.item[0].question == "")
-                                                {
-                                                    learnRecordItem.Desc = "隨堂問答";
-                                                }
-                                                else
-                                                {
-                                                    learnRecordItem.Desc = iRSItems[j].question.item[0].question;
-                                                }
-                                                learnRecordItem.Points = iRSItems[j].question.exercise.knowledges;
-
-                                                await setCorrectChoices(iRSItems[j], learnRecordItem);
-                                                learnRecordItem.ExamQuesQty = null;
-                                                learnRecordItem.TotalScore = null;
-                                                learnRecordItem.Success = null;
-                                                learnRecordItems.Add(learnRecordItem);
-                                            }
-                                        }
-                                    }
-                                    break;
-                                // 上傳作品
-                                case "WrkSpaceLoad":
-                                    for (int j = 0; j < taskItems.Count; j++)
-                                    {
-                                        if (timeLineEvents.events[i].Pgid == taskItems[j].pageID) // 比對 Pgid 找到 IRS.json 該活動的詳細資料
-                                        {
-                                            for (int k = 0; k < taskItems[j].clientWorks.Count; k++)
-                                            {
-                                                LearnRecordItem learnRecordItem = new();
-                                                for (int m = 0; m < lessonBase.student.Count; m++)
-                                                {// 比對學生座號 取學號
-                                                    if (lessonBase.student[m].seatID == taskItems[j].clientWorks[k].seatID)
-                                                    {
-                                                        if (lessonBase.student[k].type == 2)
-                                                        {// 校內帳號
-                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
-                                                        }
-                                                        else
-                                                        {// 非校內帳號
-                                                            learnRecordItem.actor = setActor(school, lessonBase.student[k].id);
-                                                        }
-                                                    }
-                                                }
-
-                                                string[] arrymd = lessonBase.summary.date.Split('.');
-                                                string[] arrhms = taskItems[j].clientWorks[k].reciveTime.Split(':');
-                                                DateTime dt = new DateTime(int.Parse(arrymd[0]), int.Parse(arrymd[1]), int.Parse(arrymd[2]), int.Parse(arrhms[0]), int.Parse(arrhms[1]), int.Parse(arrhms[2]));
-                                                dt = dt.AddSeconds(timeLineEvents.events[i].Time);
-                                                learnRecordItem.verb = "SubmitTask";
-                                                learnRecordItem.time = dt.ToUnixTimestamp();
-                                                learnRecordItem.ID = timeLineEvents.events[i].Pgid;
-                                                learnRecordItem.Desc = "隨堂作品";
-                                                learnRecordItem.Correct = null;
-                                                learnRecordItem.Choices = null;
-                                                learnRecordItem.ExamQuesQty = null;
-                                                learnRecordItem.TotalScore = null;
-                                                learnRecordItem.Success = null;
-
-                                                learnRecordItems.Add(learnRecordItem);
-                                            }
-                                        }
-                                    }
-                                    break;
-                                case "FastPgPush":
-                                    for (int k = 0; k < lessonBase.student.Count; k++)
-                                    {
-                                        LearnRecordItem learnRecordItem = new();
-                                        for (int m = 0; m < lessonBase.student.Count; m++)
-                                        {// 比對學生座號 取學號
-
-                                            if (lessonBase.student[k].type == 2)
-                                            {
-                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
-                                            }
-                                            else
-                                            {// 非校內帳號
-                                                learnRecordItem.actor = setActor(school, lessonBase.student[k].id);
-                                            }
-                                        }
-
-                                        string[] arrymd = lessonBase.summary.date.Split('.');
-                                        string[] arrhms = lessonBase.summary.startTime.Split(':');
-                                        DateTime dt = new DateTime(int.Parse(arrymd[0]), int.Parse(arrymd[1]), int.Parse(arrymd[2]), int.Parse(arrhms[0]), int.Parse(arrhms[1]), int.Parse(arrhms[2]));
-                                        dt = dt.AddSeconds(timeLineEvents.events[i].Time);
-                                        learnRecordItem.verb = "ViewPage";
-                                        learnRecordItem.time = dt.ToUnixTimestamp();
-                                        learnRecordItem.ID = timeLineEvents.events[i].Pgid;
-                                        learnRecordItem.Desc = $"https://www.teammodel.net/viewpage?id={timeLineEvents.events[i].Pgid}";
-                                        learnRecordItem.Correct = null;
-                                        learnRecordItem.Choices = null;
-                                        learnRecordItem.ExamQuesQty = null;
-                                        learnRecordItem.TotalScore = null;
-                                        learnRecordItem.Success = null;
-
-                                        learnRecordItems.Add(learnRecordItem);
-                                    }
-                                    break;
-                                case "ActStart":
-                                case "ActEnd":
-                                    for (int k = 0; k < lessonBase.student.Count; k++)
-                                    {
-                                        LearnRecordItem learnRecordItem = new();
-                                        for (int m = 0; m < lessonBase.student.Count; m++)
-                                        {// 比對學生座號 取學號
-
-                                            if (lessonBase.student[k].type == 2)
-                                            {
-                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
-                                            }
-                                            else
-                                            {// 非校內帳號
-                                                learnRecordItem.actor = setActor(school, lessonBase.student[k].id);
-                                            }
-                                        }
-                                        string[] arrymd = lessonBase.summary.date.Split('.');
-                                        string[] arrhms = lessonBase.summary.startTime.Split(':');
-                                        DateTime dt = new DateTime(int.Parse(arrymd[0]), int.Parse(arrymd[1]), int.Parse(arrymd[2]), int.Parse(arrhms[0]), int.Parse(arrhms[1]), int.Parse(arrhms[2]));
-                                        dt = dt.AddSeconds(timeLineEvents.events[i].Time);
-                                        if (timeLineEvents.events[i].Event == "ActStart") { learnRecordItem.verb = "StartExam"; }
-                                        if (timeLineEvents.events[i].Event == "ActEnd") { learnRecordItem.verb = "EndExam"; }
-                                        learnRecordItem.time = dt.ToUnixTimestamp();
-                                        learnRecordItem.ID = lessonId;
-                                        learnRecordItem.Desc = lessonBase.summary.activityName;
-                                        learnRecordItem.Correct = null;
-                                        learnRecordItem.Choices = null;
-                                        learnRecordItem.ExamQuesQty = 0;
-                                        foreach (var item in timeLineEvents.events)
-                                        {
-                                            if (item.Event == "PopQuesLoad" || item.Event == "QuesLoad" || item.Event == "BuzrAns")
-                                            {
-                                                learnRecordItem.ExamQuesQty = learnRecordItem.ExamQuesQty + 1;
-                                            }
-                                        }
-                                        learnRecordItem.TotalScore = learnRecordItem.ExamQuesQty * 10;
-                                        learnRecordItem.Success = null;
-
-                                        learnRecordItems.Add(learnRecordItem);
-                                    }
-                                    break;
-
-
-                                // 測驗
-                                case "SPQStrt":
-                                    //// 開啟 .json
-                                    //BlobDownloadResult taskblobDownload = await _azureStorage.GetBlobContainerClient(school).GetBlobClient($"/records/{lessonId}/IES/Task.json").DownloadContentAsync();
-                                    //List<TaskItem> taskItems = taskblobDownload.Content.ToObjectFromJson<List<TaskItem>>();
-
-                                    break;
-                            }
-                        }
-
-
-                    }
-
-                    #region 寫入blob
-
-                    // 容器名称
-                    string containerName = "twmoeld";
-
-                    // 新文件的名称
-                    string blobName = $"/{DateTime.Now.ToString("yyyyMMdd")}/{lessonId}.json";                    
-
-                    // 要上传的文件内容
-                    string fileContent = Newtonsoft.Json.JsonConvert.SerializeObject(learnRecordItems);
-
-                    // 获取容器引用
-                    BlobContainerClient containerClient = _azureStorage.GetBlobContainerClient(containerName);
-
-                    // 获取 Blob 客户端
-                    BlobClient blobClient = containerClient.GetBlobClient(blobName);
-
-                    // 将文件内容上传到 Blob
-                    using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(fileContent)))
-                    {
-                        await blobClient.UploadAsync(stream, true);
-                    }
-
-                    #endregion
-
-                }
-            }
-            catch (Exception ex)
-            {
-
-            }
-        }
+      
 
         private async Task SetLearnRecordContentForBatch(string _school, string _tmdid, string _lessonId, string _scope, string htype, bool _isIES = true)
         {

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

@@ -335,7 +335,7 @@ namespace TEAMModelOS.Controllers.Client
                 messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
                 //await _dingDing.SendBotMsg($"{_option.Location},课堂id:{_lessonId} 更新事件,{msg}", GroupNames.醍摩豆服務運維群組);
                 await _serviceBus.GetServiceBusClient().SendMessageAsync(ActiveTask, messageChange);
-                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope);
+                await LessonServiceIES.SetLearnRecordContent(_school, _tmdid, _lessonId, _scope, _azureCosmos, _azureStorage);
                 return Ok(new { status = 200 });
             }
             catch (CosmosException ex) when (ex.Status == 404)

+ 25 - 25
TEAMModelOS/Models/Service/LessonServiceIES.cs

@@ -28,11 +28,11 @@ namespace TEAMModelOS.Models.Service
         /// <param name="_lessonId"></param>
         /// <param name="_scope"></param>
         /// <returns></returns>
-        public static async Task SetLearnRecordContent(JsonElement _school, JsonElement _tmdid, JsonElement _lessonId, JsonElement _scope, bool _isIES = true)
+        public static async Task SetLearnRecordContent(JsonElement _school, JsonElement _tmdid, JsonElement _lessonId, JsonElement _scope, AzureCosmosFactory _azureCosmos, AzureStorageFactory _azureStorage, bool _isIES = true)
         {
             try
-            {                
-                var client = AzureCosmosFactory.GetCosmosClientStatic();
+            {
+                var client = _azureCosmos.GetCosmosClient();
                 string school = $"{_school}";
                 string tmdid = _tmdid.GetString();
                 string lessonId = _lessonId.GetString();
@@ -77,12 +77,12 @@ namespace TEAMModelOS.Models.Service
                     blobTaskUrl = $"/temp/records/{lessonId}/IES/Task.json";
                 }
                 // 檢查 TimeLine 是否存在blob
-                if (AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobTimeLineUrl).Exists() &&
-                    AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobIRSUrl).Exists() &&
-                    AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobbaseUrl).Exists())
+                if (_azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTimeLineUrl).Exists() &&
+                    _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobIRSUrl).Exists() &&
+                    _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobbaseUrl).Exists())
                 {
                     // 開啟 base.json
-                    BlobDownloadResult baseblobDownload = await AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobbaseUrl).DownloadContentAsync();
+                    BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobbaseUrl).DownloadContentAsync();
                     ScoreLessonBase lessonBase = baseblobDownload.Content.ToObjectFromJson<ScoreLessonBase>();
                     //取得學校學生名單                    
                     List<string> stuIdForSql = new List<string>();
@@ -98,15 +98,15 @@ namespace TEAMModelOS.Models.Service
                     }
 
                     // 開啟 TimeLine.json
-                    BlobDownloadResult TimeLineblobDownload = await AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobTimeLineUrl).DownloadContentAsync();
+                    BlobDownloadResult TimeLineblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTimeLineUrl).DownloadContentAsync();
                     TimeLineEvents timeLineEvents = TimeLineblobDownload.Content.ToObjectFromJson<TimeLineEvents>();
 
                     // 開啟 IRS.json
-                    BlobDownloadResult IRSblobDownload = await AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobIRSUrl).DownloadContentAsync();
+                    BlobDownloadResult IRSblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobIRSUrl).DownloadContentAsync();
                     List<IRSItem> iRSItems = IRSblobDownload.Content.ToObjectFromJson<List<IRSItem>>();
 
                     // 開啟 Task.json
-                    BlobDownloadResult taskblobDownload = await AzureStorageFactory.GetBlobContainerClientStatic(rootName).GetBlobClient(blobTaskUrl).DownloadContentAsync();
+                    BlobDownloadResult taskblobDownload = await _azureStorage.GetBlobContainerClient(rootName).GetBlobClient(blobTaskUrl).DownloadContentAsync();
                     List<TaskItem> taskItems = taskblobDownload.Content.ToObjectFromJson<List<TaskItem>>();
                     if (timeLineEvents.events.Count > 0)
                     {
@@ -126,23 +126,23 @@ namespace TEAMModelOS.Models.Service
                                             {
                                                 // 單選
                                                 case "single":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSingle", learnRecordItems);
+                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSingle", learnRecordItems, _azureCosmos);
                                                     break;
                                                 // 複選
                                                 case "multiple":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsMultiple", learnRecordItems);
+                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsMultiple", learnRecordItems, _azureCosmos);
                                                     break;
                                                 // 是非
                                                 case "judge":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsJudge", learnRecordItems);
+                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsJudge", learnRecordItems, _azureCosmos);
                                                     break;
                                                 // 填充
                                                 case "complete":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsComplete", learnRecordItems);
+                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsComplete", learnRecordItems, _azureCosmos);
                                                     break;
                                                 // 問答
                                                 case "subjective":
-                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSubjective", learnRecordItems);
+                                                    await SetPopQuesLoadContent(lessonBase, school, lessonId, iRSItems[j], timeLineEvents.events[i], "AnsSubjective", learnRecordItems, _azureCosmos);
                                                     break;
                                             }
                                         }
@@ -163,7 +163,7 @@ namespace TEAMModelOS.Models.Service
                                                     {
                                                         if (lessonBase.student[k].type == 2)
                                                         {// 校內帳號
-                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
+                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem, _azureCosmos);
                                                         }
                                                         else
                                                         {// 非校內帳號
@@ -212,7 +212,7 @@ namespace TEAMModelOS.Models.Service
                                                     {
                                                         if (lessonBase.student[k].type == 2)
                                                         {// 校內帳號
-                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
+                                                            await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem, _azureCosmos);
                                                         }
                                                         else
                                                         {// 非校內帳號
@@ -249,7 +249,7 @@ namespace TEAMModelOS.Models.Service
 
                                             if (lessonBase.student[k].type == 2)
                                             {
-                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
+                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem, _azureCosmos);
                                             }
                                             else
                                             {// 非校內帳號
@@ -284,7 +284,7 @@ namespace TEAMModelOS.Models.Service
 
                                             if (lessonBase.student[k].type == 2)
                                             {
-                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
+                                                await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem, _azureCosmos);
                                             }
                                             else
                                             {// 非校內帳號
@@ -343,7 +343,7 @@ namespace TEAMModelOS.Models.Service
                     string fileContent = Newtonsoft.Json.JsonConvert.SerializeObject(learnRecordItems);
 
                     // 获取容器引用
-                    BlobContainerClient containerClient = AzureStorageFactory.GetBlobContainerClientStatic(containerName);
+                    BlobContainerClient containerClient = _azureStorage.GetBlobContainerClient(containerName);
 
                     // 获取 Blob 客户端
                     BlobClient blobClient = containerClient.GetBlobClient(blobName);
@@ -372,12 +372,12 @@ namespace TEAMModelOS.Models.Service
         /// <param name="studentId"></param>
         /// <param name="learnRecordItem"></param>
         /// <returns></returns>
-        private static async Task getSchoolCode(string school, string lessonId, string studentId, LearnRecordItem learnRecordItem)
+        private static async Task getSchoolCode(string school, string lessonId, string studentId, LearnRecordItem learnRecordItem, AzureCosmosFactory _azureCosmos)
         {
             if (string.IsNullOrWhiteSpace(school))
             {// 如果沒有學校代碼 需要用lessonId去DB取學校代碼
-                var clientTeacher = AzureCosmosFactory.GetCosmosClientStatic().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
-                GroupIdsFromLesson groupIdsFromLesson = await AzureCosmosFactory.GetCosmosClientStatic().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<GroupIdsFromLesson>(lessonId, new PartitionKey($"LessonRecord"));
+                var clientTeacher = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher);
+                GroupIdsFromLesson groupIdsFromLesson = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<GroupIdsFromLesson>(lessonId, new PartitionKey($"LessonRecord"));
                 //SchoolFromgroupIds schoolFromgroupIds = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<SchoolFromgroupIds>(groupIdsFromLesson.groupIds[0], new PartitionKey($"GroupList"));
                 GroupList groupList = await clientTeacher.ReadItemAsync<GroupList>(groupIdsFromLesson.groupIds[0], new PartitionKey($"GroupList"));
                 if (!string.IsNullOrWhiteSpace(groupList.school))// 如果沒有撈到schoolid防呆
@@ -416,14 +416,14 @@ namespace TEAMModelOS.Models.Service
         /// <param name="verb"></param>
         /// <param name="learnRecordItems"></param>
         /// <returns></returns>
-        private static async Task SetPopQuesLoadContent(ScoreLessonBase lessonBase, string school, string lessonId, IRSItem iRSItem, TimeLineEventPg timeLineEvent, string verb, List<LearnRecordItem> learnRecordItems)
+        private static async Task SetPopQuesLoadContent(ScoreLessonBase lessonBase, string school, string lessonId, IRSItem iRSItem, TimeLineEventPg timeLineEvent, string verb, List<LearnRecordItem> learnRecordItems, AzureCosmosFactory _azureCosmos)
         {
             for (int k = 0; k < lessonBase.student.Count; k++)
             {
                 LearnRecordItem learnRecordItem = new();
                 if (lessonBase.student[k].type == 2)
                 {
-                    await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem);
+                    await getSchoolCode(school, lessonId, lessonBase.student[k].id, learnRecordItem, _azureCosmos);
                 }
                 else
                 {// 非校內帳號