using Microsoft.Azure.Cosmos;
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using TEAMModelOS.SDK.DI;
using TEAMModelOS.SDK.Extension;
using TEAMModelOS.SDK.Models.Cosmos;
using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
using TEAMModelOS.SDK.Models.Cosmos;
namespace TEAMModelOS.SDK.Models.Service.BI
{
public static class BIProdAnalysis
{
///
/// 1.取得某日CS IOT 資料
/// 2.生成IES5各校產品分析統計資料
/// 3.生成TMID產品分析統計資料
/// 4.生成DeviceID產品分析統計資料
///
///
///
/// 年
/// 月(2位數)
/// 日(2位數)
///
public static async Task BICreatDailyAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, CosmosClient _azureCosmosClientCsv2, CosmosClient _azureCosmosClientCsv2CnRead, DingDing _dingDing, string y, string m, string d)
{
List IotTeachingDataList = await BIGetDailyRedisProdAnalData(_azureRedis, _azureCosmosClientCsv2, _dingDing, y, m, d); //取得Redis IOT 每日資訊
await CreatIes5ProdAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2CnRead, _dingDing, y, m, d, IotTeachingDataList); //生成學校CosmosDB年月日統計資料
await CreatTmidProdAnalData(_azureRedis, _azureCosmosClient, _dingDing, y, m, d, IotTeachingDataList); //生成TMID CosmosDB年月日統計資料
}
///
/// 取得某日CS IOT 資料
///
///
///
/// 年
/// 月(2位數)
/// 日(2位數)
///
public static async Task> BIGetDailyRedisProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClientCsv2, DingDing _dingDing, string y, string m, string d)
{
List IotTeachingDataList = new List();
try
{
var redisClinet2 = _azureRedis.GetRedisClient(2);
var datetime = DateTimeOffset.UtcNow;
var ynow = datetime.Year;
HashSet tmids = new HashSet();
Dictionary tmidSchidDic = new Dictionary();
//取得CS Redis TeachingData (IOT紀錄只有三個月分)
if (y.Equals(ynow.ToString()))
{
bool TeachingDataExist = await redisClinet2.KeyExistsAsync($"TeachingData:{m}{d}");
if (TeachingDataExist)
{
RedisValue[] TeachingData = redisClinet2.ListRange($"TeachingData:{m}{d}");
foreach (RedisValue tdataRow in TeachingData)
{
string[] tdata = tdataRow.ToString().Split(',');
IotTeachingData IotTeachingData = new IotTeachingData();
IotTeachingData.timestamp = Convert.ToInt64(tdata[0]);
IotTeachingData.deviceId = tdata[1];
IotTeachingData.channel = tdata[2];
IotTeachingData.tmid = tdata[3];
IotTeachingData.schoolId = tdata[4];
IotTeachingData.useIES = tdata[5];
IotTeachingData.useIES5Resource = (!string.IsNullOrWhiteSpace(tdata[6])) ? Convert.ToInt32(tdata[6]) : 0;
IotTeachingData.useWebIrs = tdata[7];
IotTeachingData.useDeviceIrs = tdata[8];
IotTeachingData.useHaboard = tdata[9];
IotTeachingData.useHita = tdata[10];
IotTeachingData.lessonLengMin = (!string.IsNullOrWhiteSpace(tdata[11])) ? Convert.ToInt32(tdata[11]) : 0;
IotTeachingData.stuShow = (!string.IsNullOrWhiteSpace(tdata[12])) ? Convert.ToInt32(tdata[12]) : 0;
IotTeachingData.tPoint = (!string.IsNullOrWhiteSpace(tdata[13])) ? Convert.ToInt32(tdata[13]) : 0;
IotTeachingData.lTypeCoop = tdata[14];
IotTeachingData.lTypeIact = tdata[15];
IotTeachingData.lTypeMis = tdata[16];
IotTeachingData.lTypeTst = tdata[17];
IotTeachingData.lTypeDif = tdata[18];
IotTeachingData.authType = tdata[19];
IotTeachingData.mission = (!string.IsNullOrWhiteSpace(tdata[20])) ? Convert.ToInt32(tdata[20]) : 0;
IotTeachingData.missionFin = (!string.IsNullOrWhiteSpace(tdata[21])) ? Convert.ToInt32(tdata[21]) : 0;
IotTeachingData.item = (!string.IsNullOrWhiteSpace(tdata[22])) ? Convert.ToInt32(tdata[22]) : 0;
IotTeachingData.interact = (!string.IsNullOrWhiteSpace(tdata[23])) ? Convert.ToInt32(tdata[23]) : 0;
IotTeachingData.ip = (tdata.Length > 24) ? tdata[24] : "";
IotTeachingData.version = (tdata.Length > 25) ? tdata[25] : "";
IotTeachingData.sendSok = (tdata.Length > 26 && !string.IsNullOrWhiteSpace(tdata[26])) ? tdata[26] : "0";
IotTeachingData.learnPeer = (tdata.Length > 27 && !string.IsNullOrWhiteSpace(tdata[27])) ? tdata[27] : "0";
IotTeachingData.learnCoop = (tdata.Length > 28 && !string.IsNullOrWhiteSpace(tdata[28])) ? tdata[28] : "0";
IotTeachingData.useWordCloud = (tdata.Length > 29 && !string.IsNullOrWhiteSpace(tdata[29])) ? tdata[29] : "0";
IotTeachingData.useClouDAS = (tdata.Length > 30 && !string.IsNullOrWhiteSpace(tdata[30])) ? tdata[30] : "0";
IotTeachingData.useGPT = (tdata.Length > 31 && !string.IsNullOrWhiteSpace(tdata[31])) ? tdata[31] : "0";
IotTeachingData.useIes5Test = (tdata.Length > 32 && !string.IsNullOrWhiteSpace(tdata[32])) ? tdata[32] : "0";
IotTeachingData.usePaperTest = (tdata.Length > 33 && !string.IsNullOrWhiteSpace(tdata[33])) ? tdata[33] : "0";
IotTeachingData.useExcelTest = (tdata.Length > 34 && !string.IsNullOrWhiteSpace(tdata[34])) ? tdata[34] : "0";
IotTeachingData.useScoreBoard = (tdata.Length > 35 && !string.IsNullOrWhiteSpace(tdata[35])) ? tdata[35] : "0"; //課堂中使用記分板
IotTeachingData.learnParticipation = (tdata.Length > 36 && !string.IsNullOrWhiteSpace(tdata[36])) ? Convert.ToInt32(tdata[36]) : 0; //學習參與度指數
IotTeachingData.learnParticipationCnt = (IotTeachingData.learnParticipation > 0) ? "1" : "0"; //是否計算學習參與度
IotTeachingData.coopMission = (tdata.Length > 37 && !string.IsNullOrWhiteSpace(tdata[37])) ? Convert.ToInt32(tdata[37]) : 0; //協作任務數
IotTeachingData.coopWork = (tdata.Length > 38 && !string.IsNullOrWhiteSpace(tdata[38])) ? Convert.ToInt32(tdata[38]) : 0; //協作作品數
IotTeachingData.coopContributionT = (tdata.Length > 39 && !string.IsNullOrWhiteSpace(tdata[39])) ? Convert.ToInt32(tdata[39]) : 0; //協作總貢獻度
IotTeachingData.peerAct = (tdata.Length > 40 && !string.IsNullOrWhiteSpace(tdata[40])) ? Convert.ToInt32(tdata[40]) : 0; //互評活動次數
IotTeachingData.peerStuParticipationT = (tdata.Length > 41 && !string.IsNullOrWhiteSpace(tdata[41])) ? Convert.ToInt32(tdata[41]) : 0; //互評學生參與總次數
IotTeachingData.useTransMode = (tdata.Length > 42 && !string.IsNullOrWhiteSpace(tdata[42])) ? tdata[42] : "0"; //有使用透明模式
IotTeachingData.useMiniMode = (tdata.Length > 43 && !string.IsNullOrWhiteSpace(tdata[43])) ? tdata[43] : "0"; //有使用最小化模式
IotTeachingDataList.Add(IotTeachingData);
if(!string.IsNullOrWhiteSpace(IotTeachingData.tmid))
{
tmids.Add(IotTeachingData.tmid);
}
}
}
}
//取得TMID進階資料,以弱強歸戶學校補足學校ID
QueryDefinition querye = new QueryDefinition(@"SELECT c.id, c.schoolCode, c.schoolCodeW FROM c WHERE (ARRAY_CONTAINS(@key, c.id) AND ( (IS_DEFINED(c.schoolCode) AND IS_STRING(c.schoolCode)) OR (IS_DEFINED(c.schoolCodeW) AND IS_STRING(c.schoolCodeW)) ))").WithParameter("@key", tmids);
await foreach (var item in _azureCosmosClientCsv2.GetContainer("Core", "ID2")
.GetItemQueryStreamIteratorQuery(querye, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("base-ex")}))
{
using var json = await JsonDocument.ParseAsync(item.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var doc in json.RootElement.GetProperty("Documents").EnumerateArray())
{
string id = doc.GetProperty("id").GetString();
string schoolCode = (doc.TryGetProperty("schoolCode", out JsonElement _tmidSchoolCode)) ? _tmidSchoolCode.GetString() : string.Empty;
string schoolCodeW = (doc.TryGetProperty("schoolCodeW", out JsonElement _tmidSchoolCodeW)) ? _tmidSchoolCodeW.GetString() : string.Empty;
List IotTeachingDatas = IotTeachingDataList.Where(x => x.tmid.Equals(id) && string.IsNullOrWhiteSpace(x.schoolId)).ToList();
if(IotTeachingDatas.Count > 0)
{
foreach(IotTeachingData IotTeachingDataRow in IotTeachingDatas)
{
if (!string.IsNullOrWhiteSpace(schoolCode))
{
IotTeachingDataRow.schoolId = schoolCode;
}
else if (!string.IsNullOrWhiteSpace(schoolCodeW))
{
IotTeachingDataRow.schoolId = schoolCodeW;
}
}
}
}
}
}
return IotTeachingDataList;
}
catch (Exception ex)
{
_ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},BIGetDailyRedisProdAnalData() 取得每日CoreServiceIOT資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
return IotTeachingDataList;
}
}
//年月日 IES5學校IOT產品分析數據生成
///參數:某日IOT 教學資料列
///1.生成 Redis ProdAnalysis:Month
///2.生成 CosmosDB Month
///3.生成 CosmosDB 系統所有學校數值加總
private static async Task CreatIes5ProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, CosmosClient _azureCosmosClientCsv2CnRead, DingDing _dingDing, string y, string m, string d, List IotTeachingDataList)
{
try
{
var redisClinet8 = _azureRedis.GetRedisClient(8);
List crtVirtualSchoolId = new List(); //虛擬學校創建ID列表
List calPropList = new List() { "lessonRecord", "useIES", "useIES5Resource", "useWebIrs", "useDeviceIrs", "useHaboard", "useHita", "lessonLengMin", "lessonLeng0", "stuShow", "stuLessonLengMin", "tGreen", "tLesson", "lTypeCoop", "lTypeIact", "lTypeMis", "lTypeTst", "lTypeDif", "lTypeNone", "lessonCnt928", "lessonCntId", "lessonCntDevice", "lessonCntIdDevice", "mission", "missionFin", "item", "interact", "sendSok", "learnPeer", "learnCoop", "useWordCloud", "useClouDAS", "useGPT", "useIes5Test", "usePaperTest", "useExcelTest", "useScoreBoard", "learnParticipationCnt", "learnParticipationT", "coopMission", "coopWork", "coopContributionT", "peerAct", "peerStuParticipationT", "useTransMode", "useMiniMode" }; //要計算的ProdAnalysis欄位列表
List ProdAnalysisList = new List();
if (IotTeachingDataList.Count > 0)
{
foreach (IotTeachingData IotTeachingDatRow in IotTeachingDataList)
{
string schoolId = (!string.IsNullOrWhiteSpace(IotTeachingDatRow.schoolId)) ? IotTeachingDatRow.schoolId.ToLower() : "noschoolid"; //noschoolid:無任何學校ID
if (!schoolId.Equals("noschoolid") && !schoolId.Equals("allschool") && !crtVirtualSchoolId.Contains(schoolId))
{
crtVirtualSchoolId.Add(schoolId);
}
string toolType = string.Empty;
if (!string.IsNullOrWhiteSpace(IotTeachingDatRow.deviceId))
{
if (IotTeachingDatRow.deviceId.Contains("HiTeachCC-")) toolType = "HiTeachCC";
else if (IotTeachingDatRow.deviceId.Contains("HiTeach-")) toolType = "HiTeach";
else if (IotTeachingDatRow.deviceId.Contains("HiTA-")) toolType = "HiTA";
}
//學校數據生成
if (!string.IsNullOrWhiteSpace(schoolId) && !string.IsNullOrWhiteSpace(toolType))
{
bool addFlg = false;
ProdAnalysis prodAnalysisRow = ProdAnalysisList.Where(s => s.schoolId.Equals(schoolId) && s.toolType.Equals(toolType)).FirstOrDefault();
//無此校數據=>創建
if (prodAnalysisRow == null)
{
prodAnalysisRow = new ProdAnalysis();
prodAnalysisRow.schoolId = schoolId;
prodAnalysisRow.toolType = toolType;
addFlg = true;
}
//欄位加總
if (!string.IsNullOrWhiteSpace(IotTeachingDatRow.deviceId) && !prodAnalysisRow.deviceList.Contains(IotTeachingDatRow.deviceId))
{
prodAnalysisRow.deviceList.Add(IotTeachingDatRow.deviceId);
}
prodAnalysisRow.deviceCnt = prodAnalysisRow.deviceList.Count;
switch (IotTeachingDatRow.authType)
{
case "0": //928授權
if (!prodAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) prodAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
prodAnalysisRow.lessonCnt928++;
break;
case "1": //ID授權
if (!prodAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) prodAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
prodAnalysisRow.lessonCntId++;
break;
case "2": //機器授權
if (!prodAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) prodAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
prodAnalysisRow.lessonCntDevice++;
break;
case "3": //ID+機器授權
if (!prodAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) prodAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
prodAnalysisRow.lessonCntIdDevice++;
break;
}
prodAnalysisRow.deviceNoAuth = prodAnalysisRow.deviceNoAuthList.Count;
prodAnalysisRow.deviceAuth = prodAnalysisRow.deviceAuthList.Count;
if (!string.IsNullOrWhiteSpace(IotTeachingDatRow.tmid) && !prodAnalysisRow.tmidList.Contains(IotTeachingDatRow.tmid))
{
prodAnalysisRow.tmidList.Add(IotTeachingDatRow.tmid);
}
prodAnalysisRow.tmidCnt = prodAnalysisRow.tmidList.Count;
prodAnalysisRow.lessonRecord++;
if (IotTeachingDatRow.useIES.Equals("1")) prodAnalysisRow.useIES++;
prodAnalysisRow.useIES5Resource += IotTeachingDatRow.useIES5Resource;
if (IotTeachingDatRow.useWebIrs.Equals("1")) prodAnalysisRow.useWebIrs++;
if (IotTeachingDatRow.useDeviceIrs.Equals("1")) prodAnalysisRow.useDeviceIrs++;
if (IotTeachingDatRow.useHaboard.Equals("1")) prodAnalysisRow.useHaboard++;
if (IotTeachingDatRow.useHita.Equals("1")) prodAnalysisRow.useHita++;
prodAnalysisRow.lessonLengMin += IotTeachingDatRow.lessonLengMin;
if (IotTeachingDatRow.lessonLengMin.Equals(0)) prodAnalysisRow.lessonLeng0++;
prodAnalysisRow.stuShow += IotTeachingDatRow.stuShow;
prodAnalysisRow.stuLessonLengMin += IotTeachingDatRow.lessonLengMin * IotTeachingDatRow.stuShow;
if (IotTeachingDatRow.tPoint >= 70) prodAnalysisRow.tGreen++;
if (IotTeachingDatRow.lessonLengMin >= 10 && IotTeachingDatRow.tPoint > 0) prodAnalysisRow.tLesson++;
if (IotTeachingDatRow.lTypeCoop.Equals("1")) prodAnalysisRow.lTypeCoop++;
if (IotTeachingDatRow.lTypeIact.Equals("1")) prodAnalysisRow.lTypeIact++;
if (IotTeachingDatRow.lTypeMis.Equals("1")) prodAnalysisRow.lTypeMis++;
if (IotTeachingDatRow.lTypeTst.Equals("1")) prodAnalysisRow.lTypeTst++;
if (IotTeachingDatRow.lTypeDif.Equals("1")) prodAnalysisRow.lTypeDif++;
if (IotTeachingDatRow.lTypeCoop.Equals("0") && IotTeachingDatRow.lTypeIact.Equals("0") && IotTeachingDatRow.lTypeMis.Equals("0") && IotTeachingDatRow.lTypeTst.Equals("0") && IotTeachingDatRow.lTypeDif.Equals("0")) prodAnalysisRow.lTypeNone++;
prodAnalysisRow.mission += IotTeachingDatRow.mission;
prodAnalysisRow.missionFin += IotTeachingDatRow.missionFin;
prodAnalysisRow.item += IotTeachingDatRow.item;
prodAnalysisRow.interact += IotTeachingDatRow.interact;
if (IotTeachingDatRow.sendSok.Equals("1")) prodAnalysisRow.sendSok++;
if (IotTeachingDatRow.learnPeer.Equals("1")) prodAnalysisRow.learnPeer++;
if (IotTeachingDatRow.learnCoop.Equals("1")) prodAnalysisRow.learnCoop++;
if (IotTeachingDatRow.useWordCloud.Equals("1")) prodAnalysisRow.useWordCloud++;
if (IotTeachingDatRow.useClouDAS.Equals("1")) prodAnalysisRow.useClouDAS++;
if (IotTeachingDatRow.useGPT.Equals("1")) prodAnalysisRow.useGPT++;
if (IotTeachingDatRow.useIes5Test.Equals("1")) prodAnalysisRow.useIes5Test++;
if (IotTeachingDatRow.usePaperTest.Equals("1")) prodAnalysisRow.usePaperTest++;
if (IotTeachingDatRow.useExcelTest.Equals("1")) prodAnalysisRow.useExcelTest++;
if (IotTeachingDatRow.useScoreBoard.Equals("1")) prodAnalysisRow.useScoreBoard++; //課堂中使用記分板
if (IotTeachingDatRow.learnParticipationCnt.Equals("1")) prodAnalysisRow.learnParticipationCnt++; //學習參與度次數
prodAnalysisRow.learnParticipationT += IotTeachingDatRow.learnParticipation; //學習參與度指數(總和)
decimal learnParticipationTmp = (prodAnalysisRow.learnParticipationCnt > 0) ? (decimal)prodAnalysisRow.learnParticipationT / (decimal)prodAnalysisRow.learnParticipationCnt : 0;
prodAnalysisRow.learnParticipation = Math.Round(learnParticipationTmp, 2); //學習參與度指數(平均)
prodAnalysisRow.coopMission += IotTeachingDatRow.coopMission; //協作任務數
prodAnalysisRow.coopWork += IotTeachingDatRow.coopWork; //協作作品數
prodAnalysisRow.coopContributionT += IotTeachingDatRow.coopContributionT; //協作總貢獻度
prodAnalysisRow.peerAct += IotTeachingDatRow.peerAct; //互評活動次數
prodAnalysisRow.peerStuParticipationT += IotTeachingDatRow.peerStuParticipationT; //互評學生參與總次數
if (IotTeachingDatRow.useTransMode.Equals("1")) prodAnalysisRow.useTransMode++; //有使用透明模式
if (IotTeachingDatRow.useMiniMode.Equals("1")) prodAnalysisRow.useMiniMode++; //有使用最小化模式
if (addFlg)
{
ProdAnalysisList.Add(prodAnalysisRow);
}
}
}
}
//1.記入IES5 Redis ProdAnalysis:Day
//2.記入IES5 CosmosDB Day
if (ProdAnalysisList.Count > 0)
{
//資料整形
Dictionary> redisSchFieldDic = new Dictionary>(); //架構: key => schId => schJsonContent
List cosmosSchList = new List();
Dictionary cosmosAllSchSumDayDic = new Dictionary();
foreach (ProdAnalysis prodAnalysisRow in ProdAnalysisList)
{
//Redis整形
string toolType = prodAnalysisRow.toolType;
string schoolId = prodAnalysisRow.schoolId;
string hkey = $"ProdAnalysis:Day:{toolType}:{y}{m}{d}";
string fieldContent = prodAnalysisRow.ToJsonString();
if (redisSchFieldDic.ContainsKey(hkey)) redisSchFieldDic[hkey].Add(schoolId, fieldContent);
else redisSchFieldDic.Add(hkey, new Dictionary() { { schoolId, fieldContent } });
//CosmosDB整形
ProdAnalysisCosmos ProdAnalysisCosmosRow = prodAnalysisRow.ToJsonString().ToObject();
ProdAnalysisCosmosRow.date = $"{y}{m}{d}";
ProdAnalysisCosmosRow.year = Convert.ToInt32(y, 10);
ProdAnalysisCosmosRow.month = Convert.ToInt32(m, 10);
ProdAnalysisCosmosRow.day = Convert.ToInt32(d, 10);
DateTimeOffset dateTime = new DateTimeOffset(ProdAnalysisCosmosRow.year, ProdAnalysisCosmosRow.month, ProdAnalysisCosmosRow.day, 0, 0, 0, TimeSpan.Zero);
ProdAnalysisCosmosRow.dateTime = dateTime.ToUnixTimeSeconds();
ProdAnalysisCosmosRow.id = $"{ProdAnalysisCosmosRow.toolType}-{ProdAnalysisCosmosRow.date}-{schoolId}";
ProdAnalysisCosmosRow.dateUnit = "day";
ProdAnalysisCosmosRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
cosmosSchList.Add(ProdAnalysisCosmosRow);
}
//記入Redis
if (redisSchFieldDic.Count > 0)
{
foreach (KeyValuePair> hkeyItem in redisSchFieldDic)
{
//記入Redis
string hkey = hkeyItem.Key;
List hvalList = new List();
Dictionary fieldDic = hkeyItem.Value;
foreach (KeyValuePair schItem in fieldDic)
{
string schoolId = schItem.Key;
string fieldContent = schItem.Value;
hvalList.Add(new HashEntry($"{schoolId}", fieldContent));
}
await redisClinet8.HashSetAsync(hkey, hvalList.ToArray());
}
}
//記入CosmosDB
if (cosmosSchList.Count > 0)
{
foreach (ProdAnalysisCosmos cosmosSchRow in cosmosSchList)
{
//各校每日CosmosDB記入
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosSchRow);
//所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
cosmosAllSchSumDayDic = GenAnalysisRowSumData(cosmosAllSchSumDayDic, cosmosSchRow, calPropList, "day");
}
//每日所有學校數據總計CosmosDB記入
foreach (KeyValuePair schItem in cosmosAllSchSumDayDic)
{
string toolType = schItem.Key;
ProdAnalysisCosmos cosmosAllSchSumDay = schItem.Value;
cosmosAllSchSumDay.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosAllSchSumDay);
}
}
}
//取 Redis 該月所有 ProdAnalysis:Day
//1.生成 Redis ProdAnalysis:Month
//2.生成 CosmosDB Month
Dictionary> ProdAnalysisListMonth = new Dictionary>();
Dictionary cosmosAllSchSumMonthDic = new Dictionary();
List cosmosSchListMonth = new List();
string patternD = $"ProdAnalysis:Day:HiT*:{y}{m}*";
List keysDayList = ScanRedisKeysByPattern(_azureRedis, patternD);
if (keysDayList.Count > 0)
{
foreach (string keyDay in keysDayList)
{
string[] keyItemList = keyDay.Split(':'); //ProdAnalysis:Day:HiTeach:20230326
string toolType = keyItemList[2];
string dateStrD = keyItemList[3];
string dateStrD_y = string.Empty;
string dateStrD_m = string.Empty;
string dateStrD_d = string.Empty;
Regex rgx = new Regex(@"[0-9]{8}");
if (rgx.IsMatch(dateStrD))
{
dateStrD_y = dateStrD.Substring(0, 4);
dateStrD_m = dateStrD.Substring(4, 2);
dateStrD_d = dateStrD.Substring(6, 2);
}
string prodAnalMonthKey = $"ProdAnalysis:Month:{toolType}:{dateStrD_y}{dateStrD_m}";
bool ProdAnalysisDayExist = await redisClinet8.KeyExistsAsync(keyDay);
if (ProdAnalysisDayExist && !string.IsNullOrWhiteSpace(dateStrD_y) && !string.IsNullOrWhiteSpace(dateStrD_m) && !string.IsNullOrWhiteSpace(dateStrD_d))
{
HashEntry[] hsetDay = redisClinet8.HashGetAll(keyDay); //某日 ProdAnalysis:Day所有學校的統計項目
foreach (HashEntry hset in hsetDay)
{
string keySchId = hset.Name;
string valSchDataJson = hset.Value;
ProdAnalysis SchDataTodo = valSchDataJson.ToObject();
//Redis Month 資料生成
if (ProdAnalysisListMonth.ContainsKey(prodAnalMonthKey)) //月Dic已有此key => 分校累加
{
if (ProdAnalysisListMonth[$"{prodAnalMonthKey}"].ContainsKey($"{keySchId}"))
{
ProdAnalysis SchDataNow = ProdAnalysisListMonth[$"{prodAnalMonthKey}"][$"{keySchId}"];
foreach (PropertyInfo propertyInfo in SchDataNow.GetType().GetProperties())
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(SchDataNow);
var valTodo = SchDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(SchDataTodo);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(SchDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(SchDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
SchDataNow.deviceList = SchDataNow.deviceList.Union(SchDataTodo.deviceList).ToList();
SchDataNow.deviceCnt = SchDataNow.deviceList.Count;
SchDataNow.deviceAuthList = SchDataNow.deviceAuthList.Union(SchDataTodo.deviceAuthList).ToList();
SchDataNow.deviceAuth = SchDataNow.deviceAuthList.Count;
SchDataNow.deviceNoAuthList = SchDataNow.deviceNoAuthList.Union(SchDataTodo.deviceNoAuthList).ToList();
SchDataNow.deviceNoAuth = SchDataNow.deviceNoAuthList.Count;
SchDataNow.tmidList = SchDataNow.tmidList.Union(SchDataTodo.tmidList).ToList();
SchDataNow.tmidCnt = SchDataNow.tmidList.Count;
}
//無此校資料 => 該校資料放入
else
{
ProdAnalysisListMonth[$"{prodAnalMonthKey}"][$"{keySchId}"] = SchDataTodo;
}
}
else //無此月資料 => 所有學校資料放入
{
ProdAnalysisListMonth.Add(prodAnalMonthKey, new Dictionary() { { keySchId, SchDataTodo } });
}
}
}
}
}
if (ProdAnalysisListMonth.Count > 0)
{
foreach (KeyValuePair> item in ProdAnalysisListMonth)
{
string monthRedisKey = item.Key;
List hvalList = new List();
Dictionary monthRedisSchDIc = item.Value;
foreach (KeyValuePair monthRedisSchItem in monthRedisSchDIc)
{
string monthRedisSchId = monthRedisSchItem.Key;
ProdAnalysis monthRedisSchData = monthRedisSchItem.Value;
//Redis資料製作
hvalList.Add(new HashEntry(monthRedisSchId, monthRedisSchData.ToJsonString()));
//CosmosDB資料製作
ProdAnalysisCosmos cosmosSchRow = monthRedisSchData.ToJsonString().ToObject();
cosmosSchRow.date = $"{y}{m}";
cosmosSchRow.year = Convert.ToInt32(y, 10);
cosmosSchRow.month = Convert.ToInt32(m, 10);
DateTimeOffset dateTime = new DateTimeOffset(cosmosSchRow.year, cosmosSchRow.month, 1, 0, 0, 0, TimeSpan.Zero);
cosmosSchRow.dateTime = dateTime.ToUnixTimeSeconds();
cosmosSchRow.id = $"{monthRedisSchData.toolType}-{cosmosSchRow.date}-{monthRedisSchId}";
cosmosSchRow.dateUnit = "month";
cosmosSchRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
cosmosSchListMonth.Add(cosmosSchRow);
}
//記入Redis
await redisClinet8.HashSetAsync($"{monthRedisKey}", hvalList.ToArray());
}
//記入CosmosDB
if (cosmosSchListMonth.Count > 0)
{
foreach (ProdAnalysisCosmos cosmosSchRow in cosmosSchListMonth)
{
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosSchRow);
//所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
cosmosAllSchSumMonthDic = GenAnalysisRowSumData(cosmosAllSchSumMonthDic, cosmosSchRow, calPropList, "month");
}
//每月所有學校數據總計CosmosDB記入
foreach (KeyValuePair schItem in cosmosAllSchSumMonthDic)
{
string toolType = schItem.Key;
ProdAnalysisCosmos cosmosAllSchSumMonth = schItem.Value;
cosmosAllSchSumMonth.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosAllSchSumMonth);
}
}
}
//取該年所有 CosmosDB 該年所有月份 生成CosmosDB年資料
Dictionary> ProdAnalysisListYear = new Dictionary>();
Dictionary cosmosAllSchSumYearDic = new Dictionary();
var query = $"SELECT * FROM c WHERE c.year = {y} AND c.dateUnit = 'month' AND c.schoolId != 'allschool'";
await foreach (var itemcr in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIteratorSql(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("ProdAnalysis") }))
{
var json = await JsonDocument.ParseAsync(itemcr.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
{
ProdAnalysisCosmos SchDataTodo = obj.ToObject();
string toolType = SchDataTodo.toolType;
string schId = SchDataTodo.schoolId;
//年Dic已有此key => 分校累加
if (ProdAnalysisListYear.ContainsKey(toolType))
{
if (ProdAnalysisListYear[$"{toolType}"].ContainsKey($"{schId}"))
{
ProdAnalysisCosmos SchDataNow = ProdAnalysisListYear[$"{toolType}"][$"{schId}"];
foreach (PropertyInfo propertyInfo in SchDataNow.GetType().GetProperties())
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(SchDataNow);
var valTodo = SchDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(SchDataTodo);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(SchDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(SchDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
SchDataNow.deviceList = SchDataNow.deviceList.Union(SchDataTodo.deviceList).ToList();
SchDataNow.deviceCnt = SchDataNow.deviceList.Count;
SchDataNow.deviceAuthList = SchDataNow.deviceAuthList.Union(SchDataTodo.deviceAuthList).ToList();
SchDataNow.deviceAuth = SchDataNow.deviceAuthList.Count;
SchDataNow.deviceNoAuthList = SchDataNow.deviceNoAuthList.Union(SchDataTodo.deviceNoAuthList).ToList();
SchDataNow.deviceNoAuth = SchDataNow.deviceNoAuthList.Count;
SchDataNow.tmidList = SchDataNow.tmidList.Union(SchDataTodo.tmidList).ToList();
SchDataNow.tmidCnt = SchDataNow.tmidList.Count;
}
//無此校資料 => 該校資料放入
else
{
ProdAnalysisCosmos SchDataNow = SchDataTodo;
SchDataNow.date = $"{y}";
SchDataNow.year = Convert.ToInt32(y, 10);
SchDataNow.month = 0;
DateTimeOffset dateTime = new DateTimeOffset(SchDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
SchDataNow.dateTime = dateTime.ToUnixTimeSeconds();
SchDataNow.id = $"{toolType}-{y}-{schId}";
SchDataNow.dateUnit = "year";
ProdAnalysisListYear[$"{toolType}"][$"{schId}"] = SchDataNow;
}
}
//無此年資料 => 所有學校資料放入
else
{
ProdAnalysisCosmos SchDataNow = SchDataTodo;
SchDataNow.date = $"{y}";
SchDataNow.year = Convert.ToInt32(y, 10);
SchDataNow.month = 0;
DateTimeOffset dateTime = new DateTimeOffset(SchDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
SchDataNow.dateTime = dateTime.ToUnixTimeSeconds();
SchDataNow.id = $"{toolType}-{y}-{schId}";
SchDataNow.dateUnit = "year";
ProdAnalysisListYear.Add(toolType, new Dictionary() { { schId, SchDataNow } });
}
}
}
}
if (ProdAnalysisListYear.Count > 0)
{
foreach (KeyValuePair> item in ProdAnalysisListYear)
{
//string toolType = item.Key;
ProdAnalysisCosmos SchDataNow = new ProdAnalysisCosmos(); //當年某產品所有學校總和
Dictionary yearCosmosSchDIc = item.Value;
foreach (KeyValuePair yearCosmosSchItem in yearCosmosSchDIc)
{
string schId = yearCosmosSchItem.Key;
ProdAnalysisCosmos cosmosSchRow = yearCosmosSchItem.Value;
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosSchRow);
//每年所有學校數據總計CosmosDB記入
cosmosAllSchSumYearDic = GenAnalysisRowSumData(cosmosAllSchSumYearDic, cosmosSchRow, calPropList, "year");
}
//每年所有學校數據總計CosmosDB記入
foreach (KeyValuePair schItem in cosmosAllSchSumYearDic)
{
string toolType = schItem.Key;
ProdAnalysisCosmos cosmosAllSchSumYear = schItem.Value;
cosmosAllSchSumYear.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(cosmosAllSchSumYear);
}
//await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(SchDataNow);
}
}
//虛擬學校創建
if (crtVirtualSchoolId.Count > 0)
{
//取得IES5 school Base
string schIdListStr = JsonConvert.SerializeObject(crtVirtualSchoolId);
string schBaseQueryText = $"SELECT c.id FROM c where ARRAY_CONTAINS({schIdListStr}, c.id, true)";
await foreach (var itemsr in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIteratorSql(queryText: schBaseQueryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
{
using var json = await JsonDocument.ParseAsync(itemsr.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
{
string existSchid = obj.GetProperty("id").GetString();
if (crtVirtualSchoolId.Contains(existSchid))
{
crtVirtualSchoolId.Remove(existSchid);
}
}
}
}
//取得IES5 school VirtualBase
schIdListStr = JsonConvert.SerializeObject(crtVirtualSchoolId);
schBaseQueryText = $"SELECT c.id FROM c where ARRAY_CONTAINS({schIdListStr}, c.id, true)";
await foreach (var itemsr in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIteratorSql(queryText: schBaseQueryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"VirtualBase") }))
{
using var json = await JsonDocument.ParseAsync(itemsr.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
{
string existSchid = obj.GetProperty("id").GetString();
if (crtVirtualSchoolId.Contains(existSchid))
{
crtVirtualSchoolId.Remove(existSchid);
}
}
}
}
//VirtualBase school 建立
if (crtVirtualSchoolId.Count > 0)
{
//取得CSV2 School,存在者建立IES5 VirtualBase school
List crtVSchoolList = new List();
string csv2SchIdListStr = JsonConvert.SerializeObject(crtVirtualSchoolId);
string schCsv2QueryText = $"SELECT c.shortCode, c.name, c.countryName, c.provinceName, c.cityName, c.distName, c.address FROM c where ARRAY_CONTAINS({csv2SchIdListStr}, c.shortCode, true)";
await foreach (var item in _azureCosmosClientCsv2CnRead.GetContainer("Core", "School").GetItemQueryStreamIteratorSql(queryText: schCsv2QueryText, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("base") }))
{
using var json = await JsonDocument.ParseAsync(item.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
{
VirtualBase crtVSchool = new VirtualBase();
crtVSchool.code = "VirtualBase";
crtVSchool.id = obj.GetProperty("shortCode").GetString();
crtVSchool.pk = "School";
crtVSchool.schoolCode = obj.GetProperty("shortCode").GetString();
crtVSchool.name = obj.GetProperty("name").GetString();
crtVSchool.region = (obj.TryGetProperty("countryName", out JsonElement countryNameJ)) ? Convert.ToString(countryNameJ) : null;
crtVSchool.province = (obj.TryGetProperty("provinceName", out JsonElement provinceNameJ)) ? Convert.ToString(provinceNameJ) : null;
crtVSchool.city = (obj.TryGetProperty("cityName", out JsonElement cityNameJ)) ? Convert.ToString(cityNameJ) : null;
crtVSchool.dist = (obj.TryGetProperty("distName", out JsonElement distNameJ)) ? Convert.ToString(distNameJ) : null;
crtVSchool.address = (obj.TryGetProperty("address", out JsonElement addressJ)) ? Convert.ToString(addressJ) : null;
crtVSchool.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(crtVSchool);
}
}
}
}
}
}
catch (Exception ex)
{
_ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},CreatIes5ProdAnalData() 生成學校年月日日IOT統計資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
}
}
//年月日 TMID IOT產品分析數據生成
///1.生成 Redis TmidAnalysis:Month
///2.生成 CosmosDB Month
///3.生成 CosmosDB 系統所有TMID數值加總
private static async Task CreatTmidProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing, string y, string m, string d, List IotTeachingDataList)
{
try
{
var redisClinet8 = _azureRedis.GetRedisClient(8);
List calPropList = new List() { "lessonRecord", "useIES", "useIES5Resource", "useWebIrs", "useDeviceIrs", "useHaboard", "useHita", "lessonLengMin", "lessonLeng0", "stuShow", "stuLessonLengMin", "tGreen", "tLesson", "lTypeCoop", "lTypeIact", "lTypeMis", "lTypeTst", "lTypeDif", "lTypeNone", "lessonCnt928", "lessonCntId", "lessonCntDevice", "lessonCntIdDevice", "mission", "missionFin", "item", "interact", "sendSok", "learnPeer", "learnCoop", "useWordCloud", "useClouDAS", "useGPT", "useIes5Test", "usePaperTest", "useExcelTest", "useScoreBoard", "learnParticipationCnt", "learnParticipationT", "coopMission", "coopWork", "coopContributionT", "peerAct", "peerStuParticipationT", "useTransMode", "useMiniMode" }; //要計算的ProdAnalysis欄位列表
List TmidAnalysisList = new List();
if (IotTeachingDataList.Count > 0)
{
foreach (IotTeachingData IotTeachingDatRow in IotTeachingDataList)
{
bool addTmidFlg = false;
string tmid = (!string.IsNullOrWhiteSpace(IotTeachingDatRow.tmid)) ? IotTeachingDatRow.tmid.ToString() : string.Empty;
string deviceId = (!string.IsNullOrWhiteSpace(IotTeachingDatRow.deviceId)) ? IotTeachingDatRow.deviceId.ToString() : string.Empty;
string ver = (!string.IsNullOrWhiteSpace(IotTeachingDatRow.version)) ? IotTeachingDatRow.version : string.Empty;
string toolType = string.Empty;
if (!string.IsNullOrWhiteSpace(IotTeachingDatRow.deviceId))
{
if (IotTeachingDatRow.deviceId.Contains("HiTeachCC-")) toolType = "HiTeachCC";
else if (IotTeachingDatRow.deviceId.Contains("HiTeach-")) toolType = "HiTeach";
else if (IotTeachingDatRow.deviceId.Contains("HiTA-")) toolType = "HiTA";
}
if (!string.IsNullOrWhiteSpace(tmid) && !string.IsNullOrWhiteSpace(deviceId) && !string.IsNullOrWhiteSpace(toolType))
{
bool addFlg = false;
TmidAnalysis tmidAnalysisRow = TmidAnalysisList.Where(s => s.tmid.Equals(tmid) && s.toolType.Equals(toolType)).FirstOrDefault();
//無此tmid數據=>創建
if (tmidAnalysisRow == null)
{
tmidAnalysisRow = new TmidAnalysis();
tmidAnalysisRow.tmid = tmid;
tmidAnalysisRow.toolType = toolType;
addFlg = true;
}
//欄位加總
if (!tmidAnalysisRow.deviceList.Contains(IotTeachingDatRow.deviceId))
{
tmidAnalysisRow.deviceList.Add(IotTeachingDatRow.deviceId);
}
tmidAnalysisRow.deviceCnt = tmidAnalysisRow.deviceList.Count;
switch (IotTeachingDatRow.authType)
{
case "0": //928授權
if (!tmidAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) tmidAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
tmidAnalysisRow.lessonCnt928++;
break;
case "1": //ID授權
if (!tmidAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) tmidAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
tmidAnalysisRow.lessonCntId++;
break;
case "2": //機器授權
if (!tmidAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) tmidAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
tmidAnalysisRow.lessonCntDevice++;
break;
case "3": //ID+機器授權
if (!tmidAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) tmidAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
tmidAnalysisRow.lessonCntIdDevice++;
break;
}
tmidAnalysisRow.deviceNoAuth = tmidAnalysisRow.deviceNoAuthList.Count;
tmidAnalysisRow.deviceAuth = tmidAnalysisRow.deviceAuthList.Count;
if (!tmidAnalysisRow.tmidList.Contains(IotTeachingDatRow.tmid))
{
tmidAnalysisRow.tmidList.Add(IotTeachingDatRow.tmid);
}
tmidAnalysisRow.tmidCnt = tmidAnalysisRow.tmidList.Count;
tmidAnalysisRow.lessonRecord++;
if (IotTeachingDatRow.useIES.Equals("1")) tmidAnalysisRow.useIES++;
tmidAnalysisRow.useIES5Resource += IotTeachingDatRow.useIES5Resource;
if (IotTeachingDatRow.useWebIrs.Equals("1")) tmidAnalysisRow.useWebIrs++;
if (IotTeachingDatRow.useDeviceIrs.Equals("1")) tmidAnalysisRow.useDeviceIrs++;
if (IotTeachingDatRow.useHaboard.Equals("1")) tmidAnalysisRow.useHaboard++;
if (IotTeachingDatRow.useHita.Equals("1")) tmidAnalysisRow.useHita++;
tmidAnalysisRow.lessonLengMin += IotTeachingDatRow.lessonLengMin;
if (IotTeachingDatRow.lessonLengMin.Equals(0)) tmidAnalysisRow.lessonLeng0++;
tmidAnalysisRow.stuShow += IotTeachingDatRow.stuShow;
tmidAnalysisRow.stuLessonLengMin += IotTeachingDatRow.lessonLengMin * IotTeachingDatRow.stuShow;
if (IotTeachingDatRow.tPoint >= 70) tmidAnalysisRow.tGreen++;
if (IotTeachingDatRow.lessonLengMin >= 10 && IotTeachingDatRow.tPoint > 0) tmidAnalysisRow.tLesson++;
if (IotTeachingDatRow.lTypeCoop.Equals("1")) tmidAnalysisRow.lTypeCoop++;
if (IotTeachingDatRow.lTypeIact.Equals("1")) tmidAnalysisRow.lTypeIact++;
if (IotTeachingDatRow.lTypeMis.Equals("1")) tmidAnalysisRow.lTypeMis++;
if (IotTeachingDatRow.lTypeTst.Equals("1")) tmidAnalysisRow.lTypeTst++;
if (IotTeachingDatRow.lTypeDif.Equals("1")) tmidAnalysisRow.lTypeDif++;
if (IotTeachingDatRow.lTypeCoop.Equals("0") && IotTeachingDatRow.lTypeIact.Equals("0") && IotTeachingDatRow.lTypeMis.Equals("0") && IotTeachingDatRow.lTypeTst.Equals("0") && IotTeachingDatRow.lTypeDif.Equals("0")) tmidAnalysisRow.lTypeNone++;
tmidAnalysisRow.mission += IotTeachingDatRow.mission;
tmidAnalysisRow.missionFin += IotTeachingDatRow.missionFin;
tmidAnalysisRow.item += IotTeachingDatRow.item;
tmidAnalysisRow.interact += IotTeachingDatRow.interact;
if (IotTeachingDatRow.sendSok.Equals("1")) tmidAnalysisRow.sendSok++;
if (IotTeachingDatRow.learnPeer.Equals("1")) tmidAnalysisRow.learnPeer++;
if (IotTeachingDatRow.learnCoop.Equals("1")) tmidAnalysisRow.learnCoop++;
if (IotTeachingDatRow.useWordCloud.Equals("1")) tmidAnalysisRow.useWordCloud++;
if (IotTeachingDatRow.useClouDAS.Equals("1")) tmidAnalysisRow.useClouDAS++;
if (IotTeachingDatRow.useGPT.Equals("1")) tmidAnalysisRow.useGPT++;
if (IotTeachingDatRow.useIes5Test.Equals("1")) tmidAnalysisRow.useIes5Test++;
if (IotTeachingDatRow.usePaperTest.Equals("1")) tmidAnalysisRow.usePaperTest++;
if (IotTeachingDatRow.useExcelTest.Equals("1")) tmidAnalysisRow.useExcelTest++;
if (IotTeachingDatRow.useScoreBoard.Equals("1")) tmidAnalysisRow.useScoreBoard++; //課堂中使用記分板
if (IotTeachingDatRow.learnParticipationCnt.Equals("1")) tmidAnalysisRow.learnParticipationCnt++; //學習參與度次數
tmidAnalysisRow.learnParticipationT += IotTeachingDatRow.learnParticipation; //學習參與度指數(總和)
decimal learnParticipationTmp = (tmidAnalysisRow.learnParticipationCnt > 0) ? (decimal)tmidAnalysisRow.learnParticipationT / (decimal)tmidAnalysisRow.learnParticipationCnt : 0;
tmidAnalysisRow.learnParticipation = Math.Round(learnParticipationTmp, 2); //學習參與度指數(平均)
tmidAnalysisRow.coopMission += IotTeachingDatRow.coopMission; //協作任務數
tmidAnalysisRow.coopWork += IotTeachingDatRow.coopWork; //協作作品數
tmidAnalysisRow.coopContributionT += IotTeachingDatRow.coopContributionT; //協作總貢獻度
tmidAnalysisRow.peerAct += IotTeachingDatRow.peerAct; //互評活動次數
tmidAnalysisRow.peerStuParticipationT += IotTeachingDatRow.peerStuParticipationT; //互評學生參與總次數
if (IotTeachingDatRow.useTransMode.Equals("1")) tmidAnalysisRow.useTransMode++; //有使用透明模式
if (IotTeachingDatRow.useMiniMode.Equals("1")) tmidAnalysisRow.useMiniMode++; //有使用最小化模式
if (!string.IsNullOrWhiteSpace(ver) && !tmidAnalysisRow.verList.Contains(ver))
{
tmidAnalysisRow.verList.Add(ver);
}
if (addFlg)
{
TmidAnalysisList.Add(tmidAnalysisRow);
}
}
}
}
//1.記入CSV2 Redis TmidAnalysis:Day
//2.記入CSV2 CosmosDB Day
if (TmidAnalysisList.Count > 0)
{
//資料整形
Dictionary> redisTmidFieldDic = new Dictionary>(); //架構: key => tmid => JsonContent
List cosmosTmidList = new List();
Dictionary cosmosAllTmidSumDayDic = new Dictionary();
foreach (TmidAnalysis tmidAnalysisRow in TmidAnalysisList)
{
//Redis整形
string toolType = tmidAnalysisRow.toolType;
string tmid = tmidAnalysisRow.tmid;
string hkey = $"TmidAnalysis:Day:{toolType}:{y}{m}{d}";
string fieldContent = tmidAnalysisRow.ToJsonString();
if (redisTmidFieldDic.ContainsKey(hkey)) redisTmidFieldDic[hkey].Add(tmid, fieldContent);
else redisTmidFieldDic.Add(hkey, new Dictionary() { { tmid, fieldContent } });
//CosmosDB整形
TmidAnalysisCosmos TmidAnalysisCosmosRow = tmidAnalysisRow.ToJsonString().ToObject();
TmidAnalysisCosmosRow.date = $"{y}{m}{d}";
TmidAnalysisCosmosRow.year = Convert.ToInt32(y, 10);
TmidAnalysisCosmosRow.month = Convert.ToInt32(m, 10);
TmidAnalysisCosmosRow.day = Convert.ToInt32(d, 10);
DateTimeOffset dateTime = new DateTimeOffset(TmidAnalysisCosmosRow.year, TmidAnalysisCosmosRow.month, TmidAnalysisCosmosRow.day, 0, 0, 0, TimeSpan.Zero);
TmidAnalysisCosmosRow.dateTime = dateTime.ToUnixTimeSeconds();
TmidAnalysisCosmosRow.id = $"{TmidAnalysisCosmosRow.toolType}-{TmidAnalysisCosmosRow.date}-{tmid}";
TmidAnalysisCosmosRow.dateUnit = "day";
TmidAnalysisCosmosRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
cosmosTmidList.Add(TmidAnalysisCosmosRow);
}
//記入Redis
if (redisTmidFieldDic.Count > 0)
{
foreach (KeyValuePair> hkeyItem in redisTmidFieldDic)
{
string hkey = hkeyItem.Key;
List hvalList = new List();
Dictionary fieldDic = hkeyItem.Value;
foreach (KeyValuePair tmidItem in fieldDic)
{
string tmid = tmidItem.Key;
string fieldContent = tmidItem.Value;
hvalList.Add(new HashEntry($"{tmid}", fieldContent));
}
await redisClinet8.HashSetAsync(hkey, hvalList.ToArray());
}
}
//記入CosmosDB
if (cosmosTmidList.Count > 0)
{
foreach (TmidAnalysisCosmos cosmosTmidRow in cosmosTmidList)
{
//各TMID每日CosmosDB記入
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosTmidRow);
//所有TMID每日數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
cosmosAllTmidSumDayDic = GenAnalysisRowSumData(cosmosAllTmidSumDayDic, cosmosTmidRow, calPropList, "day");
}
//每日所有TMID數據總計CosmosDB記入
foreach (KeyValuePair tmidItem in cosmosAllTmidSumDayDic)
{
string toolType = tmidItem.Key;
TmidAnalysisCosmos cosmosAllTmidSumDay = tmidItem.Value;
cosmosAllTmidSumDay.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosAllTmidSumDay);
}
}
}
//取 Redis 該月所有 TmidAnalysis:Day
//1.生成 Redis TmidAnalysis:Month
//2.生成 CosmosDB Month
Dictionary> TmidAnalysisListMonth = new Dictionary>();
Dictionary cosmosAllTmidSumMonthDic = new Dictionary();
List cosmosTmidListMonth = new List();
string patternD = $"TmidAnalysis:Day:HiT*:{y}{m}*";
List keysDayList = ScanRedisKeysByPattern(_azureRedis, patternD);
if (keysDayList.Count > 0)
{
foreach (string keyDay in keysDayList)
{
string[] keyItemList = keyDay.Split(':'); //TmidAnalysis:Day:HiTeach:20230326
string toolType = keyItemList[2];
string dateStrD = keyItemList[3];
string dateStrD_y = string.Empty;
string dateStrD_m = string.Empty;
string dateStrD_d = string.Empty;
Regex rgx = new Regex(@"[0-9]{8}");
if (rgx.IsMatch(dateStrD))
{
dateStrD_y = dateStrD.Substring(0, 4);
dateStrD_m = dateStrD.Substring(4, 2);
dateStrD_d = dateStrD.Substring(6, 2);
}
string tmidAnalMonthKey = $"TmidAnalysis:Month:{toolType}:{dateStrD_y}{dateStrD_m}";
bool tmidAnalysisDayExist = await redisClinet8.KeyExistsAsync(keyDay);
if (tmidAnalysisDayExist && !string.IsNullOrWhiteSpace(dateStrD_y) && !string.IsNullOrWhiteSpace(dateStrD_m) && !string.IsNullOrWhiteSpace(dateStrD_d))
{
HashEntry[] hsetDay = redisClinet8.HashGetAll(keyDay); //某日 ProdAnalysis:Day所有學校的統計項目
foreach (HashEntry hset in hsetDay)
{
string keyTMID = hset.Name;
string valTmidDataJson = hset.Value;
TmidAnalysis tmidDataTodo = valTmidDataJson.ToObject();
//Redis Month 資料生成
if (TmidAnalysisListMonth.ContainsKey(tmidAnalMonthKey)) //月Dic已有此key => TMID累加
{
if (TmidAnalysisListMonth[$"{tmidAnalMonthKey}"].ContainsKey($"{keyTMID}"))
{
TmidAnalysis TmidDataNow = TmidAnalysisListMonth[$"{tmidAnalMonthKey}"][$"{keyTMID}"];
foreach (PropertyInfo propertyInfo in TmidDataNow.GetType().GetProperties())
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(TmidDataNow);
var valTodo = tmidDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(tmidDataTodo);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(TmidDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(TmidDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
TmidDataNow.deviceList = TmidDataNow.deviceList.Union(tmidDataTodo.deviceList).ToList();
TmidDataNow.deviceCnt = TmidDataNow.deviceList.Count;
TmidDataNow.deviceAuthList = TmidDataNow.deviceAuthList.Union(tmidDataTodo.deviceAuthList).ToList();
TmidDataNow.deviceAuth = TmidDataNow.deviceAuthList.Count;
TmidDataNow.deviceNoAuthList = TmidDataNow.deviceNoAuthList.Union(tmidDataTodo.deviceNoAuthList).ToList();
TmidDataNow.deviceNoAuth = TmidDataNow.deviceNoAuthList.Count;
TmidDataNow.tmidList = TmidDataNow.tmidList.Union(tmidDataTodo.tmidList).ToList();
TmidDataNow.tmidCnt = TmidDataNow.tmidList.Count;
TmidDataNow.verList = TmidDataNow.verList.Union(tmidDataTodo.verList).ToList();
}
//無TMID資料 => 該TMID資料放入
else
{
TmidAnalysisListMonth[$"{tmidAnalMonthKey}"][$"{keyTMID}"] = tmidDataTodo;
}
}
else //無此月資料 => 所有TMID資料放入
{
TmidAnalysisListMonth.Add(tmidAnalMonthKey, new Dictionary() { { keyTMID, tmidDataTodo } });
}
}
}
}
}
if (TmidAnalysisListMonth.Count > 0)
{
foreach (KeyValuePair> item in TmidAnalysisListMonth)
{
string monthRedisKey = item.Key;
List hvalList = new List();
Dictionary monthRedisTmidDIc = item.Value;
foreach (KeyValuePair monthRedisTmidItem in monthRedisTmidDIc)
{
string monthRedisTmid = monthRedisTmidItem.Key;
TmidAnalysis monthRedisTmidData = monthRedisTmidItem.Value;
//Redis資料製作
hvalList.Add(new HashEntry(monthRedisTmid, monthRedisTmidData.ToJsonString()));
//CosmosDB資料製作
TmidAnalysisCosmos cosmosTmidRow = monthRedisTmidData.ToJsonString().ToObject();
cosmosTmidRow.date = $"{y}{m}";
cosmosTmidRow.year = Convert.ToInt32(y, 10);
cosmosTmidRow.month = Convert.ToInt32(m, 10);
DateTimeOffset dateTime = new DateTimeOffset(cosmosTmidRow.year, cosmosTmidRow.month, 1, 0, 0, 0, TimeSpan.Zero);
cosmosTmidRow.dateTime = dateTime.ToUnixTimeSeconds();
cosmosTmidRow.id = $"{monthRedisTmidData.toolType}-{cosmosTmidRow.date}-{monthRedisTmid}";
cosmosTmidRow.dateUnit = "month";
cosmosTmidRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
cosmosTmidListMonth.Add(cosmosTmidRow);
}
//記入Redis
await redisClinet8.HashSetAsync($"{monthRedisKey}", hvalList.ToArray());
}
//記入CosmosDB
if (cosmosTmidListMonth.Count > 0)
{
foreach (TmidAnalysisCosmos cosmosTmidRow in cosmosTmidListMonth)
{
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosTmidRow);
//所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
cosmosAllTmidSumMonthDic = GenAnalysisRowSumData(cosmosAllTmidSumMonthDic, cosmosTmidRow, calPropList, "day");
}
//每月所有TMID數據總計CosmosDB記入
foreach (KeyValuePair tmidItem in cosmosAllTmidSumMonthDic)
{
string toolType = tmidItem.Key;
TmidAnalysisCosmos cosmosAllTmidSumMonth = tmidItem.Value;
cosmosAllTmidSumMonth.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosAllTmidSumMonth);
}
}
}
//取該年所有 CosmosDB 該年所有月份 生成CosmosDB年資料
Dictionary> TmidAnalysisListYear = new Dictionary>();
Dictionary cosmosAllTmidSumYearDic = new Dictionary();
var query = $"SELECT * FROM c WHERE c.year = {y} AND c.dateUnit = 'month' AND c.tmid != 'alltmid'";
await foreach (var itemcr in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryStreamIteratorSql(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("TmidAnalysis") }))
{
var json = await JsonDocument.ParseAsync(itemcr.Content);
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
{
foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
{
TmidAnalysisCosmos TmidDataTodo = obj.ToObject();
string toolType = TmidDataTodo.toolType;
string tmid = TmidDataTodo.tmid;
//年Dic已有此key => 分校累加
if (TmidAnalysisListYear.ContainsKey(toolType))
{
if (TmidAnalysisListYear[$"{toolType}"].ContainsKey($"{tmid}"))
{
TmidAnalysisCosmos TmidDataNow = TmidAnalysisListYear[$"{toolType}"][$"{tmid}"];
foreach (PropertyInfo propertyInfo in TmidDataNow.GetType().GetProperties())
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(TmidDataNow);
var valTodo = TmidDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(TmidDataTodo);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(TmidDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(TmidDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
TmidDataNow.deviceList = TmidDataNow.deviceList.Union(TmidDataTodo.deviceList).ToList();
TmidDataNow.deviceCnt = TmidDataNow.deviceList.Count;
TmidDataNow.deviceAuthList = TmidDataNow.deviceAuthList.Union(TmidDataTodo.deviceAuthList).ToList();
TmidDataNow.deviceAuth = TmidDataNow.deviceAuthList.Count;
TmidDataNow.deviceNoAuthList = TmidDataNow.deviceNoAuthList.Union(TmidDataTodo.deviceNoAuthList).ToList();
TmidDataNow.deviceNoAuth = TmidDataNow.deviceNoAuthList.Count;
TmidDataNow.tmidList = TmidDataNow.tmidList.Union(TmidDataTodo.tmidList).ToList();
TmidDataNow.tmidCnt = TmidDataNow.tmidList.Count;
TmidDataNow.verList = TmidDataNow.verList.Union(TmidDataTodo.verList).ToList();
}
//無此校資料 => 該校資料放入
else
{
TmidAnalysisCosmos TmidDataNow = TmidDataTodo;
TmidDataNow.date = $"{y}";
TmidDataNow.year = Convert.ToInt32(y, 10);
TmidDataNow.month = 0;
DateTimeOffset dateTime = new DateTimeOffset(TmidDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
TmidDataNow.dateTime = dateTime.ToUnixTimeSeconds();
TmidDataNow.id = $"{toolType}-{y}-{tmid}";
TmidDataNow.dateUnit = "year";
TmidAnalysisListYear[$"{toolType}"][$"{tmid}"] = TmidDataNow;
}
}
//無此年資料 => 所有學校資料放入
else
{
TmidAnalysisCosmos TmidDataNow = TmidDataTodo;
TmidDataNow.date = $"{y}";
TmidDataNow.year = Convert.ToInt32(y, 10);
TmidDataNow.month = 0;
DateTimeOffset dateTime = new DateTimeOffset(TmidDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
TmidDataNow.dateTime = dateTime.ToUnixTimeSeconds();
TmidDataNow.id = $"{toolType}-{y}-{tmid}";
TmidDataNow.dateUnit = "year";
TmidAnalysisListYear.Add(toolType, new Dictionary() { { tmid, TmidDataNow } });
}
}
}
}
if (TmidAnalysisListYear.Count > 0)
{
foreach (KeyValuePair> item in TmidAnalysisListYear)
{
//string toolType = item.Key;
TmidAnalysisCosmos TmidDataNow = new TmidAnalysisCosmos(); //當年某產品所有學校總和
Dictionary yearCosmosTmidDIc = item.Value;
foreach (KeyValuePair yearCosmosTmidItem in yearCosmosTmidDIc)
{
string tmid = yearCosmosTmidItem.Key;
TmidAnalysisCosmos cosmosTmidRow = yearCosmosTmidItem.Value;
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosTmidRow);
//每年所有學校數據總計CosmosDB記入
cosmosAllTmidSumYearDic = GenAnalysisRowSumData(cosmosAllTmidSumYearDic, cosmosTmidRow, calPropList, "year");
}
//每年所有學校數據總計CosmosDB記入
foreach (KeyValuePair tmidItem in cosmosAllTmidSumYearDic)
{
string toolType = tmidItem.Key;
TmidAnalysisCosmos cosmosAllTmidSumYear = tmidItem.Value;
cosmosAllTmidSumYear.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(cosmosAllTmidSumYear);
}
//await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync(TmidDataNow);
}
}
}
catch (Exception ex)
{
_ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},CreatTmidProdAnalData() 生成TMID年月日日IOT統計資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.研發C組);
}
}
//生成年月日 Device IOT產品分析數據 [待做]
private static async Task CreatDeviceAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing, string y, string m, string d, List IotTeachingDataList)
{
try
{
var redisClinet8 = _azureRedis.GetRedisClient(8);
//1. 從IOT 取得DeviceID 或 IP
//2. 從DeviceID 或 IP 算出地理位置(國省市區)
//3. 依照各地理位置進行項目統計;統計項目和學校及TMID統計項目相同
}
catch (Exception ex)
{
_ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},CreatDeviceAnalData() 生成TMID年月日日IOT統計資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.研發C組);
}
}
//累加各校每日/月總計資料,生成所有學校每日/月總計資料
private static Dictionary GenAnalysisRowSumData(Dictionary cosmosAllSumDic, ProdAnalysisCosmos cosmosRow, List calPropList, string dataType) //dataType:"day","month","year"
{
try
{
string toolType = cosmosRow.toolType;
string schoolId = "allschool";
int year = 0;
int month = 1;
int day = 1;
switch (dataType)
{
case "day":
year = cosmosRow.year;
month = cosmosRow.month;
day = cosmosRow.day;
break;
case "month":
year = cosmosRow.year;
month = cosmosRow.month;
break;
case "year":
year = cosmosRow.year;
break;
}
ProdAnalysisCosmos cosmosAllSum = new ProdAnalysisCosmos();
if (cosmosAllSumDic.ContainsKey(toolType)) cosmosAllSum = cosmosAllSumDic[toolType];
foreach (PropertyInfo propertyInfo in cosmosAllSum.GetType().GetProperties()) //累加項目
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(cosmosAllSum);
var valTodo = cosmosRow.GetType().GetProperty(propertyInfo.Name).GetValue(cosmosRow);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(cosmosAllSum, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(cosmosAllSum, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
cosmosAllSum.schoolId = schoolId;
cosmosAllSum.toolType = cosmosRow.toolType;
cosmosAllSum.date = cosmosRow.date;
cosmosAllSum.id = $"{cosmosAllSum.toolType}-{cosmosAllSum.date}-{schoolId}";
cosmosAllSum.dateUnit = dataType;
cosmosAllSum.year = year;
cosmosAllSum.month = month;
cosmosAllSum.day = day;
DateTimeOffset dateTime = new DateTimeOffset(year, month, day, 0, 0, 0, TimeSpan.Zero);
cosmosAllSum.dateTime = dateTime.ToUnixTimeSeconds();
cosmosAllSum.deviceList = cosmosAllSum.deviceList.Union(cosmosRow.deviceList).ToList();
cosmosAllSum.deviceCnt = cosmosAllSum.deviceList.Count;
cosmosAllSum.deviceAuthList = cosmosAllSum.deviceAuthList.Union(cosmosRow.deviceAuthList).ToList();
cosmosAllSum.deviceAuth = cosmosAllSum.deviceAuthList.Count;
cosmosAllSum.deviceNoAuthList = cosmosAllSum.deviceNoAuthList.Union(cosmosRow.deviceNoAuthList).ToList();
cosmosAllSum.deviceNoAuth = cosmosAllSum.deviceNoAuthList.Count;
cosmosAllSum.tmidList = cosmosAllSum.tmidList.Union(cosmosRow.tmidList).ToList();
cosmosAllSum.tmidCnt = cosmosAllSum.tmidList.Count;
decimal learnParticipationTmp = (cosmosAllSum.learnParticipationCnt > 0) ? (decimal)cosmosAllSum.learnParticipationT / (decimal)cosmosAllSum.learnParticipationCnt : 0;
cosmosAllSum.learnParticipation = Math.Round(learnParticipationTmp, 2); //學習參與度指數(平均)
if (cosmosAllSumDic.ContainsKey(toolType)) cosmosAllSumDic[toolType] = cosmosAllSum;
else cosmosAllSumDic.Add(toolType, cosmosAllSum);
return cosmosAllSumDic;
}
catch (Exception ex)
{
return cosmosAllSumDic;
}
}
//累加各TMID每日/月總計資料,生成所有TMID每日/月總計資料
private static Dictionary GenAnalysisRowSumData(Dictionary cosmosAllSumDic, TmidAnalysisCosmos cosmosRow, List calPropList, string dataType) //dataType:"day","month","year"
{
try
{
string toolType = cosmosRow.toolType;
string tmid = "alltmid";
int year = 0;
int month = 1;
int day = 1;
switch (dataType)
{
case "day":
year = cosmosRow.year;
month = cosmosRow.month;
day = cosmosRow.day;
break;
case "month":
year = cosmosRow.year;
month = cosmosRow.month;
break;
case "year":
year = cosmosRow.year;
break;
}
TmidAnalysisCosmos cosmosAllSum = new TmidAnalysisCosmos();
if (cosmosAllSumDic.ContainsKey(toolType)) cosmosAllSum = cosmosAllSumDic[toolType];
foreach (PropertyInfo propertyInfo in cosmosAllSum.GetType().GetProperties()) //累加項目
{
if (calPropList.Contains(propertyInfo.Name))
{
var propType = propertyInfo.PropertyType;
var valNow = propertyInfo.GetValue(cosmosAllSum);
var valTodo = cosmosRow.GetType().GetProperty(propertyInfo.Name).GetValue(cosmosRow);
if (propType.Equals(typeof(long))) propertyInfo.SetValue(cosmosAllSum, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
else propertyInfo.SetValue(cosmosAllSum, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
}
}
cosmosAllSum.tmid = tmid;
cosmosAllSum.toolType = cosmosRow.toolType;
cosmosAllSum.date = cosmosRow.date;
cosmosAllSum.id = $"{cosmosAllSum.toolType}-{cosmosAllSum.date}-{tmid}";
cosmosAllSum.dateUnit = dataType;
cosmosAllSum.year = year;
cosmosAllSum.month = month;
cosmosAllSum.day = day;
DateTimeOffset dateTime = new DateTimeOffset(year, month, day, 0, 0, 0, TimeSpan.Zero);
cosmosAllSum.dateTime = dateTime.ToUnixTimeSeconds();
cosmosAllSum.deviceList = cosmosAllSum.deviceList.Union(cosmosRow.deviceList).ToList();
cosmosAllSum.deviceCnt = cosmosAllSum.deviceList.Count;
cosmosAllSum.deviceAuthList = cosmosAllSum.deviceAuthList.Union(cosmosRow.deviceAuthList).ToList();
cosmosAllSum.deviceAuth = cosmosAllSum.deviceAuthList.Count;
cosmosAllSum.deviceNoAuthList = cosmosAllSum.deviceNoAuthList.Union(cosmosRow.deviceNoAuthList).ToList();
cosmosAllSum.deviceNoAuth = cosmosAllSum.deviceNoAuthList.Count;
cosmosAllSum.tmidList = cosmosAllSum.tmidList.Union(cosmosRow.tmidList).ToList();
cosmosAllSum.tmidCnt = cosmosAllSum.tmidList.Count;
cosmosAllSum.verList = cosmosAllSum.verList.Union(cosmosRow.verList).ToList();
decimal learnParticipationTmp = (cosmosAllSum.learnParticipationCnt > 0) ? (decimal)cosmosAllSum.learnParticipationT / (decimal)cosmosAllSum.learnParticipationCnt : 0;
cosmosAllSum.learnParticipation = Math.Round(learnParticipationTmp, 2); //學習參與度指數(平均)
if (cosmosAllSumDic.ContainsKey(toolType)) cosmosAllSumDic[toolType] = cosmosAllSum;
else cosmosAllSumDic.Add(toolType, cosmosAllSum);
return cosmosAllSumDic;
}
catch (Exception ex)
{
return cosmosAllSumDic;
}
}
///
/// 取得Redis(8)符合搜尋模式的key
///
///
///
public static List ScanRedisKeysByPattern(AzureRedisFactory _azureRedis, string pattern)
{
var redisClinet8 = _azureRedis.GetRedisClient(8);
var keys = new HashSet();
int nextCursor = 0;
do
{
RedisResult redisResult = redisClinet8.Execute("SCAN", nextCursor.ToString(), "MATCH", pattern, "COUNT", "1000");
var innerResult = (RedisResult[])redisResult;
nextCursor = int.Parse((string)innerResult[0]);
List resultLines = ((RedisKey[])innerResult[1]).ToList();
keys.UnionWith(resultLines);
}
while (nextCursor != 0);
List result = new List();
if (keys.Count > 0)
{
foreach (RedisKey key in keys)
{
result.Add(key.ToString());
}
}
return result;
}
}
}