1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897 |
- 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.DI.IPIP;
- using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
- using static TEAMModelOS.SDK.Extension.GeoRegion;
- using static TEAMModelOS.SDK.Models.Cosmos.IotTeachingData;
- namespace TEAMModelOS.SDK.Models.Service.BI
- {
- public static class BIProdAnalysis
- {
- /// <summary>
- /// 1.取得某日CS IOT 資料
- /// 2.生成IES5各校產品分析統計資料
- /// 3.生成TMID產品分析統計資料
- /// 4.生成DeviceID產品分析統計資料
- /// </summary>
- /// <param name="_azureRedis"></param>
- /// <param name="_dingDing"></param>
- /// <param name="y">年</param>
- /// <param name="m">月(2位數)</param>
- /// <param name="d">日(2位數)</param>
- /// <returns></returns>
- public static async Task BICreatDailyAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, CosmosClient _azureCosmosClientCsv2, CosmosClient _azureCosmosClientCsv2CnRead, DingDing _dingDing, City _city, string _location, string y, string m, string d, List<regionrow> _region_gl, List<regionrow> _region_cn)
- {
- List<IotTeachingData> IotTeachingDataList = await BIGetDailyRedisProdAnalData(_azureRedis, _azureCosmosClientCsv2, _dingDing, _city, _location, y, m, d, _region_gl, _region_cn); //取得Redis IOT 每日資訊
- await CreatIes5ProdAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2CnRead, _dingDing, y, m, d, IotTeachingDataList); //生成學校CosmosDB年月日統計資料
- await CreatTmidProdAnalData(_azureRedis, _azureCosmosClient, _dingDing, y, m, d, IotTeachingDataList); //生成TMID CosmosDB年月日統計資料
- await CreatGeoProdAnalData(_azureRedis, _azureCosmosClient, _dingDing, y, m, d, IotTeachingDataList); //生成地理位置 CosmosDB年月日統計資料
- }
- /// <summary>
- /// 取得某日CS IOT 資料
- /// </summary>
- /// <param name="_azureRedis"></param>
- /// <param name="_dingDing"></param>
- /// <param name="y">年</param>
- /// <param name="m">月(2位數)</param>
- /// <param name="d">日(2位數)</param>
- /// <returns></returns>
- public static async Task<List<IotTeachingData>> BIGetDailyRedisProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClientCsv2, DingDing _dingDing, City _city, string _location, string y, string m, string d, List<regionrow> _region_gl, List<regionrow> _region_cn)
- {
- List<IotTeachingData> IotTeachingDataList = new List<IotTeachingData>();
- try
- {
- var redisClinet2 = _azureRedis.GetRedisClient(2);
- var datetime = DateTimeOffset.UtcNow;
- var ynow = datetime.Year;
- HashSet<string> tmids = new HashSet<string>();
- Dictionary<string, string> tmidSchidDic = new Dictionary<string, string>();
- //取得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"; //有使用最小化模式
- if (!string.IsNullOrWhiteSpace(IotTeachingData.ip)) ///IP分析地理位置
- (IotTeachingData.geo, IotTeachingData.geoFromIp) = BIProdAnalysis.getGeoFromIp(_city, IotTeachingData.ip, _region_gl, _region_cn);
- 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<IotTeachingData> 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<IotTeachingData> IotTeachingDataList)
- {
- try
- {
- var redisClinet8 = _azureRedis.GetRedisClient(8);
- List<string> crtVirtualSchoolId = new List<string>(); //虛擬學校創建ID列表
- List<string> calPropList = new List<string>() { "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<ProdAnalysis> ProdAnalysisList = new List<ProdAnalysis>();
- 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<string, Dictionary<string, string>> redisSchFieldDic = new Dictionary<string, Dictionary<string, string>>(); //架構: key => schId => schJsonContent
- List<ProdAnalysisCosmos> cosmosSchList = new List<ProdAnalysisCosmos>();
- Dictionary<string, ProdAnalysisCosmos> cosmosAllSchSumDayDic = new Dictionary<string, ProdAnalysisCosmos>();
- 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<string, string>() { { schoolId, fieldContent } });
- //CosmosDB整形
- ProdAnalysisCosmos ProdAnalysisCosmosRow = prodAnalysisRow.ToJsonString().ToObject<ProdAnalysisCosmos>();
- 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<string, Dictionary<string, string>> hkeyItem in redisSchFieldDic)
- {
- //記入Redis
- string hkey = hkeyItem.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, string> fieldDic = hkeyItem.Value;
- foreach (KeyValuePair<string, string> 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<ProdAnalysisCosmos>(cosmosSchRow);
- //所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
- cosmosAllSchSumDayDic = GenAnalysisRowSumData(cosmosAllSchSumDayDic, cosmosSchRow, calPropList, "day");
- }
- //每日所有學校數據總計CosmosDB記入
- foreach (KeyValuePair<string, ProdAnalysisCosmos> schItem in cosmosAllSchSumDayDic)
- {
- string toolType = schItem.Key;
- ProdAnalysisCosmos cosmosAllSchSumDay = schItem.Value;
- cosmosAllSchSumDay.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ProdAnalysisCosmos>(cosmosAllSchSumDay);
- }
- }
- }
- //取 Redis 該月所有 ProdAnalysis:Day
- //1.生成 Redis ProdAnalysis:Month
- //2.生成 CosmosDB Month
- Dictionary<string, Dictionary<string, ProdAnalysis>> ProdAnalysisListMonth = new Dictionary<string, Dictionary<string, ProdAnalysis>>();
- Dictionary<string, ProdAnalysisCosmos> cosmosAllSchSumMonthDic = new Dictionary<string, ProdAnalysisCosmos>();
- List<ProdAnalysisCosmos> cosmosSchListMonth = new List<ProdAnalysisCosmos>();
- string patternD = $"ProdAnalysis:Day:HiT*:{y}{m}*";
- List<string> 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<ProdAnalysis>();
- //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<string, ProdAnalysis>() { { keySchId, SchDataTodo } });
- }
- }
- }
- }
- }
- if (ProdAnalysisListMonth.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, ProdAnalysis>> item in ProdAnalysisListMonth)
- {
- string monthRedisKey = item.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, ProdAnalysis> monthRedisSchDIc = item.Value;
- foreach (KeyValuePair<string, ProdAnalysis> 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<ProdAnalysisCosmos>();
- 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<ProdAnalysisCosmos>(cosmosSchRow);
- //所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
- cosmosAllSchSumMonthDic = GenAnalysisRowSumData(cosmosAllSchSumMonthDic, cosmosSchRow, calPropList, "month");
- }
- //每月所有學校數據總計CosmosDB記入
- foreach (KeyValuePair<string, ProdAnalysisCosmos> schItem in cosmosAllSchSumMonthDic)
- {
- string toolType = schItem.Key;
- ProdAnalysisCosmos cosmosAllSchSumMonth = schItem.Value;
- cosmosAllSchSumMonth.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ProdAnalysisCosmos>(cosmosAllSchSumMonth);
- }
- }
- }
- //取該年所有 CosmosDB 該年所有月份 生成CosmosDB年資料
- Dictionary<string, Dictionary<string, ProdAnalysisCosmos>> ProdAnalysisListYear = new Dictionary<string, Dictionary<string, ProdAnalysisCosmos>>();
- Dictionary<string, ProdAnalysisCosmos> cosmosAllSchSumYearDic = new Dictionary<string, ProdAnalysisCosmos>();
- 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<ProdAnalysisCosmos>();
- 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<string, ProdAnalysisCosmos>() { { schId, SchDataNow } });
- }
- }
- }
- }
- if (ProdAnalysisListYear.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, ProdAnalysisCosmos>> item in ProdAnalysisListYear)
- {
- //string toolType = item.Key;
- ProdAnalysisCosmos SchDataNow = new ProdAnalysisCosmos(); //當年某產品所有學校總和
- Dictionary<string, ProdAnalysisCosmos> yearCosmosSchDIc = item.Value;
- foreach (KeyValuePair<string, ProdAnalysisCosmos> yearCosmosSchItem in yearCosmosSchDIc)
- {
- string schId = yearCosmosSchItem.Key;
- ProdAnalysisCosmos cosmosSchRow = yearCosmosSchItem.Value;
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ProdAnalysisCosmos>(cosmosSchRow);
- //每年所有學校數據總計CosmosDB記入
- cosmosAllSchSumYearDic = GenAnalysisRowSumData(cosmosAllSchSumYearDic, cosmosSchRow, calPropList, "year");
- }
- //每年所有學校數據總計CosmosDB記入
- foreach (KeyValuePair<string, ProdAnalysisCosmos> schItem in cosmosAllSchSumYearDic)
- {
- string toolType = schItem.Key;
- ProdAnalysisCosmos cosmosAllSchSumYear = schItem.Value;
- cosmosAllSchSumYear.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ProdAnalysisCosmos>(cosmosAllSchSumYear);
- }
- //await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<ProdAnalysisCosmos>(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<School> crtVSchoolList = new List<School>();
- 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<VirtualBase>(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<IotTeachingData> IotTeachingDataList)
- {
- try
- {
- var redisClinet8 = _azureRedis.GetRedisClient(8);
- List<string> calPropList = new List<string>() { "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<TmidAnalysis> TmidAnalysisList = new List<TmidAnalysis>();
- 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<string, Dictionary<string, string>> redisTmidFieldDic = new Dictionary<string, Dictionary<string, string>>(); //架構: key => tmid => JsonContent
- List<TmidAnalysisCosmos> cosmosTmidList = new List<TmidAnalysisCosmos>();
- Dictionary<string, TmidAnalysisCosmos> cosmosAllTmidSumDayDic = new Dictionary<string, TmidAnalysisCosmos>();
- 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<string, string>() { { tmid, fieldContent } });
- //CosmosDB整形
- TmidAnalysisCosmos TmidAnalysisCosmosRow = tmidAnalysisRow.ToJsonString().ToObject<TmidAnalysisCosmos>();
- 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<string, Dictionary<string, string>> hkeyItem in redisTmidFieldDic)
- {
- string hkey = hkeyItem.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, string> fieldDic = hkeyItem.Value;
- foreach (KeyValuePair<string, string> 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<TmidAnalysisCosmos>(cosmosTmidRow);
- //所有TMID每日數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
- cosmosAllTmidSumDayDic = GenAnalysisRowSumData(cosmosAllTmidSumDayDic, cosmosTmidRow, calPropList, "day");
- }
- //每日所有TMID數據總計CosmosDB記入
- foreach (KeyValuePair<string, TmidAnalysisCosmos> tmidItem in cosmosAllTmidSumDayDic)
- {
- string toolType = tmidItem.Key;
- TmidAnalysisCosmos cosmosAllTmidSumDay = tmidItem.Value;
- cosmosAllTmidSumDay.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TmidAnalysisCosmos>(cosmosAllTmidSumDay);
- }
- }
- }
- //取 Redis 該月所有 TmidAnalysis:Day
- //1.生成 Redis TmidAnalysis:Month
- //2.生成 CosmosDB Month
- Dictionary<string, Dictionary<string, TmidAnalysis>> TmidAnalysisListMonth = new Dictionary<string, Dictionary<string, TmidAnalysis>>();
- Dictionary<string, TmidAnalysisCosmos> cosmosAllTmidSumMonthDic = new Dictionary<string, TmidAnalysisCosmos>();
- List<TmidAnalysisCosmos> cosmosTmidListMonth = new List<TmidAnalysisCosmos>();
- string patternD = $"TmidAnalysis:Day:HiT*:{y}{m}*";
- List<string> 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<TmidAnalysis>();
- //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<string, TmidAnalysis>() { { keyTMID, tmidDataTodo } });
- }
- }
- }
- }
- }
- if (TmidAnalysisListMonth.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, TmidAnalysis>> item in TmidAnalysisListMonth)
- {
- string monthRedisKey = item.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, TmidAnalysis> monthRedisTmidDIc = item.Value;
- foreach (KeyValuePair<string, TmidAnalysis> 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<TmidAnalysisCosmos>();
- 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<TmidAnalysisCosmos>(cosmosTmidRow);
- //所有學校數值加總 數值生成 cosmosAllSchSumDayDic -> key:toolType val:cosmosAllSchSumDay
- cosmosAllTmidSumMonthDic = GenAnalysisRowSumData(cosmosAllTmidSumMonthDic, cosmosTmidRow, calPropList, "day");
- }
- //每月所有TMID數據總計CosmosDB記入
- foreach (KeyValuePair<string, TmidAnalysisCosmos> tmidItem in cosmosAllTmidSumMonthDic)
- {
- string toolType = tmidItem.Key;
- TmidAnalysisCosmos cosmosAllTmidSumMonth = tmidItem.Value;
- cosmosAllTmidSumMonth.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TmidAnalysisCosmos>(cosmosAllTmidSumMonth);
- }
- }
- }
- //取該年所有 CosmosDB 該年所有月份 生成CosmosDB年資料
- Dictionary<string, Dictionary<string, TmidAnalysisCosmos>> TmidAnalysisListYear = new Dictionary<string, Dictionary<string, TmidAnalysisCosmos>>();
- Dictionary<string, TmidAnalysisCosmos> cosmosAllTmidSumYearDic = new Dictionary<string, TmidAnalysisCosmos>();
- 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<TmidAnalysisCosmos>();
- 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<string, TmidAnalysisCosmos>() { { tmid, TmidDataNow } });
- }
- }
- }
- }
- if (TmidAnalysisListYear.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, TmidAnalysisCosmos>> item in TmidAnalysisListYear)
- {
- //string toolType = item.Key;
- TmidAnalysisCosmos TmidDataNow = new TmidAnalysisCosmos(); //當年某產品所有學校總和
- Dictionary<string, TmidAnalysisCosmos> yearCosmosTmidDIc = item.Value;
- foreach (KeyValuePair<string, TmidAnalysisCosmos> yearCosmosTmidItem in yearCosmosTmidDIc)
- {
- string tmid = yearCosmosTmidItem.Key;
- TmidAnalysisCosmos cosmosTmidRow = yearCosmosTmidItem.Value;
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TmidAnalysisCosmos>(cosmosTmidRow);
- //每年所有學校數據總計CosmosDB記入
- cosmosAllTmidSumYearDic = GenAnalysisRowSumData(cosmosAllTmidSumYearDic, cosmosTmidRow, calPropList, "year");
- }
- //每年所有學校數據總計CosmosDB記入
- foreach (KeyValuePair<string, TmidAnalysisCosmos> tmidItem in cosmosAllTmidSumYearDic)
- {
- string toolType = tmidItem.Key;
- TmidAnalysisCosmos cosmosAllTmidSumYear = tmidItem.Value;
- cosmosAllTmidSumYear.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TmidAnalysisCosmos>(cosmosAllTmidSumYear);
- }
- //await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TmidAnalysisCosmos>(TmidDataNow);
- }
- }
- }
- catch (Exception ex)
- {
- _ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},CreatTmidProdAnalData() 生成TMID年月日日IOT統計資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.研發C組);
- }
- }
- //年月日 地理位置 IOT產品分析數據生成
- ///1.生成 Redis GeoAnalysis:Month
- ///2.生成 CosmosDB Month
- ///3.生成 CosmosDB 系統所有地理位置數值加總
- private static async Task CreatGeoProdAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing, string y, string m, string d, List<IotTeachingData> IotTeachingDataList)
- {
- try
- {
- var redisClinet8 = _azureRedis.GetRedisClient(8);
- List<string> calPropList = new List<string>() { "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<GeoAnalysis> GeoAnalysisList = new List<GeoAnalysis>();
- 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";
- }
- Geo geo = IotTeachingDatRow.geo;
- if(geo != null)
- {
- string countryId = (!string.IsNullOrWhiteSpace(geo.countryId)) ? geo.countryId : string.Empty;
- string provinceId = (!string.IsNullOrWhiteSpace(geo.provinceId)) ? geo.provinceId : string.Empty;
- string cityId = (!string.IsNullOrWhiteSpace(geo.cityId)) ? geo.cityId : string.Empty;
- string distId = (!string.IsNullOrWhiteSpace(geo.distId)) ? geo.distId : string.Empty;
- string geoId = $"{countryId}-{provinceId}-{cityId}-{distId}";
- if (!string.IsNullOrWhiteSpace(geo.countryId))
- {
- bool addFlg = false;
- GeoAnalysis geoAnalysisRow = GeoAnalysisList.Where(s => s.geoId.Equals(geoId) && s.toolType.Equals(toolType)).FirstOrDefault();
- //無此geoId數據=>創建
- if (geoAnalysisRow == null)
- {
- geoAnalysisRow = new GeoAnalysis();
- geoAnalysisRow.geoId = geoId;
- geoAnalysisRow.geo = geo;
- geoAnalysisRow.toolType = toolType;
- addFlg = true;
- }
- //欄位加總
- if (!geoAnalysisRow.deviceList.Contains(IotTeachingDatRow.deviceId))
- {
- geoAnalysisRow.deviceList.Add(IotTeachingDatRow.deviceId);
- }
- geoAnalysisRow.deviceCnt = geoAnalysisRow.deviceList.Count;
- switch (IotTeachingDatRow.authType)
- {
- case "0": //928授權
- if (!geoAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) geoAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
- geoAnalysisRow.lessonCnt928++;
- break;
- case "1": //ID授權
- if (!geoAnalysisRow.deviceNoAuthList.Contains(IotTeachingDatRow.deviceId)) geoAnalysisRow.deviceNoAuthList.Add(IotTeachingDatRow.deviceId);
- geoAnalysisRow.lessonCntId++;
- break;
- case "2": //機器授權
- if (!geoAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) geoAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
- geoAnalysisRow.lessonCntDevice++;
- break;
- case "3": //ID+機器授權
- if (!geoAnalysisRow.deviceAuthList.Contains(IotTeachingDatRow.deviceId)) geoAnalysisRow.deviceAuthList.Add(IotTeachingDatRow.deviceId);
- geoAnalysisRow.lessonCntIdDevice++;
- break;
- }
- geoAnalysisRow.deviceNoAuth = geoAnalysisRow.deviceNoAuthList.Count;
- geoAnalysisRow.deviceAuth = geoAnalysisRow.deviceAuthList.Count;
- if (!geoAnalysisRow.tmidList.Contains(IotTeachingDatRow.tmid))
- {
- geoAnalysisRow.tmidList.Add(IotTeachingDatRow.tmid);
- }
- geoAnalysisRow.tmidCnt = geoAnalysisRow.tmidList.Count;
- geoAnalysisRow.lessonRecord++;
- if (IotTeachingDatRow.useIES.Equals("1")) geoAnalysisRow.useIES++;
- geoAnalysisRow.useIES5Resource += IotTeachingDatRow.useIES5Resource;
- if (IotTeachingDatRow.useWebIrs.Equals("1")) geoAnalysisRow.useWebIrs++;
- if (IotTeachingDatRow.useDeviceIrs.Equals("1")) geoAnalysisRow.useDeviceIrs++;
- if (IotTeachingDatRow.useHaboard.Equals("1")) geoAnalysisRow.useHaboard++;
- if (IotTeachingDatRow.useHita.Equals("1")) geoAnalysisRow.useHita++;
- geoAnalysisRow.lessonLengMin += IotTeachingDatRow.lessonLengMin;
- if (IotTeachingDatRow.lessonLengMin.Equals(0)) geoAnalysisRow.lessonLeng0++;
- geoAnalysisRow.stuShow += IotTeachingDatRow.stuShow;
- geoAnalysisRow.stuLessonLengMin += IotTeachingDatRow.lessonLengMin * IotTeachingDatRow.stuShow;
- if (IotTeachingDatRow.tPoint >= 70) geoAnalysisRow.tGreen++;
- if (IotTeachingDatRow.lessonLengMin >= 10 && IotTeachingDatRow.tPoint > 0) geoAnalysisRow.tLesson++;
- if (IotTeachingDatRow.lTypeCoop.Equals("1")) geoAnalysisRow.lTypeCoop++;
- if (IotTeachingDatRow.lTypeIact.Equals("1")) geoAnalysisRow.lTypeIact++;
- if (IotTeachingDatRow.lTypeMis.Equals("1")) geoAnalysisRow.lTypeMis++;
- if (IotTeachingDatRow.lTypeTst.Equals("1")) geoAnalysisRow.lTypeTst++;
- if (IotTeachingDatRow.lTypeDif.Equals("1")) geoAnalysisRow.lTypeDif++;
- if (IotTeachingDatRow.lTypeCoop.Equals("0") && IotTeachingDatRow.lTypeIact.Equals("0") && IotTeachingDatRow.lTypeMis.Equals("0") && IotTeachingDatRow.lTypeTst.Equals("0") && IotTeachingDatRow.lTypeDif.Equals("0")) geoAnalysisRow.lTypeNone++;
- geoAnalysisRow.mission += IotTeachingDatRow.mission;
- geoAnalysisRow.missionFin += IotTeachingDatRow.missionFin;
- geoAnalysisRow.item += IotTeachingDatRow.item;
- geoAnalysisRow.interact += IotTeachingDatRow.interact;
- if (IotTeachingDatRow.sendSok.Equals("1")) geoAnalysisRow.sendSok++;
- if (IotTeachingDatRow.learnPeer.Equals("1")) geoAnalysisRow.learnPeer++;
- if (IotTeachingDatRow.learnCoop.Equals("1")) geoAnalysisRow.learnCoop++;
- if (IotTeachingDatRow.useWordCloud.Equals("1")) geoAnalysisRow.useWordCloud++;
- if (IotTeachingDatRow.useClouDAS.Equals("1")) geoAnalysisRow.useClouDAS++;
- if (IotTeachingDatRow.useGPT.Equals("1")) geoAnalysisRow.useGPT++;
- if (IotTeachingDatRow.useIes5Test.Equals("1")) geoAnalysisRow.useIes5Test++;
- if (IotTeachingDatRow.usePaperTest.Equals("1")) geoAnalysisRow.usePaperTest++;
- if (IotTeachingDatRow.useExcelTest.Equals("1")) geoAnalysisRow.useExcelTest++;
- if (IotTeachingDatRow.useScoreBoard.Equals("1")) geoAnalysisRow.useScoreBoard++; //課堂中使用記分板
- if (IotTeachingDatRow.learnParticipationCnt.Equals("1")) geoAnalysisRow.learnParticipationCnt++; //學習參與度次數
- geoAnalysisRow.learnParticipationT += IotTeachingDatRow.learnParticipation; //學習參與度指數(總和)
- decimal learnParticipationTmp = (geoAnalysisRow.learnParticipationCnt > 0) ? (decimal)geoAnalysisRow.learnParticipationT / (decimal)geoAnalysisRow.learnParticipationCnt : 0;
- geoAnalysisRow.learnParticipation = Math.Round(learnParticipationTmp, 2); //學習參與度指數(平均)
- geoAnalysisRow.coopMission += IotTeachingDatRow.coopMission; //協作任務數
- geoAnalysisRow.coopWork += IotTeachingDatRow.coopWork; //協作作品數
- geoAnalysisRow.coopContributionT += IotTeachingDatRow.coopContributionT; //協作總貢獻度
- geoAnalysisRow.peerAct += IotTeachingDatRow.peerAct; //互評活動次數
- geoAnalysisRow.peerStuParticipationT += IotTeachingDatRow.peerStuParticipationT; //互評學生參與總次數
- if (IotTeachingDatRow.useTransMode.Equals("1")) geoAnalysisRow.useTransMode++; //有使用透明模式
- if (IotTeachingDatRow.useMiniMode.Equals("1")) geoAnalysisRow.useMiniMode++; //有使用最小化模式
- if (!string.IsNullOrWhiteSpace(ver) && !geoAnalysisRow.verList.Contains(ver))
- {
- geoAnalysisRow.verList.Add(ver);
- }
- if (addFlg)
- {
- GeoAnalysisList.Add(geoAnalysisRow);
- }
- }
- }
- }
- }
- //1.記入CSV2 Redis TmidAnalysis:Day
- //2.記入CSV2 CosmosDB Day
- if (GeoAnalysisList.Count > 0) //[待做]
- {
- //資料整形
- Dictionary<string, Dictionary<string, string>> redisGeoFieldDic = new Dictionary<string, Dictionary<string, string>>(); //架構: key => geoId => JsonContent key = $"GeoAnalysis:Day:{toolType}:{y}{m}{d}"
- List<GeoAnalysisCosmos> cosmosGeoList = new List<GeoAnalysisCosmos>();
- Dictionary<string, GeoAnalysisCosmos> cosmosAllGeoSumDayDic = new Dictionary<string, GeoAnalysisCosmos>();
- foreach (GeoAnalysis geoAnalysisRow in GeoAnalysisList)
- {
- //Redis整形
- string toolType = geoAnalysisRow.toolType;
- string geoId = geoAnalysisRow.geoId;
- string hkey = $"GeoAnalysis:Day:{toolType}:{y}{m}{d}";
- string fieldContent = geoAnalysisRow.ToJsonString();
- if (redisGeoFieldDic.ContainsKey(hkey)) redisGeoFieldDic[hkey].Add(geoId, fieldContent);
- else redisGeoFieldDic.Add(hkey, new Dictionary<string, string>() { { geoId, fieldContent } });
- //CosmosDB整形
- GeoAnalysisCosmos GeoAnalysisCosmosRow = geoAnalysisRow.ToJsonString().ToObject<GeoAnalysisCosmos>();
- GeoAnalysisCosmosRow.date = $"{y}{m}{d}";
- GeoAnalysisCosmosRow.year = Convert.ToInt32(y, 10);
- GeoAnalysisCosmosRow.month = Convert.ToInt32(m, 10);
- GeoAnalysisCosmosRow.day = Convert.ToInt32(d, 10);
- DateTimeOffset dateTime = new DateTimeOffset(GeoAnalysisCosmosRow.year, GeoAnalysisCosmosRow.month, GeoAnalysisCosmosRow.day, 0, 0, 0, TimeSpan.Zero);
- GeoAnalysisCosmosRow.dateTime = dateTime.ToUnixTimeSeconds();
- GeoAnalysisCosmosRow.id = $"{GeoAnalysisCosmosRow.toolType}-{GeoAnalysisCosmosRow.date}-{geoId}";
- GeoAnalysisCosmosRow.dateUnit = "day";
- GeoAnalysisCosmosRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- cosmosGeoList.Add(GeoAnalysisCosmosRow);
- }
- //記入Redis
- if (redisGeoFieldDic.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, string>> hkeyItem in redisGeoFieldDic)
- {
- string hkey = hkeyItem.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, string> fieldDic = hkeyItem.Value;
- foreach (KeyValuePair<string, string> geoItem in fieldDic)
- {
- string geoId = geoItem.Key;
- string fieldContent = geoItem.Value;
- hvalList.Add(new HashEntry($"{geoId}", fieldContent));
- }
- await redisClinet8.HashSetAsync(hkey, hvalList.ToArray());
- }
- }
- //記入CosmosDB
- if (cosmosGeoList.Count > 0)
- {
- foreach (GeoAnalysisCosmos cosmosGeoRow in cosmosGeoList)
- {
- //各geoId每日CosmosDB記入
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosGeoRow);
- //所有geoId每日數值加總 數值生成 cosmosAllGeoSumDayDic -> key:toolType val:cosmosAllGeoSumDay
- cosmosAllGeoSumDayDic = GenAnalysisRowSumData(cosmosAllGeoSumDayDic, cosmosGeoRow, calPropList, "day");
- }
- //每日所有geoId數據總計CosmosDB記入
- foreach (KeyValuePair<string, GeoAnalysisCosmos> geoItem in cosmosAllGeoSumDayDic)
- {
- string toolType = geoItem.Key;
- GeoAnalysisCosmos cosmosAllGeoSumDay = geoItem.Value;
- cosmosAllGeoSumDay.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosAllGeoSumDay);
- }
- }
- }
- //取 Redis 該月所有 GeoAnalysis:Day
- //1.生成 Redis GeoAnalysis:Month
- //2.生成 CosmosDB Month
- Dictionary<string, Dictionary<string, GeoAnalysis>> GeoAnalysisListMonth = new Dictionary<string, Dictionary<string, GeoAnalysis>>();
- Dictionary<string, GeoAnalysisCosmos> cosmosAllGeoSumMonthDic = new Dictionary<string, GeoAnalysisCosmos>();
- List<GeoAnalysisCosmos> cosmosGeoListMonth = new List<GeoAnalysisCosmos>();
- string patternD = $"GeoAnalysis:Day:HiT*:{y}{m}*";
- List<string> keysDayList = ScanRedisKeysByPattern(_azureRedis, patternD);
- if (keysDayList.Count > 0)
- {
- foreach (string keyDay in keysDayList)
- {
- string[] keyItemList = keyDay.Split(':'); //[例] GeoAnalysis: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 geoAnalMonthKey = $"GeoAnalysis:Month:{toolType}:{dateStrD_y}{dateStrD_m}";
- bool geoAnalysisDayExist = await redisClinet8.KeyExistsAsync(keyDay);
- if (geoAnalysisDayExist && !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 keyGeoId = hset.Name;
- string valGeoDataJson = hset.Value;
- GeoAnalysis geoDataTodo = valGeoDataJson.ToObject<GeoAnalysis>();
- //Redis Month 資料生成
- if (GeoAnalysisListMonth.ContainsKey(geoAnalMonthKey)) //月Dic已有此key => geoId累加
- {
- if (GeoAnalysisListMonth[$"{geoAnalMonthKey}"].ContainsKey($"{keyGeoId}"))
- {
- GeoAnalysis GeoDataNow = GeoAnalysisListMonth[$"{geoAnalMonthKey}"][$"{keyGeoId}"];
- foreach (PropertyInfo propertyInfo in GeoDataNow.GetType().GetProperties())
- {
- if (calPropList.Contains(propertyInfo.Name))
- {
- var propType = propertyInfo.PropertyType;
- var valNow = propertyInfo.GetValue(GeoDataNow);
- var valTodo = geoDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(geoDataTodo);
- if (propType.Equals(typeof(long))) propertyInfo.SetValue(GeoDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
- else propertyInfo.SetValue(GeoDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
- }
- }
- GeoDataNow.deviceList = GeoDataNow.deviceList.Union(geoDataTodo.deviceList).ToList();
- GeoDataNow.deviceCnt = GeoDataNow.deviceList.Count;
- GeoDataNow.deviceAuthList = GeoDataNow.deviceAuthList.Union(geoDataTodo.deviceAuthList).ToList();
- GeoDataNow.deviceAuth = GeoDataNow.deviceAuthList.Count;
- GeoDataNow.deviceNoAuthList = GeoDataNow.deviceNoAuthList.Union(geoDataTodo.deviceNoAuthList).ToList();
- GeoDataNow.deviceNoAuth = GeoDataNow.deviceNoAuthList.Count;
- GeoDataNow.tmidList = GeoDataNow.tmidList.Union(geoDataTodo.tmidList).ToList();
- GeoDataNow.tmidCnt = GeoDataNow.tmidList.Count;
- GeoDataNow.verList = GeoDataNow.verList.Union(geoDataTodo.verList).ToList();
- }
- //無TMID資料 => 該TMID資料放入
- else
- {
- GeoAnalysisListMonth[$"{geoAnalMonthKey}"][$"{keyGeoId}"] = geoDataTodo;
- }
- }
- else //無此月資料 => 所有TMID資料放入
- {
- GeoAnalysisListMonth.Add(geoAnalMonthKey, new Dictionary<string, GeoAnalysis>() { { keyGeoId, geoDataTodo } });
- }
- }
- }
- }
- }
- if (GeoAnalysisListMonth.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, GeoAnalysis>> item in GeoAnalysisListMonth)
- {
- string monthRedisKey = item.Key;
- List<HashEntry> hvalList = new List<HashEntry>();
- Dictionary<string, GeoAnalysis> monthRedisGeoDIc = item.Value;
- foreach (KeyValuePair<string, GeoAnalysis> monthRedisGeoItem in monthRedisGeoDIc)
- {
- string monthRedisGeo = monthRedisGeoItem.Key;
- GeoAnalysis monthRedisGeoData = monthRedisGeoItem.Value;
- //Redis資料製作
- hvalList.Add(new HashEntry(monthRedisGeo, monthRedisGeoData.ToJsonString()));
- //CosmosDB資料製作
- GeoAnalysisCosmos cosmosGeoRow = monthRedisGeoData.ToJsonString().ToObject<GeoAnalysisCosmos>();
- cosmosGeoRow.date = $"{y}{m}";
- cosmosGeoRow.year = Convert.ToInt32(y, 10);
- cosmosGeoRow.month = Convert.ToInt32(m, 10);
- DateTimeOffset dateTime = new DateTimeOffset(cosmosGeoRow.year, cosmosGeoRow.month, 1, 0, 0, 0, TimeSpan.Zero);
- cosmosGeoRow.dateTime = dateTime.ToUnixTimeSeconds();
- cosmosGeoRow.id = $"{monthRedisGeoData.toolType}-{cosmosGeoRow.date}-{monthRedisGeo}";
- cosmosGeoRow.dateUnit = "month";
- cosmosGeoRow.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- cosmosGeoListMonth.Add(cosmosGeoRow);
- }
- //記入Redis
- await redisClinet8.HashSetAsync($"{monthRedisKey}", hvalList.ToArray());
- }
- //記入CosmosDB
- if (cosmosGeoListMonth.Count > 0)
- {
- foreach (GeoAnalysisCosmos cosmosGeoRow in cosmosGeoListMonth)
- {
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosGeoRow);
- //所有地理位置數值加總 數值生成 cosmosAllGeoSumDayDic -> key:toolType val:cosmosAllGeoSumDay
- cosmosAllGeoSumMonthDic = GenAnalysisRowSumData(cosmosAllGeoSumMonthDic, cosmosGeoRow, calPropList, "day");
- }
- //每月所有geoId數據總計CosmosDB記入
- foreach (KeyValuePair<string, GeoAnalysisCosmos> geoItem in cosmosAllGeoSumMonthDic)
- {
- string toolType = geoItem.Key;
- GeoAnalysisCosmos cosmosAllGeoSumMonth = geoItem.Value;
- cosmosAllGeoSumMonth.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosAllGeoSumMonth);
- }
- }
- }
- //取該年所有 CosmosDB 該年所有月份 生成CosmosDB年資料
- Dictionary<string, Dictionary<string, GeoAnalysisCosmos>> GeoAnalysisListYear = new Dictionary<string, Dictionary<string, GeoAnalysisCosmos>>();
- Dictionary<string, GeoAnalysisCosmos> cosmosAllGeoSumYearDic = new Dictionary<string, GeoAnalysisCosmos>();
- var query = $"SELECT * FROM c WHERE c.year = {y} AND c.dateUnit = 'month' AND c.geoId != 'allgeoid'";
- await foreach (var itemcr in _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").GetItemQueryStreamIteratorSql(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("GeoAnalysis") }))
- {
- 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())
- {
- GeoAnalysisCosmos GeoDataTodo = obj.ToObject<GeoAnalysisCosmos>();
- string toolType = GeoDataTodo.toolType;
- string geoId = GeoDataTodo.geoId;
- //年Dic已有此key => 分校累加
- if (GeoAnalysisListYear.ContainsKey(toolType))
- {
- if (GeoAnalysisListYear[$"{toolType}"].ContainsKey($"{geoId}"))
- {
- GeoAnalysisCosmos GeoDataNow = GeoAnalysisListYear[$"{toolType}"][$"{geoId}"];
- foreach (PropertyInfo propertyInfo in GeoDataNow.GetType().GetProperties())
- {
- if (calPropList.Contains(propertyInfo.Name))
- {
- var propType = propertyInfo.PropertyType;
- var valNow = propertyInfo.GetValue(GeoDataNow);
- var valTodo = GeoDataTodo.GetType().GetProperty(propertyInfo.Name).GetValue(GeoDataTodo);
- if (propType.Equals(typeof(long))) propertyInfo.SetValue(GeoDataNow, Convert.ToInt64(valNow.ToString(), 10) + Convert.ToInt64(valTodo.ToString(), 10));
- else propertyInfo.SetValue(GeoDataNow, Convert.ToInt32(valNow.ToString(), 10) + Convert.ToInt32(valTodo.ToString(), 10));
- }
- }
- GeoDataNow.deviceList = GeoDataNow.deviceList.Union(GeoDataTodo.deviceList).ToList();
- GeoDataNow.deviceCnt = GeoDataNow.deviceList.Count;
- GeoDataNow.deviceAuthList = GeoDataNow.deviceAuthList.Union(GeoDataTodo.deviceAuthList).ToList();
- GeoDataNow.deviceAuth = GeoDataNow.deviceAuthList.Count;
- GeoDataNow.deviceNoAuthList = GeoDataNow.deviceNoAuthList.Union(GeoDataTodo.deviceNoAuthList).ToList();
- GeoDataNow.deviceNoAuth = GeoDataNow.deviceNoAuthList.Count;
- GeoDataNow.tmidList = GeoDataNow.tmidList.Union(GeoDataTodo.tmidList).ToList();
- GeoDataNow.tmidCnt = GeoDataNow.tmidList.Count;
- GeoDataNow.verList = GeoDataNow.verList.Union(GeoDataTodo.verList).ToList();
- }
- //無此校資料 => 該校資料放入
- else
- {
- GeoAnalysisCosmos GeoDataNow = GeoDataTodo;
- GeoDataNow.date = $"{y}";
- GeoDataNow.year = Convert.ToInt32(y, 10);
- GeoDataNow.month = 0;
- DateTimeOffset dateTime = new DateTimeOffset(GeoDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
- GeoDataNow.dateTime = dateTime.ToUnixTimeSeconds();
- GeoDataNow.id = $"{toolType}-{y}-{geoId}";
- GeoDataNow.dateUnit = "year";
- GeoAnalysisListYear[$"{toolType}"][$"{geoId}"] = GeoDataNow;
- }
- }
- //無此年資料 => 所有學校資料放入
- else
- {
- GeoAnalysisCosmos GeoDataNow = GeoDataTodo;
- GeoDataNow.date = $"{y}";
- GeoDataNow.year = Convert.ToInt32(y, 10);
- GeoDataNow.month = 0;
- DateTimeOffset dateTime = new DateTimeOffset(GeoDataNow.year, 1, 1, 0, 0, 0, TimeSpan.Zero);
- GeoDataNow.dateTime = dateTime.ToUnixTimeSeconds();
- GeoDataNow.id = $"{toolType}-{y}-{geoId}";
- GeoDataNow.dateUnit = "year";
- GeoAnalysisListYear.Add(toolType, new Dictionary<string, GeoAnalysisCosmos>() { { geoId, GeoDataNow } });
- }
- }
- }
- }
- if (GeoAnalysisListYear.Count > 0)
- {
- foreach (KeyValuePair<string, Dictionary<string, GeoAnalysisCosmos>> item in GeoAnalysisListYear)
- {
- //string toolType = item.Key;
- GeoAnalysisCosmos GeoDataNow = new GeoAnalysisCosmos(); //當年某產品所有地理位置總和
- Dictionary<string, GeoAnalysisCosmos> yearCosmosGeoDIc = item.Value;
- foreach (KeyValuePair<string, GeoAnalysisCosmos> yearCosmosGeoItem in yearCosmosGeoDIc)
- {
- string tmid = yearCosmosGeoItem.Key;
- GeoAnalysisCosmos cosmosGeoRow = yearCosmosGeoItem.Value;
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosGeoRow);
- //每年所有學校數據總計CosmosDB記入
- cosmosAllGeoSumYearDic = GenAnalysisRowSumData(cosmosAllGeoSumYearDic, cosmosGeoRow, calPropList, "year");
- }
- //每年所有學校數據總計CosmosDB記入
- foreach (KeyValuePair<string, GeoAnalysisCosmos> geoItem in cosmosAllGeoSumYearDic)
- {
- string toolType = geoItem.Key;
- GeoAnalysisCosmos cosmosAllGeoSumYear = geoItem.Value;
- cosmosAllGeoSumYear.createDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
- await _azureCosmosClient.GetContainer(Constant.TEAMModelOS, "Common").UpsertItemAsync<GeoAnalysisCosmos>(cosmosAllGeoSumYear);
- }
- }
- }
- }
- catch (Exception ex)
- {
- _ = _dingDing.SendBotMsg($"BI,{Environment.GetEnvironmentVariable("Option:Location")},CreatGeoProdAnalData() 生成地理資訊年月日日IOT統計資料錯誤\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.研發C組);
- }
- }
- public static (Geo, List<string>) getGeoFromIp(City _city, string ip, List<regionrow> _region_gl, List<regionrow> _region_cn)
- {
- var ipInfo = _city.find(ip, "CN");
- //輸出定義
- List<string> ipToGeoList = (ipInfo != null) ? ipInfo.ToList() : new List<string>(); ///直接由IP取得的地理資訊
- IotTeachingData.Geo geo = null; ///地理資訊
- if(ipInfo == null) return (geo, ipToGeoList);
- else geo = new IotTeachingData.Geo();
- //國省市字典製作
- regiondata regionData = GetRegionData(_region_gl, _region_cn); //取得國省市區地理資訊架構
- List<string> comeRemoveStr = GeoRegion.comeRemoveStr;
- ///國字典製作
- var geoCountryIdNameDic = new Dictionary<string, string>();
- foreach (KeyValuePair<string, regionbase> item in regionData.country)
- {
- geoCountryIdNameDic.Add(item.Value.code, item.Value.name);
- }
- ///省字典製作
- var geoProvinceIdNameDic = new Dictionary<string, string>();
- foreach (KeyValuePair<string, regionbase> item in regionData.province["CN"])
- {
- geoProvinceIdNameDic.Add(item.Value.code, item.Value.name);
- }
- ///市字典製作
- var geoCityIdNameDic = new Dictionary<string, Dictionary<string, string>>();
- geoCityIdNameDic.Add("TW", new Dictionary<string, string>());
- geoCityIdNameDic.Add("CN", new Dictionary<string, string>());
- List<string> municipalityId = GeoRegion.municipalityId; //大陸直轄市的省ID
- foreach (var itemCountry in regionData.city)
- {
- if (itemCountry.Key.Equals("TW"))
- {
- foreach (var itemCity in regionData.city["TW"]["tw"])
- {
- geoCityIdNameDic["TW"].Add(itemCity.Value.code, itemCity.Value.name);
- }
- }
- else if (itemCountry.Key.Equals("CN"))
- {
- foreach (var itemProvince in regionData.city["CN"])
- {
- string provinceIdTmp = itemProvince.Key;
- foreach (var itemCity in regionData.city["CN"][provinceIdTmp])
- {
- geoCityIdNameDic["CN"].Add(itemCity.Value.code, itemCity.Value.name);
- }
- }
- }
- }
- //地理資料生成
- if (ipToGeoList[0].Equals("中国") && ipToGeoList[1].Equals("台湾"))
- {
- geo.countryId = "TW";
- geo.countryName = geoCountryIdNameDic["TW"];
- comeRemoveStr.ForEach(c => { geo.countryName = geo.countryName.Replace(c, ""); });
- string cityNameTmp = ipToGeoList[2];
- if (!string.IsNullOrWhiteSpace(cityNameTmp))
- {
- cityNameTmp = ChineseConverter.Convert(cityNameTmp, ChineseConversionDirection.SimplifiedToTraditional);
- comeRemoveStr.ForEach(c => { cityNameTmp = cityNameTmp.Replace(c, ""); });
- var cityDicRow = geoCityIdNameDic["TW"].FirstOrDefault(c => c.Value.Contains(cityNameTmp));
- if (!cityDicRow.Equals(default(KeyValuePair<string, string>)))
- {
- geo.cityId = cityDicRow.Key;
- geo.cityName = cityDicRow.Value;
- comeRemoveStr.ForEach(c => { geo.cityName = geo.cityName.Replace(c, ""); });
- }
- }
- }
- else if (ipToGeoList[0].Equals("中国"))
- {
- geo.countryId = "CN";
- geo.countryName = geoCountryIdNameDic["CN"];
- string provinceNameTmp = ipToGeoList[1];
- comeRemoveStr.ForEach(p => { provinceNameTmp = provinceNameTmp.Replace(p, ""); });
- var provinceDicRow = geoProvinceIdNameDic.FirstOrDefault(p => p.Value.Contains(provinceNameTmp));
- if (!provinceDicRow.Equals(default(KeyValuePair<string, string>)))
- {
- geo.provinceId = provinceDicRow.Key;
- geo.provinceName = provinceDicRow.Value;
- comeRemoveStr.ForEach(c => { geo.provinceName = geo.provinceName.Replace(c, ""); });
- }
- string cityNameTmp = ipToGeoList[2];
- if (!string.IsNullOrWhiteSpace(cityNameTmp))
- {
- comeRemoveStr.ForEach(c => { cityNameTmp = cityNameTmp.Replace(c, ""); });
- if (!string.IsNullOrWhiteSpace(geo.provinceId) && municipalityId.Contains(geo.provinceId)) ///直轄市處理
- {
- var cityDicFromRegion = regionData.city["CN"][geo.provinceId].First();
- string cityId = cityDicFromRegion.Key;
- geo.cityId = cityId;
- geo.cityName = geoCityIdNameDic["CN"][cityId];
- }
- else ///非直轄市
- {
- var cityDicRow = geoCityIdNameDic["CN"].FirstOrDefault(c => c.Value.Contains(cityNameTmp));
- if (!cityDicRow.Equals(default(KeyValuePair<string, string>)))
- {
- geo.cityId = cityDicRow.Key;
- geo.cityName = cityDicRow.Value;
- comeRemoveStr.ForEach(c => { geo.cityName = geo.cityName.Replace(c, ""); });
- }
- }
- }
- }
- else
- {
- string countryNameTmp = ipToGeoList[0];
- countryNameTmp = ChineseConverter.Convert(countryNameTmp, ChineseConversionDirection.SimplifiedToTraditional);
- var countryDicRow = geoCountryIdNameDic.FirstOrDefault(c => c.Value.Contains(countryNameTmp));
- if (!countryDicRow.Equals(default(KeyValuePair<string, string>)))
- {
- geo.countryId = countryDicRow.Key;
- geo.countryName = countryDicRow.Value;
- }
- }
- return ( geo, ipToGeoList );
- }
- //生成年月日 Device IOT產品分析數據 [待做]
- private static async Task CreatDeviceAnalData(AzureRedisFactory _azureRedis, CosmosClient _azureCosmosClient, DingDing _dingDing, string y, string m, string d, List<IotTeachingData> 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<string, ProdAnalysisCosmos> GenAnalysisRowSumData(Dictionary<string, ProdAnalysisCosmos> cosmosAllSumDic, ProdAnalysisCosmos cosmosRow, List<string> 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<string, TmidAnalysisCosmos> GenAnalysisRowSumData(Dictionary<string, TmidAnalysisCosmos> cosmosAllSumDic, TmidAnalysisCosmos cosmosRow, List<string> 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;
- }
- }
- //累加各地理位置(geoId)每日/月總計資料,生成所有geoId每日/月總計資料
- private static Dictionary<string, GeoAnalysisCosmos> GenAnalysisRowSumData(Dictionary<string, GeoAnalysisCosmos> cosmosAllSumDic, GeoAnalysisCosmos cosmosRow, List<string> calPropList, string dataType) //dataType:"day","month","year"
- {
- try
- {
- string toolType = cosmosRow.toolType;
- string geoId = "allgeoid";
- 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;
- }
- GeoAnalysisCosmos cosmosAllSum = new GeoAnalysisCosmos();
- 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.geoId = geoId;
- cosmosAllSum.geo = null;
- cosmosAllSum.toolType = cosmosRow.toolType;
- cosmosAllSum.date = cosmosRow.date;
- cosmosAllSum.id = $"{cosmosAllSum.toolType}-{cosmosAllSum.date}-{geoId}";
- 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;
- }
- }
- /// <summary>
- /// 取得Redis(8)符合搜尋模式的key
- /// </summary>
- /// <param name="pattern"></param>
- /// <returns></returns>
- public static List<string> ScanRedisKeysByPattern(AzureRedisFactory _azureRedis, string pattern)
- {
- var redisClinet8 = _azureRedis.GetRedisClient(8);
- var keys = new HashSet<RedisKey>();
- 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<RedisKey> resultLines = ((RedisKey[])innerResult[1]).ToList();
- keys.UnionWith(resultLines);
- }
- while (nextCursor != 0);
- List<string> result = new List<string>();
- if (keys.Count > 0)
- {
- foreach (RedisKey key in keys)
- {
- result.Add(key.ToString());
- }
- }
- return result;
- }
- //public static List<string> GetGeoFromIp(string ip)
- //{
- //}
- }
- }
|