Przeglądaj źródła

Merge branch 'develop' of http://52.130.252.100:10000/TEAMMODEL/TEAMModelOS into develop

CrazyIter_Bin 1 rok temu
rodzic
commit
21dea67054

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

@@ -906,6 +906,7 @@ namespace TEAMModelBI.Controllers.BISchool
                     {
                         //將該老師從學校的老師名單中移除
                         await cosmosClient.GetContainer("TEAMModelOS", "School").DeleteItemAsync<SchoolTeacher>($"{tmdId}", new PartitionKey($"Teacher-{scId}"));
+                        strMsg.Append($"{scId},");
                     }
                     else
                     {

+ 5 - 3
TEAMModelOS.FunctionV4/CosmosDB/CommonTrigger.cs

@@ -26,8 +26,9 @@ namespace TEAMModelOS.FunctionV4
         private readonly IHttpClientFactory _httpClient;
         private IConfiguration _configuration { get; set; }
         private readonly CoreAPIHttpService _coreAPIHttpService;
+        private readonly HttpTrigger _httpTrigger;
         public CommonTrigger(CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory azureServiceBus, AzureStorageFactory azureStorage, DingDing dingDing, AzureRedisFactory azureRedis
-          , IConfiguration configuration, IHttpClientFactory httpClient
+          , IConfiguration configuration, IHttpClientFactory httpClient, HttpTrigger httpTrigger
           )
         {
             _azureCosmos = azureCosmos;
@@ -38,6 +39,7 @@ namespace TEAMModelOS.FunctionV4
             _configuration = configuration;
             _coreAPIHttpService=coreAPIHttpService;
             _httpClient = httpClient;
+            _httpTrigger = httpTrigger;
         }
         [Function("Common")]
         public async Task Common([CosmosDBTriggerAttribute(
@@ -83,7 +85,7 @@ namespace TEAMModelOS.FunctionV4
                                 switch (data.pk)
                                 {
                                     case "Exam":
-                                        await TriggerExam.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration);
+                                        await TriggerExam.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration,_httpTrigger);
                                         break;
                                     case "Vote":
                                         await TriggerVote.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
@@ -104,7 +106,7 @@ namespace TEAMModelOS.FunctionV4
                                         await TriggerHomework.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
                                         break;
                                     case "Art":
-                                        await TriggerArt.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration);
+                                        await TriggerArt.Trigger(_coreAPIHttpService, _serviceBus, _azureStorage, _dingDing, client, element, data, _azureRedis, _configuration, _httpTrigger);
                                         break;
                                     case "ExamImport":
                                         await TriggerExamImport.Trigger(_coreAPIHttpService, _azureCosmos, _serviceBus, _azureStorage, _dingDing, client, element, data, _httpClient, _configuration);

+ 67 - 7
TEAMModelOS.FunctionV4/CosmosDB/TriggerArt.cs

@@ -20,13 +20,15 @@ using OpenXmlPowerTools;
 using DocumentFormat.OpenXml.Office2010.Excel;
 using DocumentFormat.OpenXml.Office2016.Excel;
 using static TEAMModelOS.SDK.Models.Cosmos.Student.StudentAnalysis;
+using HTEXLib.Helpers.ShapeHelpers;
+using DocumentFormat.OpenXml.Spreadsheet;
 
 namespace TEAMModelOS.FunctionV4.CosmosDB
 {
     public class TriggerArt
     {
         public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
-            CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
+            CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration, HttpTrigger _httpTrigger)
         {
             try
             {
@@ -241,11 +243,11 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
                             break;
                         case "finish":
                             //判定是否是区级创建的活动内容
-                            if (art.lost.Count == 0 && art.pass == 0)
+                           /* if (art.lost.Count == 0 && art.pass == 0)
                             {
                                 if (art.owner.Equals("area") && string.IsNullOrEmpty(art.pId))
                                 {
-                                    /* List<(string id, string code, List<Tasks> settings)> artSchools = new();
+                                    *//* List<(string id, string code, List<Tasks> settings)> artSchools = new();
                                      string ql = $"select c.id,c.school,c.settings,c.classes from c where  c.pk = 'Art' and c.pId = '{art.id}'";
                                      await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: ql))
                                      {
@@ -293,13 +295,13 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
 
                                      }
                                      art.pass = 1;
-                                     await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*/
+                                     await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*//*
                                 }
                                 else
                                 {
                                     //获取当前艺术评价相关评测ID目前暂时排除区级发布的评测信息
 
-                                    /*List<(string eId, string sId)> ids = new();
+                                    *//*List<(string eId, string sId)> ids = new();
                                     var examId = art.settings.SelectMany(x => x.task).Where(c => c.type == 1).Select(z => new { z.acId, z.subject }).ToList();
                                     examId.ForEach(x =>
                                     {
@@ -328,9 +330,9 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
                                     art.miss.Add(stus.Count);
                                     //art.miss = stus.Count;
                                     art.pass = 1;
-                                    await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*/
+                                    await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<ArtEvaluation>(art, art.id, new PartitionKey(art.code));*//*
                                 }
-                            }
+                            }*/
                             List<StudentArtResult> studentArtResults = new();
                             string sql = $"SELECT value c FROM c   where  c.pk='ArtResult' ";
                             await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
@@ -362,6 +364,16 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
 
                             }
                             List<Task<ItemResponse<StudentArtResult>>> tasks = new List<Task<ItemResponse<StudentArtResult>>>();
+                            //新增数据推送 obj => Portrait
+                            Portrait portrait = new()
+                            {
+                                schoolCode = art.school,
+                                periodId = art.period.id,
+                                subjectId = "subject_art"
+                            };
+                            var period = scInfo.period.Where(x => x.id.Equals(art.period.id)).FirstOrDefault();
+                            //获取学期信息
+                            var (currSemester, studyYear, date, nextSemester) =  SchoolService.GetSemester(period, art.startTime);
                             //总分的占比情况
 
                             foreach (var rs in studentArtResults)
@@ -375,6 +387,7 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
                                         res.score = Math.Round(res.score);
                                     }
                                 }
+                                
                                 //if (rs.totalScore == 0)
                                 //{
                                 foreach (var sc in rs.subjectScores)
@@ -408,12 +421,59 @@ namespace TEAMModelOS.FunctionV4.CosmosDB
                                 }
                                 rs.totalScore = Math.Round(rs.subjectScores.Where(m => m.score >= 0).Sum(z => z.score),2);
                                 tasks.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync(rs, rs.id, new PartitionKey(rs.code)));
+                                PortraitStudent student = new()
+                                {
+                                    studentId = rs.studentId,
+                                    name = rs.studentName,
+                                    classId = rs.classIds[0]
+                                };
+                                SemesterData semesterData = new()
+                                {
+                                    examName = art.name,
+                                    examId = art.id,
+                                    examDate = art.startTime,
+                                    examType = "",
+                                    year = studyYear,
+                                    semesterId = currSemester.id,
+                                    totalScore = 200,
+                                    sumScore = rs.totalScore,
+                                    excellenceRate = 0,
+                                    passRate = 0,
+                                };
+                                int index = 0;
+                                foreach (var sj in art.subjects)
+                                {
+                                    ItemScore item = new()
+                                    {
+                                        name = sj.name,
+                                        score = rs.subjectScores.Where(x => x.subjectId.Equals(sj.id)).FirstOrDefault().score,
+                                        time = art.startTime,
+                                        totalScore = 100,
+                                        type = sj.id
+                                    };
+                                    index++;
+                                    semesterData.itemScore.Add(item);
+                                }
+                                student.semesterData.Add(semesterData);
+
+                                portrait.students.Add(student);
                                 //}
                             }
                             if (tasks.Count > 0)
                             {
                                 await Task.WhenAll(tasks);
                             }
+                          
+                            //获取学生信息
+                            //(List<RMember> rmembers, List<RGroupList> groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, art.classes, art.school);
+                           /* foreach (var member in studentArtResults)
+                            {                                
+                                
+                            }*/
+                            string location = $"{Environment.GetEnvironmentVariable("Option:Location")}";
+                            var responseData = await _httpTrigger.RequestHttpTrigger(portrait.ToJson(), location, "upsert-student-portrait");
+
+
                             break;
                     }
                 }

+ 60 - 2
TEAMModelOS.FunctionV4/CosmosDB/TriggerExam.cs

@@ -31,13 +31,16 @@ using Newtonsoft.Json;
 using System.Net;
 using System.Security.Policy;
 using Microsoft.Extensions.Configuration;
+using DocumentFormat.OpenXml.EMMA;
+using Microsoft.Extensions.Options;
+using TEAMModelOS.Models;
 
 namespace TEAMModelOS.FunctionV4
 {
     public class TriggerExam
     {
         public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureCosmosFactory _azureCosmos, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
-            CosmosClient client, JsonElement input, TriggerData data, IHttpClientFactory _httpClient, IConfiguration _configuration)
+            CosmosClient client, JsonElement input, TriggerData data, IHttpClientFactory _httpClient, IConfiguration _configuration, HttpTrigger _httpTrigger)
         {
 
             List<ExamClassResult> examClassResults = new();
@@ -103,6 +106,7 @@ namespace TEAMModelOS.FunctionV4
                     List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", data.id }, { "PartitionKey", PartitionKey } });
                     //处理科目信息
                     List<string> sub = new List<string>();
+                    School sc = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(info.school, new Azure.Cosmos.PartitionKey("Base"));
                     foreach (ExamSubject subject in info.subjects)
                     {
                         sub.Add(subject.id);
@@ -225,7 +229,7 @@ namespace TEAMModelOS.FunctionV4
 
                                                 using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
                                                 Class classroom = json.ToObject<Class>();
-                                                School sc = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(info.school, new Azure.Cosmos.PartitionKey("Base"));
+                                                
                                                 foreach (SDK.Models.Period period in sc.period)
                                                 {
                                                     if (period.id.Equals(classroom.periodId))
@@ -435,7 +439,61 @@ namespace TEAMModelOS.FunctionV4
                                     info.lostStu = settlement.stus;
                                     info.stuCount = settlement.total;
                                     info.qRate = settlement.qrate;
+                                    //新增数据推送 obj => Portrait
+                                    Portrait portrait = new()
+                                    {
+                                        schoolCode = info.school,
+                                        periodId = info.period.id,
+                                        subjectId = "subject_exam"
+                                    };
+                                    var period = sc.period.Where(x => x.id.Equals(info.period.id)).FirstOrDefault();
+                                    //获取学期信息
+                                    var (currSemester, studyYear, date, nextSemester) = SchoolService.GetSemester(period, info.startTime);
+                                    //获取学生信息
+                                    (List<RMember> rmembers, List<RGroupList> groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, info.classes, info.school);
+                                    foreach (var member in rmembers) {
+                                        if (info.lostStu.Contains(member.id)) {
+                                            continue;
+                                        }
+                                        PortraitStudent student = new()
+                                        {
+                                            studentId = member.id,
+                                            name = member.name,
+                                            classId = member.classId
+                                        };
+                                        SemesterData semesterData = new()
+                                        {
+                                            examName = info.name,
+                                            examId = info.id,
+                                            examDate = info.startTime,
+                                            examType = info.examType?.name,
+                                            year = info.year,
+                                            semesterId = currSemester.id,
+                                            totalScore = info.papers.SelectMany(x => x.point).Sum(),
+                                            sumScore = examClassResults.SelectMany(x => x.sum).Sum(),
+                                            excellenceRate = 0,
+                                            passRate = 0,
+                                        };
+                                        int index = 0;
+                                        foreach (var sj in info.subjects) {
+                                            ItemScore item = new()
+                                            {
+                                                name = sj.name,
+                                                score = examClassResults.Where(x => x.subjectId.Equals(sj.id)).FirstOrDefault().sum.Sum(),
+                                                time = info.startTime,
+                                                totalScore = info.papers[index].point.Sum(),
+                                                type = sj.id
+                                            };
+                                            index++;
+                                            semesterData.itemScore.Add(item);
+                                        }
+                                        student.semesterData.Add(semesterData);
 
+                                        portrait.students.Add(student);
+                                    }
+                                    string location = $"{Environment.GetEnvironmentVariable("Option:Location")}";
+                                    var (status, json) =  await _httpTrigger.RequestHttpTrigger(portrait.ToJson(), location, "upsert-student-portrait");
+                                    //PortraitStudent student = new();
                                     //处理试卷活动结束统计账户信息
                                     List<FMember> idList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, info.school, info.classes, info.stuLists, null);
                                     info.staffIds = idList;

+ 6 - 0
TEAMModelOS.SDK/DI/HttpTrigger/HttpTrigger.cs

@@ -13,6 +13,7 @@ using System.Text.Json;
 using System.IO;
 using TEAMModelOS.SDK.Extension;
 using System.Net;
+using TEAMModelOS.SDK.Models;
 
 namespace TEAMModelOS.SDK.DI
 {
@@ -81,6 +82,11 @@ namespace TEAMModelOS.SDK.DI
                 return (500, Content);
             }
         }
+
+        public Task RequestHttpTrigger(Portrait portrait, object location, string v)
+        {
+            throw new NotImplementedException();
+        }
     }
     public enum HttpTriggerUrl
     {

+ 2 - 2
TEAMModelOS.SDK/Models/Cosmos/Student/OverallEducation.cs

@@ -177,7 +177,7 @@ namespace TEAMModelOS.SDK.Models
         public string studentId { get; set; }//学生编号
         public string name { get; set; }//学生姓名
         public string classId { get; set; }//行政班id
-        public List<SemesterData> semesterData { get; set; }//学期数据
+        public List<SemesterData> semesterData { get; set; } = new List<SemesterData>();//学期数据
     }
     /// <summary>
     /// 学期数据
@@ -232,6 +232,6 @@ namespace TEAMModelOS.SDK.Models
         /// <summary>
         /// //考核项目数据
         /// </summary>
-        public List<ItemScore> itemScore { get; set; } 
+        public List<ItemScore> itemScore { get; set; } = new List<ItemScore>();
     }
 }

+ 13 - 4
TEAMModelOS/Controllers/Analysis/ArtAnalysisController.cs

@@ -146,13 +146,22 @@ namespace TEAMModelOS.Controllers.Analysis
                 }
                 var pow = Math.Round(stus.Count > 0 ? Math.Pow(powSum / stus.Count, 0.5) : 0, 2);
 
-                //获取评测ID
-                //var examId = arts[0].settings.SelectMany(s => s.task).Where(a => a.type == 1 && a.subject.Equals(subjectId.GetString())).FirstOrDefault().acId;
-                //根据科目标识获取科目ID以及知识块和知识点关系
-                (string subId, List<(string name, List<string> kno)> values) = await getKnowledge("hbcn", client, subjectId.GetString(), "be32942d-97a9-52ba-45d6-2e5b722583f5");
+                
                 //获取本次评测所有科目结算结果
                 List<ExamResult> examResults = new();
                 ExamInfo info = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(examId.ToString(), new PartitionKey($"Exam-{code}"));
+                //获取评测ID
+                //var examId = arts[0].settings.SelectMany(s => s.task).Where(a => a.type == 1 && a.subject.Equals(subjectId.GetString())).FirstOrDefault().acId;
+                //根据科目标识获取科目ID以及知识块和知识点关系TODO 引用不同试卷时 获取知识点得差异
+                int index = 0;
+                foreach (var pr in info.subjects) {
+                    if (pr.id.Equals(subjectId.GetString()))
+                    {
+                        break;
+                    }
+                    index++;
+                }
+                (string subId, List<(string name, List<string> kno)> values) = await getKnowledge(info.papers[index].code, client, subjectId.GetString(), info.period.id);
                 var query = $"select c.id,c.name,c.subjectId,c.studentScores,c.studentIds,c.paper,c.classes,c.sRate,c.average,c.standard,c.lostStus,c.record,c.phc,c.plc from c where c.examId = '{examId}' and c.subjectId = '{subjectId}' ";
                 await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryIterator<ExamResult>(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ExamResult-{examId}") }))
                 {

+ 145 - 0
TEAMModelOS/Controllers/School/SchoolController.cs

@@ -2068,6 +2068,151 @@ namespace TEAMModelOS.Controllers
 
         }
 
+        [ProducesDefaultResponseType]
+        [HttpPost("get-school-iot")]
+        [Authorize(Roles = "IES")]
+        [AuthToken(Roles = "admin")]
+        public async Task<IActionResult> getSchoolIotData(JsonElement request)
+        {
+            try
+            {
+                if (!request.TryGetProperty("schoolId", out JsonElement _schoolId)) return BadRequest();
+                if (!request.TryGetProperty("periodId", out JsonElement _periodId)) return BadRequest();
+                var sdate = (request.TryGetProperty("sdate", out JsonElement _sdate)) ? TimeHelper.GetDateTime(_sdate.GetString(), "yyyy-MM-dd") : (0, 0, 0, 0, 0);
+                var edate = (request.TryGetProperty("edate", out JsonElement _edate)) ? TimeHelper.GetDateTime(_edate.GetString(), "yyyy-MM-dd") : (0, 0, 0, 0, 0);
+                //取得學校基本資訊
+                School schoolBase = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>($"{_schoolId}", new PartitionKey("Base"));
+                if(string.IsNullOrWhiteSpace(schoolBase.id)) return BadRequest();
+                string schName = schoolBase.name;
+                string schRegion = schoolBase.region;
+                string schProvince = schoolBase.province;
+                string schCity = schoolBase.city;
+                string schDist = schoolBase.dist;
+                string schAreaId = schoolBase.areaId;
+                string schType = schoolBase.code;
+                var period = schoolBase.period.Find(x => x.id.Equals($"{_periodId}"));
+                if(period == null) return BadRequest();
+                (Semester currSemester, int studyYear, DateTimeOffset date, DateTimeOffset nextSemester) info = SchoolService.GetSemester(period);
+                string semesterId = info.currSemester.id;
+                var datetime = DateTimeOffset.UtcNow;
+                int studyYear = info.studyYear;
+                int dateFromYear = (!sdate.Item1.Equals(0)) ? sdate.Item1 : studyYear;
+                int dateFromMonth = (!sdate.Item2.Equals(0)) ? sdate.Item2 : info.currSemester.month;
+                int dateFromDay = (!sdate.Item3.Equals(0)) ? sdate.Item3 : info.currSemester.day;
+                int dateToYear = (!edate.Item1.Equals(0)) ? edate.Item1 : datetime.Year;
+                int dateToMonth = (!edate.Item2.Equals(0)) ? edate.Item2 : datetime.Month;
+                int dateToDay = (!edate.Item3.Equals(0)) ? edate.Item3 : datetime.Day;
+                //教室數(今年)
+                int classCnt = 0;
+                string sql = $"SELECT VALUE COUNT(c.id) FROM c WHERE c.year = {studyYear}";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Class-{_schoolId}") }))
+                {
+                    classCnt = items;
+                }
+                //教師數
+                int teacherCnt = 0;
+                sql = $"SELECT VALUE COUNT(c.id) FROM c";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Teacher-{_schoolId}") }))
+                {
+                    teacherCnt = items;
+                }
+                //學生數(今年)
+                int studentCnt = 0;
+                sql = $"SELECT VALUE COUNT(c.id) FROM c WHERE c.year = {studyYear}";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Base-{_schoolId}") }))
+                {
+                    studentCnt = items;
+                }
+                //HiTeach硬體授權數
+                int deviceAuthCnt = 0;
+                //List<string> serialPermitList = getSerialPermitProdcodeList();
+                List<string> serialPermitList = new List<string>() { "J223IZ6M", "3222C6D2", "J223IZAM", "J2236ZCX", "3222DNG2", "3222IAVN", "BYJ6LZ6Z" };
+                string serialPermitJsonStr = JsonConvert.SerializeObject(serialPermitList);
+                string serialQueryText = $"SELECT VALUE SUM(c.deviceMax) FROM c WHERE c.dataType = 'serial' AND ARRAY_CONTAINS({serialPermitJsonStr}, c.prodCode) AND c.expireStatus = 'A'";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<int>(queryText: serialQueryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Product-{_schoolId}") }))
+                {
+                    deviceAuthCnt = items;
+                }
+
+                //取得產品分析資訊
+                int stuShow = 0; ///學生人次
+                long stuLessonLengMin = 0; ///學生參與總時間數(分)
+                int lessonRecord = 0; ///課堂數
+                long lessonLengMin = 0; ///課堂時間數(分)
+                int mission = 0; ///課中統計-任務數
+                int missionFin = 0; ///課中統計-作品數
+                int item = 0; ///課中統計-題目數
+                int interact = 0; ///課中統計-互動次數
+                int lTypeCoop = 0; ///學習型態: 合作
+                int lTypeIact = 0; ///學習型態: 互動
+                int lTypeMis = 0; ///學習型態: 任務
+                int lTypeTst = 0; ///學習型態: 測驗
+                int lTypeDif = 0; ///學習型態: 差異化
+                List<string> htcDevList = new List<string>(); ///設備統計-HiTeach Device list
+                List<string> htaDevList = new List<string>(); ///設備統計-HiTA Device list
+                List<string> htccDevList = new List<string>(); ///設備統計-HiTeachCC Device list
+                DateTimeOffset dateTimeFrom = new DateTimeOffset(dateFromYear, dateFromMonth, dateFromDay, 0, 0, 0, TimeSpan.Zero);
+                DateTimeOffset dateTimeTo = new DateTimeOffset(dateToYear, dateToMonth, dateToDay, 23, 59, 59, TimeSpan.Zero);
+                long dateTimeFromSec = dateTimeFrom.ToUnixTimeSeconds();
+                long dateTimeToSec = dateTimeTo.ToUnixTimeSeconds();
+                List<ProdAnalysisApiResult> iotData = new List<ProdAnalysisApiResult>();
+                sql = $"SELECT * FROM c WHERE c.schoolId = '{_schoolId}' AND c.dateUnit = 'day' AND c.dateTime >= {dateTimeFromSec} AND c.dateTime <= {dateTimeToSec}";
+                await foreach (var items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryStreamIterator(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ProdAnalysis") }))
+                {
+                    var json = await JsonDocument.ParseAsync(items.ContentStream);
+                    foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                    {
+                        ProdAnalysisApiResult data = obj.ToObject<ProdAnalysisApiResult>();
+                        data.school.name = schName;
+                        data.school.region = schRegion;
+                        data.school.province = schProvince;
+                        data.school.city = schCity;
+                        data.school.dist = schDist;
+                        data.school.areaId = schAreaId;
+                        data.school.type = schType;
+                        iotData.Add(data);
+                        stuShow += data.stuShow;
+                        stuLessonLengMin += data.stuLessonLengMin;
+                        lessonRecord += data.lessonRecord;
+                        lessonLengMin += data.stuLessonLengMin;
+                        mission += data.mission;
+                        missionFin += data.missionFin;
+                        item += data.item;
+                        interact += data.interact;
+                        if (data.toolType.Equals("HiTeach")) htcDevList = htcDevList.Union(data.deviceList).ToList();
+                        if (data.toolType.Equals("HiTA")) htaDevList = htaDevList.Union(data.deviceList).ToList();
+                        if (data.toolType.Equals("HiTeachCC")) htccDevList = htccDevList.Union(data.deviceList).ToList();
+                        lTypeCoop += data.lTypeCoop;
+                        lTypeIact += data.lTypeIact;
+                        lTypeMis += data.lTypeMis;
+                        lTypeTst += data.lTypeTst;
+                        lTypeDif += data.lTypeDif;
+                    }
+                }
+                int htcDevCnt = htcDevList.Count; ///設備統計-HiTeach上線數
+                int htcDevTotalCnt = 0; ///設備統計-HiTeach總設備數
+                sql = $"SELECT VALUE COUNT(1) FROM (SELECT DISTINCT x FROM c JOIN x IN c.deviceList WHERE c.schoolId = '{_schoolId}' AND c.dateUnit = 'day' AND c.toolType = 'HiTeach')";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ProdAnalysis") }))
+                {
+                    htcDevTotalCnt = items;
+                }
+                int htaDevCnt = htaDevList.Count; ///設備統計-HiTA上線數
+                int htaDevTotalCnt = 0; ///設備統計-HiTA總設備數
+                sql = $"SELECT VALUE COUNT(1) FROM (SELECT DISTINCT x FROM c JOIN x IN c.deviceList WHERE c.schoolId = '{_schoolId}' AND c.dateUnit = 'day' AND c.toolType = 'HiTA')";
+                await foreach (int items in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ProdAnalysis") }))
+                {
+                    htaDevTotalCnt = items;
+                }
+                int htccDevCnt = htccDevList.Count; ///設備統計-HiTeachCC上線數
+
+                return Ok(new { sdate=$"{dateFromYear}-{dateFromMonth}-{dateFromDay}", edate=$"{dateToYear}-{dateToMonth}-{dateToDay}", classCnt, teacherCnt, studentCnt, deviceAuthCnt, stuShow, stuLessonLengMin, lessonRecord, lessonLengMin, mission, missionFin, item, interact, htcDevCnt, htcDevTotalCnt, htaDevCnt, htaDevTotalCnt, htccDevCnt, lTypeCoop, lTypeIact, lTypeMis, lTypeTst, lTypeDif, iotData });
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"OS,{_option.Location},school/init/get-school-iot\n{ex.Message}\n{ex.StackTrace}\n{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
+                return BadRequest();
+            }
+        }
         //取得序號產品准許使用產品代碼列表
         public static List<string> getSerialPermitProdcodeList()
         {