Prechádzať zdrojové kódy

优化智慧学校的数量,优化统计方法

Li 2 rokov pred
rodič
commit
e6f89b1516

+ 1 - 0
TEAMModelBI/Controllers/BITest/TestController.cs

@@ -1749,6 +1749,7 @@ namespace TEAMModelBI.Controllers.BITest
         [HttpPost("set-statszero")]
         public async Task<IActionResult> SetStatsZero() 
         {
+            double roomCnt= await SchoolStatsWay.GetShoolWisdomRoomCount(_azureCosmos, _azureRedis, _configuration, _httpClient, _dingDing, "hbcn");
             await BIStats.SetStatsZeroPoint(_azureCosmos, _dingDing);
             return Ok(new { });
         }

+ 56 - 46
TEAMModelBI/Controllers/RepairApi/SchoolRepController.cs

@@ -498,65 +498,75 @@ namespace TEAMModelBI.Controllers.RepairApi
         [HttpPost("set-allscstats")]
         public async Task<IActionResult> SetAllScStats(JsonElement jsonElement) 
         {
-            jsonElement.TryGetProperty("scId", out JsonElement scId);
-            jsonElement.TryGetProperty("year", out JsonElement _year);
-            var cosmosClient = _azureCosmos.GetCosmosClient(); 
-            var redisClinet = _azureRedis.GetRedisClient(8);
+            try
+            {
+                jsonElement.TryGetProperty("scId", out JsonElement scId);
+                jsonElement.TryGetProperty("year", out JsonElement _year);
+                var cosmosClient = _azureCosmos.GetCosmosClient();
+                var redisClinet = _azureRedis.GetRedisClient(8);
 
-            List<string> scIds = new();
-            if (!string.IsNullOrEmpty($"{scId}"))
-                scIds.Add($"{scId}");
-            else
-                scIds = await CommonFind.FindScIds(cosmosClient, "select value(c.id) from c ", "Base");
+                List<string> scIds = new();
+                if (!string.IsNullOrEmpty($"{scId}"))
+                    scIds.Add($"{scId}");
+                else
+                    scIds = await CommonFind.FindScIds(cosmosClient, "select value(c.id) from c ", "Base");
 
-            DateTimeOffset dateTime = DateTimeOffset.UtcNow;
-            int year = dateTime.Year;
-            if (!string.IsNullOrEmpty($"{_year}"))
-            {
-                year = _year.GetInt32();
-                dateTime = dateTime.AddYears(-1);
-            }
+                DateTimeOffset dateTime = DateTimeOffset.UtcNow;
+                int year = dateTime.Year;
+                if (!string.IsNullOrEmpty($"{_year}"))
+                {
+                    year = _year.GetInt32();
+                    dateTime = dateTime.AddYears(-1);
+                }
 
-            List<StatsInfo> statsInfos = new();
-            List<Task<ItemResponse<StatsInfo>>> taskStss = new();
-            foreach (var sc in scIds) 
-            {
-                StatsInfo statsInfo = new();
-                var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{year}-{sc}", new PartitionKey("Statistics"));
-                if (scDataStats.Status == 200)
+                List<StatsInfo> statsInfos = new();
+                List<Task<ItemResponse<StatsInfo>>> taskStss = new();
+                foreach (var sc in scIds)
                 {
-                    using var fileJson = await JsonDocument.ParseAsync(scDataStats.ContentStream);
-                    statsInfo = fileJson.ToObject<StatsInfo>();
+                    StatsInfo statsInfo = new();
+                    var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{year}-{sc}", new PartitionKey("Statistics"));
+                    if (scDataStats.Status == 200)
+                    {
+                        using var fileJson = await JsonDocument.ParseAsync(scDataStats.ContentStream);
+                        statsInfo = fileJson.ToObject<StatsInfo>();
+                    }
+                    else
+                    {
+                        statsInfo.id = $"{year}-{sc}";
+                    }
+
+                    statsInfo = await SchoolStatsWay.GetSingleSc(cosmosClient, redisClinet, sc, year);
+                    statsInfo.witRoom = ((int)await SchoolStatsWay.GetShoolWisdomRoomCount(_azureCosmos, _azureRedis, _configuration, _httpClient, _dingDing, statsInfo.schoolId));
+
+                    if (scDataStats.Status == 200)
+                        taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<StatsInfo>(statsInfo, $"{year}-{sc}", new PartitionKey("Statistics")));
+                    else
+                        taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync<StatsInfo>(statsInfo, new PartitionKey("Statistics")));
+
+                    //statsInfo = await StatsWay.upSingleSc(cosmosClient, sc);
+                    statsInfos.Add(statsInfo);
                 }
+
+                if (taskStss.Count < 256)
+                    await Task.WhenAll(taskStss);
                 else
                 {
-                    statsInfo.id = $"{year}-{sc}";
+                    int pages = (taskStss.Count + 255) / 256;
+                    for (int i = 0; i < pages; i++)
+                    {
+                        List<Task<ItemResponse<StatsInfo>>> temTaskStss = taskStss.Skip(i * 256).Take(256).ToList();
+                        await Task.WhenAll(temTaskStss);
+                    }
                 }
 
-                statsInfo = await SchoolStatsWay.GetSingleSc(cosmosClient, redisClinet, sc, year);
-
-                if (scDataStats.Status == 200)
-                    taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<StatsInfo>(statsInfo, $"{year}-{sc}", new PartitionKey("Statistics")));
-                else
-                    taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync<StatsInfo>(statsInfo, new PartitionKey("Statistics")));
+                return Ok(new { state = RespondCode.Ok, statsInfos });
 
-                //statsInfo = await StatsWay.upSingleSc(cosmosClient, sc);
-                statsInfos.Add(statsInfo);
             }
-
-            if (taskStss.Count < 256)
-                await Task.WhenAll(taskStss);
-            else 
+            catch (Exception ex)
             {
-                int pages = (taskStss.Count + 255) / 256;
-                for (int i = 0; i < pages; i++)
-                {
-                    List<Task<ItemResponse<StatsInfo>>> temTaskStss = taskStss.Skip(i * 256).Take(256).ToList();
-                    await Task.WhenAll(temTaskStss);
-                }
+                await _dingDing.SendBotMsg($"BI,{_option.Location},/sccholrep/set-allscstats \n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                return BadRequest();
             }
-
-            return Ok(new { state = RespondCode.Ok, statsInfos });
         }
 
     }

+ 4 - 4
TEAMModelOS.FunctionV4/CosmosDB/CommonTrigger.cs

@@ -65,10 +65,10 @@ namespace TEAMModelOS.FunctionV4
                                 ///通知接收者的变更
                                 continue;
                             }
-                            else if ($"{jsond}".Equals("StatsNotice", StringComparison.OrdinalIgnoreCase)) 
-                            {
-                                var sert = 012;
-                            }
+                            //else if ($"{jsond}".Equals("StatsNotice", StringComparison.OrdinalIgnoreCase)) 
+                            //{
+                            //    var sert = 012;
+                            //}
                             else
                             {
                                 TriggerData data = element.ToObject<TriggerData>();

+ 11 - 5
TEAMModelOS.FunctionV4/HttpTrigger/BIHttpTrigger.cs

@@ -14,6 +14,7 @@ using MathNet.Numerics.LinearAlgebra.Double;
 using Microsoft.AspNetCore.Http;
 using Microsoft.Azure.Functions.Worker;
 using Microsoft.Azure.Functions.Worker.Http;
+using Microsoft.Extensions.Configuration;
 using NUnit.Framework.Constraints;
 using StackExchange.Redis;
 using TEAMModelOS.SDK.Context.Constant;
@@ -33,13 +34,17 @@ namespace TEAMModelOS.FunctionV4
         private readonly DingDing _dingDing;
         private readonly AzureStorageFactory _azureStorage;
         private readonly AzureRedisFactory _azureRedis;
+        private readonly IConfiguration _configuration;
+        private readonly IHttpClientFactory _httpClient;
 
-        public BIHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis)
+        public BIHttpTrigger(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, IConfiguration configuration, IHttpClientFactory httpClient)
         {
             _azureCosmos = azureCosmos;
             _dingDing = dingDing;
             _azureStorage = azureStorage;
             _azureRedis = azureRedis;
+            _configuration = configuration;
+            _httpClient = httpClient;
         }
 
         /// <summary>
@@ -111,7 +116,7 @@ namespace TEAMModelOS.FunctionV4
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"BIFunction, upSchoolBIRelation(),{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"BIFunction, {Environment.GetEnvironmentVariable("Option:Location")}, upSchoolBIRelation(),{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
             }
 
             return response;
@@ -166,6 +171,7 @@ namespace TEAMModelOS.FunctionV4
                         isExist = false;
 
                     statsInfo = await SchoolStatsWay.GetSingleSc(cosmosClient,redisClinet, scId);
+                    statsInfo.witRoom = ((int)await SchoolStatsWay.GetShoolWisdomRoomCount(_azureCosmos, _azureRedis, _configuration, _httpClient,_dingDing, scId)); //智慧教师
                     statsInfo.upTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 
                     if (isExist)
@@ -179,7 +185,7 @@ namespace TEAMModelOS.FunctionV4
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"BIFunction, StatsSchoolInfo() \n {ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"BIFunction,{Environment.GetEnvironmentVariable("Option:Location")}, StatsSchoolInfo() \n {ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
             }
 
             return response;
@@ -243,7 +249,7 @@ namespace TEAMModelOS.FunctionV4
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"BIFunction, SetSchoolStatsInfo() \n{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"BIFunction,{Environment.GetEnvironmentVariable("Option:Location")}, SetSchoolStatsInfo() \n{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
             }
 
             return response;
@@ -535,7 +541,7 @@ namespace TEAMModelOS.FunctionV4
             }
             catch (Exception ex)
             {
-                await _dingDing.SendBotMsg($"BIFunction, SetSchoolStatsType() \n{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
+                await _dingDing.SendBotMsg($"BIFunction,{Environment.GetEnvironmentVariable("Option:Location")}, SetSchoolStatsType() \n{ex.Message}\n{ex.StackTrace}\n{jsondata.ToJsonString()}", GroupNames.成都开发測試群組);
             }
 
             return response;

+ 14 - 0
TEAMModelOS.SDK/Models/Cosmos/BI/StaticValue.cs

@@ -19,6 +19,20 @@ namespace TEAMModelOS.SDK.Models.Cosmos.BI
         /// </summary>
         public static List<string> fileType = new() { "audio", "doc", "image", "other", "records", "res", "video"};
 
+        //取得序號產品准許使用產品代碼列表
+        public static List<string> GetSerialPermitProdcodeList()
+        {
+            List<string> allowProdCode = new List<string>(); //軟體許可產品列:HiTeach STD、TBL、PRO、HiTeach5;
+            allowProdCode.Add("J223IZ6M"); //HiTeach STD
+            allowProdCode.Add("3222C6D2"); //HiTeach TBL
+            allowProdCode.Add("J223IZAM"); //HiTeach PRO
+            allowProdCode.Add("J2236ZCX"); //HiTeach Lite
+            allowProdCode.Add("3222DNG2"); //HiTeach Mobile
+            allowProdCode.Add("3222IAVN"); //HiTeach Premium
+            allowProdCode.Add("BYJ6LZ6Z"); //HiTeach5
+            allowProdCode.Add("LZLL6ZEI"); //HiTeachCC
+            return allowProdCode;
+        }
 
     }
 }

+ 5 - 1
TEAMModelOS.SDK/Models/Service/BI/BIStatsNotice.cs

@@ -81,10 +81,14 @@ namespace TEAMModelOS.SDK.Models.Service.BI
             }
         }
 
-
+        /// <summary>
+        /// 发送消息
+        /// </summary>
+        /// <returns></returns>
         public static async Task MonitorStatsNotice() 
         {
             
+            
         }
 
     }

+ 30 - 18
TEAMModelOS.SDK/Models/Service/BI/JointlySingleQuery.cs

@@ -21,21 +21,27 @@ namespace TEAMModelOS.SDK.Models.Service.BI
         public static async Task<int> GetValueInt(CosmosClient cosmosClient, List<string> containerId, string code, string sqlTxt = null)
         {
             int totals = 0;
-            string sql = $"select value(count(c.id)) from c";
-            if (!string.IsNullOrEmpty(sqlTxt))
+            try
             {
-                sql = sqlTxt;
-            }
+                string sql = $"select value(count(c.id)) from c";
+                if (!string.IsNullOrEmpty(sqlTxt))
+                {
+                    sql = sqlTxt;
+                }
 
-            foreach (string conId in containerId)
-            {
-                await foreach (var itemInt in cosmosClient.GetContainer("TEAMModelOS", conId).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                foreach (string conId in containerId)
                 {
-                    totals += itemInt;
+                    await foreach (var itemInt in cosmosClient.GetContainer("TEAMModelOS", conId).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                    {
+                        totals += itemInt;
+                    }
                 }
+                return totals;
+            }
+            catch (Exception)
+            {
+                return totals;
             }
-
-            return totals;
         }
 
         /// <summary>
@@ -49,18 +55,24 @@ namespace TEAMModelOS.SDK.Models.Service.BI
         public static async Task<int> GetValueInt(CosmosClient cosmosClient, string container, string code, string sqlTxt = null)
         {
             int totals = 0;
-            string sql = $"select value(count(c.id)) from c";
-            if (!string.IsNullOrEmpty(sqlTxt))
+            try
             {
-                sql = sqlTxt;
-            }
+                string sql = $"select value(count(c.id)) from c";
+                if (!string.IsNullOrEmpty(sqlTxt))
+                {
+                    sql = sqlTxt;
+                }
 
-            await foreach (var itemInt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                await foreach (var itemInt in cosmosClient.GetContainer("TEAMModelOS", container).GetItemQueryIterator<int>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{code}") }))
+                {
+                    totals += itemInt;
+                }
+                return totals;
+            }
+            catch (Exception)
             {
-                totals += itemInt;
+                return totals;
             }
-
-            return totals;
         }
 
         /// <summary>   

+ 201 - 10
TEAMModelOS.SDK/Models/Service/BIStatsWay/SchoolStatsWay.cs

@@ -4,10 +4,14 @@ using DocumentFormat.OpenXml.Math;
 using MathNet.Numerics.LinearAlgebra.Double;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.Azure.Amqp.Framing;
+using Newtonsoft.Json;
 using StackExchange.Redis;
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net.Http.Headers;
+using System.Net.Http;
+using System.Net;
 using System.Text;
 using System.Text.Json;
 using System.Threading.Tasks;
@@ -16,6 +20,9 @@ using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Models.Cosmos.BI;
 using TEAMModelOS.SDK.Models.Service.BI;
+using Microsoft.Extensions.Configuration;
+using System.Configuration;
+using System.Net.Http.Json;
 
 namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
 {
@@ -27,7 +34,7 @@ namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
         /// <param name="cosmosClient"></param>
         /// <param name="scId"></param>
         /// <returns></returns>
-        public static async Task<StatsInfo> GetSingleSc(CosmosClient cosmosClient,IDatabase redisClinet, string scId, int year = 0)
+        public static async Task<StatsInfo> GetSingleSc(CosmosClient cosmosClient, IDatabase redisClinet, string scId, int year = 0)
         {
             DateTimeOffset dateTime = DateTimeOffset.UtcNow;
             if (year < dateTime.Year)
@@ -85,8 +92,8 @@ namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
             else
                 weekDay = 7;
 
-            statsInfo.weekTch = ((int)tchDouble.SubMatrix(weekDayS.DayOfYear-1, weekDay, 0, tchDouble.ColumnCount).ColumnSums().Sum());
-            statsInfo.monthTch += ((int)tchDouble.SubMatrix(monthDayS.DayOfYear-1, (dateTime.DayOfYear - monthDayS.DayOfYear+1), 0, tchDouble.ColumnCount).ColumnSums().Sum());
+            statsInfo.weekTch = ((int)tchDouble.SubMatrix(weekDayS.DayOfYear - 1, weekDay, 0, tchDouble.ColumnCount).ColumnSums().Sum());
+            statsInfo.monthTch += ((int)tchDouble.SubMatrix(monthDayS.DayOfYear - 1, (dateTime.DayOfYear - monthDayS.DayOfYear + 1), 0, tchDouble.ColumnCount).ColumnSums().Sum());
 
             //statsInfo.dayTch = await JointlySingleQuery.GetValueInt(cosmosClient, "School",  $"Teacher-{scBase.id}", $"{tchSql} and {dayWhereSql} ");
             //statsInfo.weekTch = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Teacher-{scBase.id}", $"{tchSql} and  {weekWhereSql}");
@@ -98,17 +105,18 @@ namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
             statsInfo.stuYear = stuDoubles;
             statsInfo.dayStu = ((int)stuDoubles[dateTime.DayOfYear]);
             DenseMatrix stuDouble = DenseMatrix.OfColumns(new List<List<double>>() { stuDoubles });
-            statsInfo.weekStu = ((int)stuDouble.SubMatrix(weekDayS.DayOfYear-1, weekDay, 0, stuDouble.ColumnCount).ColumnSums().Sum());
-            statsInfo.monthStu += ((int)stuDouble.SubMatrix(monthDayS.DayOfYear-1, (dateTime.DayOfYear - monthDayS.DayOfYear+1), 0, stuDouble.ColumnCount).ColumnSums().Sum());
+            statsInfo.weekStu = ((int)stuDouble.SubMatrix(weekDayS.DayOfYear - 1, weekDay, 0, stuDouble.ColumnCount).ColumnSums().Sum());
+            statsInfo.monthStu += ((int)stuDouble.SubMatrix(monthDayS.DayOfYear - 1, (dateTime.DayOfYear - monthDayS.DayOfYear + 1), 0, stuDouble.ColumnCount).ColumnSums().Sum());
 
             //statsInfo.dayStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {dayWhereSql}");
             //statsInfo.weekStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {weekWhereSql}");
             //statsInfo.monthStu = await JointlySingleQuery.GetValueInt(cosmosClient, "Student", $"Base-{scBase.id}", $"{currSql} where {monthWhereSql}");
             statsInfo.stuUpTime = dateTime.ToUnixTimeMilliseconds();
 
-            statsInfo.room = await JointlySingleQuery.GetValueInt(cosmosClient, "School",  $"Room-{scBase.id}" ,currSql);
-            statsInfo.witRoom = await JointlySingleQuery.GetValueInt(cosmosClient, "School",  $"Room-{scBase.id}", $"{currSql} where (c.serial != null or c.serial != '' or IS_DEFINED(c.serial) = true)");
-            statsInfo.resourceCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School",  $"Bloblog-{scBase.id}", currSql);
+            statsInfo.room = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Room-{scBase.id}", currSql);
+            //statsInfo.witRoom = await JointlySingleQuery.GetValueInt(cosmosClient, "School",  $"Room-{scBase.id}", $"{currSql} where (c.serial != null or c.serial != '' or IS_DEFINED(c.serial) = true)");
+
+            statsInfo.resourceCnt = await JointlySingleQuery.GetValueInt(cosmosClient, "School", $"Bloblog-{scBase.id}", currSql);
 
             statsInfo.upTime = dateTime.ToUnixTimeMilliseconds();
             statsInfo.lesson = await LessonRecordStatsWay.GetSchoolAll(cosmosClient, statsInfo.schoolId, year);
@@ -136,7 +144,7 @@ namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
                 pk = "Statistics",
                 code = "Statistics",
                 name = area == null ? "" : area.name,
-                areaId = area == null ? "" :area.id,
+                areaId = area == null ? "" : area.id,
                 picture = "",
                 tch = statsInfos.Select(s => s.tch).Sum(),
                 dayTch = statsInfos.Select(s => s.dayTch).Sum(),
@@ -188,7 +196,190 @@ namespace TEAMModelOS.SDK.Models.Service.BIStatsWay
             areaInfo.activity.year = BICommonWay.ManyDoubleMerge(statsInfos.Select(s => s.activity.year).Where(w => w.Count > 0).ToList());
 
             return areaInfo;
+
+        }
+
+        /// <summary>
+        /// 计算学校智慧教室数
+        /// </summary>
+        /// <param name="_azureCosmos"></param>
+        /// <param name="_azureRedis"></param>
+        /// <param name="_configuration"></param>
+        /// <param name="_httpClient"></param>
+        /// <param name="code"></param>
+        /// <returns></returns>
+        public static async Task<double> GetShoolWisdomRoomCount(AzureCosmosFactory _azureCosmos, AzureRedisFactory _azureRedis, IConfiguration _configuration, IHttpClientFactory _httpClient, DingDing _dingDing, string code)
+        {
+            try
+            {
+                var db = _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School");
+                var r8 = _azureRedis.GetRedisClient(8);
+
+                List<SchoolProductSerial> serial = new(); //承接DB資料用:序號
+                List<deviceForCoreService> uuidList = new(); //要向CoreService詢問deviceID及硬體資訊的UUID列表
+                long UTCNow = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
+
+                //軟體
+                List<string> serialPermitList = StaticValue.GetSerialPermitProdcodeList();
+                string serialPermitJsonStr = JsonConvert.SerializeObject(serialPermitList);
+                string serialQueryText = $"SELECT * FROM c WHERE c.dataType = 'serial' AND ARRAY_CONTAINS({serialPermitJsonStr}, c.prodCode)";
+                await foreach (var itemsr in db.GetItemQueryStreamIterator(queryText: serialQueryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Product-{code}") }))
+                {
+                    using var json = await JsonDocument.ParseAsync(itemsr.ContentStream);
+                    if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
+                    {
+                        deviceForCoreService uuidForCore;
+                        foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        {
+                            serial.Add(obj.ToObject<SchoolProductSerial>());
+                            if (obj.TryGetProperty("deviceBound", out JsonElement deviceBoundJobj) && !string.IsNullOrWhiteSpace(deviceBoundJobj.ToString()))
+                            {
+                                foreach (var deviceBoundTmpRow in deviceBoundJobj.EnumerateArray())
+                                {
+                                    uuidForCore = new deviceForCoreService
+                                    {
+                                        sn = (!string.IsNullOrWhiteSpace(Convert.ToString(obj.GetProperty("serial")))) ? Convert.ToString(obj.GetProperty("serial")) : null,
+                                        uuid1 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundTmpRow.GetProperty("uuid")))) ? Convert.ToString(deviceBoundTmpRow.GetProperty("uuid")) : null,
+                                        uuid2 = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundTmpRow.GetProperty("uuid2")))) ? Convert.ToString(deviceBoundTmpRow.GetProperty("uuid2")) : null,
+                                        device_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundTmpRow.GetProperty("deviceId")))) ? Convert.ToString(deviceBoundTmpRow.GetProperty("deviceId")) : null,
+                                        class_id = (!string.IsNullOrWhiteSpace(Convert.ToString(deviceBoundTmpRow.GetProperty("classId")))) ? Convert.ToString(deviceBoundTmpRow.GetProperty("classId")) : null
+                                    };
+                                    uuidList.Add(uuidForCore);
+                                }
+                            }
+                        }
+                    }
+                }
+                ////取得DeviceInfo From Core 並更新序號資料
+                List<deviceFromCoreService> coreUuidList = (List<deviceFromCoreService>)GetDeviceFromCoreAsync(uuidList, _configuration, _httpClient).GetAwaiter().GetResult();
+                List<deviceBoundExt> deviceBoundArray;
+                List<deviceBoundExt> counts = new();
+                List<deviceFromCoreService> coreUuid;
+                deviceForCoreService deviceBoundRow;
+                deviceBoundExt deviceBoundExt;
+                List<SchoolProductSerial> updSchoolProductSerialList = new List<SchoolProductSerial>(); //更新學校產品序號用
+
+                foreach (SchoolProductSerial serialRow in serial)
+                {
+                    deviceBoundArray = new List<deviceBoundExt>();
+                    coreUuid = coreUuidList
+                           .Where((deviceFromCoreService x) => x.sn == serialRow.serial)
+                           .ToList();
+                    foreach (deviceFromCoreService deviceRow in coreUuid)
+                    {
+                        if (!string.IsNullOrWhiteSpace(deviceRow.uuid1) || !string.IsNullOrWhiteSpace(deviceRow.uuid2) || !string.IsNullOrWhiteSpace(deviceRow.device_id)) //uuid1、uuid2、device_id 任一欄有值
+                        {
+                            //前端顯示用
+                            deviceBoundRow = uuidList.Where(u => u.sn == deviceRow.sn && u.uuid1 == deviceRow.uuid1 && u.uuid2 == deviceRow.uuid2).FirstOrDefault();
+                            deviceBoundExt = new deviceBoundExt
+                            {
+                                uuid = deviceBoundRow.uuid1,
+                                uuid2 = deviceBoundRow.uuid2,
+                                classId = deviceBoundRow.class_id,
+                                deviceId = deviceRow.device_id,
+                                os = deviceRow.os,
+                                ip = deviceRow.local_ip,
+                                cpu = deviceRow.cpu,
+                                pcname = deviceRow.pc_name,
+                                osver = deviceRow.os_ver
+                            };
+                            deviceBoundArray.Add(deviceBoundExt);
+                        }
+                    }
+                    if (deviceBoundArray.Count.Equals(0)) //無法取得CS的硬體資訊,則用序號的硬體資訊帶入
+                    {
+                        if (serialRow.deviceBound != null)
+                        {
+                            foreach (deviceBound serialRowDeviceBound in serialRow.deviceBound)
+                            {
+                                if (!string.IsNullOrEmpty(serialRowDeviceBound.uuid) || !string.IsNullOrEmpty(serialRowDeviceBound.uuid2))
+                                {
+                                    deviceBoundExt = new deviceBoundExt
+                                    {
+                                        uuid = serialRowDeviceBound.uuid,
+                                        uuid2 = serialRowDeviceBound.uuid2,
+                                        classId = serialRowDeviceBound.classId,
+                                        deviceId = serialRowDeviceBound.deviceId
+                                    };
+                                    deviceBoundArray.Add(deviceBoundExt);
+                                }
+                            }
+                        }
+                    }
+                    //序號更新
+                    //updSchoolProductSerialList.Add(serialRow);
+                    counts.AddRange(deviceBoundArray);
+                    //await db.ReplaceItemAsync<SchoolProductSerial>(serialRow, serialRow.id, new PartitionKey($"Product-{school_code}"));
+                }
+                //取得CC授權使用狀態
+                var hashs = await r8.HashGetAllAsync($"CC:License:{code}");
+                var ccuser = hashs.Select(x => JsonDocument.Parse(x.Value.ToString())).ToList();
+
+                //更新學校產品序號
+                //_ = UpdupdSchoolProductSerialListAsync(updSchoolProductSerialList, school_code.GetString());
+                double roomCount = counts.Count + ccuser.Count;
+                return roomCount;
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"BI, {Environment.GetEnvironmentVariable("Option:Location")},GetShoolWisdomRoomCount() {code} \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
+                return 0;
+            }
+        }
+
+
+        private static async Task<List<deviceFromCoreService>> GetDeviceFromCoreAsync(List<deviceForCoreService> uuidList, IConfiguration _configuration, IHttpClientFactory _httpClient)
+        {
+            List<deviceFromCoreService> result = new List<deviceFromCoreService>();
+            try
+            {
+                string url = _configuration.GetValue<string>("HaBookAuth:CoreService:deviceinfo");
+                string AccessToken = await getCoreAccessToken(_configuration, _httpClient);
+                var client = _httpClient.CreateClient();
+                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
+                string uuidListJson = JsonConvert.SerializeObject(uuidList);
+                var content = new StringContent(uuidListJson, Encoding.UTF8, "application/json");
+                HttpResponseMessage responseMessage = await client.PostAsync(url, content);
+                if (responseMessage.StatusCode == HttpStatusCode.OK)
+                {
+                    string responseBody = responseMessage.Content.ReadAsStringAsync().Result;
+                    result = System.Text.Json.JsonSerializer.Deserialize<List<deviceFromCoreService>>(responseBody.ToString());
+                }
+                return result;
+            }
+            catch (Exception ex)
+            {
+                return result;
+            }
+        }
+        private static async Task<string> getCoreAccessToken(IConfiguration _configuration, IHttpClientFactory _httpClient)
+        {
+            string AccessToken = "";
+            try
+            {
+                string Url = _configuration.GetValue<string>("HaBookAuth:CoreAPI") + "/oauth2/token";
+                string GrantType = "device";
+                string ClientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
+                string Secret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
+                var content = new { grant_type = GrantType, client_id = ClientID, client_secret = Secret };
+                var response = await _httpClient.CreateClient().PostAsJsonAsync($"{Url}", content);
+                if (response.IsSuccessStatusCode)
+                {
+                    string responseBody = response.Content.ReadAsStringAsync().Result;
+                    using (JsonDocument document = JsonDocument.Parse(responseBody.ToString()))
+                    {
+                        if (document.RootElement.TryGetProperty("access_token", out JsonElement AccessTokenObj))
+                        {
+                            AccessToken = AccessTokenObj.ToString();
+                        }
+                    }
+                }
+                return AccessToken;
+            }
+            catch (Exception ex)
+            {
+                return AccessToken;
+            }
         }
-       
     }
 }