|
@@ -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;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
}
|