|
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Configuration;
|
|
|
using Microsoft.Extensions.Options;
|
|
|
using System;
|
|
|
using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
using System.Text.Json;
|
|
|
using System.Threading.Tasks;
|
|
|
using TEAMModelOS.Models;
|
|
@@ -50,70 +51,147 @@ namespace TEAMModelBI.Controllers.BITmid
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
+ if (!jsonElement.TryGetProperty("tmids", out JsonElement tmidsJobj)) return BadRequest();//TMID(array)
|
|
|
+ var tmids = tmidsJobj.Deserialize<List<string>>();
|
|
|
+ if (tmids.Count is 0) return BadRequest();
|
|
|
+
|
|
|
+ //服務Client端
|
|
|
var cosmosClientIes5 = _azureCosmos.GetCosmosClient(); //CosmosDB IES5
|
|
|
var cosmosClientCsv2 = _azureCosmos.GetCosmosClient(name: "CoreServiceV2"); //CosmosDB CSV2
|
|
|
var storageClientCsv2 = _azureStorage.GetCloudTableClient(name: "CoreServiceV2"); //Storage CSV2
|
|
|
- //取得參數
|
|
|
- if (!jsonElement.TryGetProperty("tmids", out JsonElement tmidsJobj)) return BadRequest();//TMID(array)
|
|
|
- List<string> tmids = tmidsJobj.ToObject<List<string>>();
|
|
|
-
|
|
|
- Dictionary<string, TmidStics> tmidDic = new Dictionary<string, TmidStics>();
|
|
|
- if (tmids.Count.Equals(0)) return BadRequest();
|
|
|
- else
|
|
|
+ var tableCouponClient = storageClientCsv2.GetTableReference("Coupon");
|
|
|
+ var tablePointsClient = storageClientCsv2.GetTableReference("Points");
|
|
|
+ var redisClient = _azureRedis.GetRedisClient(4, _option.Location);
|
|
|
+
|
|
|
+ //存放user資料
|
|
|
+ Dictionary<string, TmidStics> tmidDic = new();
|
|
|
+
|
|
|
+ QueryDefinition query =
|
|
|
+ new QueryDefinition(@"SELECT c.id, c.name, c.mobile, c.mail FROM c WHERE (ARRAY_CONTAINS(@key, c.id))")
|
|
|
+ .WithParameter("@key", tmids);
|
|
|
+ await foreach (var item in cosmosClientCsv2
|
|
|
+ .GetContainer("Core", "ID2")
|
|
|
+ .GetItemQueryStreamIterator(query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("base") }))
|
|
|
{
|
|
|
- //Core
|
|
|
- //基本資料
|
|
|
- string tmidListStr = JsonSerializer.Serialize(tmids);
|
|
|
- string sqlIdBase = $"SELECT c.id, c.name, c.mail, c.mobile FROM c WHERE ARRAY_CONTAINS({tmidListStr}, c.id, true)";
|
|
|
- await foreach (var item in cosmosClientCsv2.GetContainer("Core", "ID2").GetItemQueryStreamIterator(queryText: sqlIdBase, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"base") }))
|
|
|
+ using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
|
+ if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
|
{
|
|
|
- var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
|
- foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
|
|
|
+ foreach (var doc in json.RootElement.GetProperty("Documents").EnumerateArray())
|
|
|
{
|
|
|
- string tmid = obj.GetProperty("id").GetString();
|
|
|
- string name = Convert.ToString(obj.GetProperty("name"));
|
|
|
- string mail = (obj.TryGetProperty("mail", out JsonElement mailJ)) ? Convert.ToString(mailJ) : string.Empty;
|
|
|
- string mobile = (obj.TryGetProperty("mobile", out JsonElement mobileJ)) ? Convert.ToString(mobileJ) : string.Empty;
|
|
|
- if (!tmidDic.ContainsKey(tmid))
|
|
|
+ string id = doc.GetProperty("id").GetString();
|
|
|
+ //基本資料
|
|
|
+ TmidStics tmidStics = (tmidDic.ContainsKey(id)) ? tmidDic[id] : new() { id = id };
|
|
|
+ tmidStics.name = doc.GetProperty("name").GetString();
|
|
|
+ tmidStics.mobile = doc.GetProperty("mobile").GetString();
|
|
|
+ tmidStics.mail = doc.GetProperty("mail").GetString();
|
|
|
+
|
|
|
+ //票券
|
|
|
+ var usersCoupons = tableCouponClient.Get<DynamicTableEntity>(id);
|
|
|
+ foreach (var coupon in usersCoupons)
|
|
|
{
|
|
|
- TmidStics tmidStics = new TmidStics();
|
|
|
- tmidStics.id = tmid;
|
|
|
- tmidStics.name = name;
|
|
|
- tmidStics.mail = mail;
|
|
|
- tmidStics.mobile = mobile;
|
|
|
- tmidDic.Add(tmid, tmidStics);
|
|
|
+ tmidStics.TmidCoupons.Add(
|
|
|
+ new TmidCoupon()
|
|
|
+ {
|
|
|
+ code = coupon.RowKey,
|
|
|
+ exchange = coupon.Properties["exchangeTime"].DateTimeOffsetValue.Value.ToUnixTimeSeconds(),
|
|
|
+ });
|
|
|
}
|
|
|
+
|
|
|
+ //登入各服務的時間
|
|
|
+ var loginTime = await redisClient.HashGetAllAsync(id);
|
|
|
+ foreach (var t in loginTime)
|
|
|
+ {
|
|
|
+ if (!t.Name.StartsWith("HiTeach") && !_dicClientIds.ContainsKey(t.Name)) continue;
|
|
|
+ tmidStics.TmidLoginTime.Add(
|
|
|
+ new TmidLoginTime()
|
|
|
+ {
|
|
|
+ product = t.Name.StartsWith("HiTeach") ? t.Name.ToString().Split("-")[0] : _dicClientIds[t.Name],
|
|
|
+ time = (long)t.Value
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ //積分
|
|
|
+ var usersPoints = tablePointsClient.Get("Points", id);
|
|
|
+ tmidStics.points.points = usersPoints.Properties["Points"].Int32Value.Value;
|
|
|
+ tmidStics.points.level = usersPoints.Properties["Level"].Int32Value.Value;
|
|
|
+ tmidStics.points.balance = usersPoints.Properties["Balance"].Int32Value.Value;
|
|
|
+
|
|
|
+ tmidDic.Add(id, tmidStics);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- //IES5
|
|
|
- //個人空間使用狀況
|
|
|
- foreach (KeyValuePair<string, TmidStics> dicItem in tmidDic)
|
|
|
+ //ID進階資料
|
|
|
+ QueryDefinition queryex = new QueryDefinition(@"SELECT c.id, c.name, c.mobile, c.mail, c.country, c.province, c.city, c.schoolCode, c.schoolCodeW FROM c WHERE (ARRAY_CONTAINS(@key, c.id))")
|
|
|
+ .WithParameter("@key", tmids);
|
|
|
+ await foreach (var item in cosmosClientCsv2
|
|
|
+ .GetContainer("Core", "ID2")
|
|
|
+ .GetItemQueryStreamIterator(queryex, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("base-ex") }))
|
|
|
+ {
|
|
|
+ using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
|
+ if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
|
{
|
|
|
- string tmidNow = dicItem.Key;
|
|
|
- var space = await BlobService.GetSurplusSpace(tmidNow, "private", _option.Location, _azureCosmos, _azureRedis, _azureStorage, _dingDing, _httpTrigger);
|
|
|
- tmidDic[tmidNow].ies5.usedSize = space.usedSize;
|
|
|
- tmidDic[tmidNow].ies5.teachSize = space.teach * 1073741824;
|
|
|
- tmidDic[tmidNow].ies5.totalSize = space.total * 1073741824;
|
|
|
- tmidDic[tmidNow].ies5.surplusSize = space.surplus;
|
|
|
+ foreach (var doc in json.RootElement.GetProperty("Documents").EnumerateArray())
|
|
|
+ {
|
|
|
+ string id = doc.GetProperty("id").GetString();
|
|
|
+ TmidStics tmidStics = (tmidDic.ContainsKey(id)) ? tmidDic[id] : new() { id = id };
|
|
|
+ if (string.IsNullOrWhiteSpace(tmidStics.name)) tmidStics.name = doc.GetProperty("name").GetString();
|
|
|
+ if (string.IsNullOrWhiteSpace(tmidStics.mobile)) tmidStics.mobile = doc.GetProperty("mobile").GetString();
|
|
|
+ if (string.IsNullOrWhiteSpace(tmidStics.mail)) tmidStics.mail = doc.GetProperty("mail").GetString();
|
|
|
+ tmidStics.country = doc.GetProperty("country").GetString();
|
|
|
+ tmidStics.province = doc.GetProperty("province").GetString();
|
|
|
+ tmidStics.city = doc.GetProperty("city").GetString();
|
|
|
+ tmidStics.schoolCode = doc.GetProperty("schoolCode").GetString();
|
|
|
+ tmidStics.schoolCodeW = doc.GetProperty("schoolCodeW").GetString();
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ //蘇格拉底資料
|
|
|
+ query = new QueryDefinition(@"SELECT * FROM c WHERE (ARRAY_CONTAINS(@key, c.id))")
|
|
|
+ .WithParameter("@key", tmidDic.Keys.ToList());
|
|
|
|
|
|
- //積分
|
|
|
- var tablePoints = storageClientCsv2.GetTableReference("Points");
|
|
|
- foreach (KeyValuePair<string, TmidStics> dicItem in tmidDic)
|
|
|
+ await foreach (var item in cosmosClientCsv2
|
|
|
+ .GetContainer("Core", "ID2")
|
|
|
+ .GetItemQueryStreamIterator(query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("sokrates") }))
|
|
|
+ {
|
|
|
+ using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
|
+ if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
|
{
|
|
|
- string tmidNow = dicItem.Key;
|
|
|
- List<string> sp = new List<string>() { "Get" };
|
|
|
- var pointsResult = tablePoints.Get<TmidSticsPoint>(partitionKey: tmidNow);
|
|
|
- foreach(TmidSticsPoint pointsRow in pointsResult)
|
|
|
+ foreach (var doc in json.RootElement.GetProperty("Documents").EnumerateArray())
|
|
|
{
|
|
|
- tmidDic[tmidNow].points += pointsRow.Get;
|
|
|
+ string id = doc.GetProperty("id").GetString();
|
|
|
+ if (doc.TryGetProperty("hiteach_data", out var elementHiteachData))
|
|
|
+ {
|
|
|
+ if (elementHiteachData.TryGetProperty("total", out var elementTotal))
|
|
|
+ {
|
|
|
+ if (elementTotal.TryGetProperty("t_data", out var tDataValue)) tmidDic[id].sokrates.t_data = tDataValue.GetString();
|
|
|
+ if (elementTotal.TryGetProperty("t_green", out var tGreenValue)) tmidDic[id].sokrates.t_green = tGreenValue.GetString();
|
|
|
+ if (elementTotal.TryGetProperty("duration", out var durationValue)) tmidDic[id].sokrates.duration = durationValue.GetString();
|
|
|
+ if (elementTotal.TryGetProperty("attendance", out var attendanceValue)) tmidDic[id].sokrates.attendance = attendanceValue.GetString();
|
|
|
+ if (elementTotal.TryGetProperty("interaction", out var interactionValue)) tmidDic[id].sokrates.interaction = interactionValue.GetString();
|
|
|
+ if (elementTotal.TryGetProperty("learning_duration", out var learningDurationValue)) tmidDic[id].sokrates.learning_duration = learningDurationValue.GetString();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //IES5
|
|
|
+ //個人空間使用狀況
|
|
|
+ foreach (KeyValuePair<string, TmidStics> dicItem in tmidDic)
|
|
|
+ {
|
|
|
+ string tmidNow = dicItem.Key;
|
|
|
+ var (usedSize, teach, total, surplus, catalog) = await BlobService.GetSurplusSpace(tmidNow, "private", _option.Location, _azureCosmos, _azureRedis, _azureStorage, _dingDing, _httpTrigger);
|
|
|
+ tmidDic[tmidNow].ies5.usedSize = usedSize;
|
|
|
+ tmidDic[tmidNow].ies5.teachSize = teach * 1073741824;
|
|
|
+ tmidDic[tmidNow].ies5.totalSize = total * 1073741824;
|
|
|
+ tmidDic[tmidNow].ies5.surplusSize = surplus;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
//輸出
|
|
|
- List<object> data = new List<object>();
|
|
|
+ List<object> data = new();
|
|
|
foreach (KeyValuePair<string, TmidStics> dicItem in tmidDic)
|
|
|
{
|
|
|
data.Add(dicItem.Value);
|
|
@@ -128,19 +206,25 @@ namespace TEAMModelBI.Controllers.BITmid
|
|
|
}
|
|
|
|
|
|
//Model
|
|
|
+
|
|
|
//TMID統計 基本資訊
|
|
|
private class TmidStics
|
|
|
{
|
|
|
- public TmidStics()
|
|
|
- {
|
|
|
- ies5 = new TmidSticsIes5();
|
|
|
- }
|
|
|
public string id { get; set; }
|
|
|
public string name { get; set; }
|
|
|
public string mobile { get; set; }
|
|
|
public string mail { get; set; }
|
|
|
- public int points { get; set; } //積分
|
|
|
- public TmidSticsIes5 ies5 { get; set; } //IES統計資料
|
|
|
+ public string country { get; set; }
|
|
|
+ public string province { get; set; }
|
|
|
+ public string city { get; set; }
|
|
|
+ public string schoolCode { get; set; }
|
|
|
+ public string schoolCodeW { get; set; }
|
|
|
+ public TmidSticsIes5 ies5 { get; set; } = new(); //IES統計資料
|
|
|
+ public TmidPoints points { get; set; } = new();
|
|
|
+ public TmidSokrates sokrates { get; set; } = new();
|
|
|
+ public List<TmidCoupon> TmidCoupons { get; set; } = new();
|
|
|
+ public List<TmidLoginTime> TmidLoginTime { get; set; } = new();
|
|
|
+
|
|
|
}
|
|
|
//TMID統計 IES5資訊
|
|
|
private class TmidSticsIes5
|
|
@@ -150,12 +234,51 @@ namespace TEAMModelBI.Controllers.BITmid
|
|
|
public long totalSize { get; set; } //總空間(Byte)
|
|
|
public long surplusSize { get; set; } //剩余的空間(Byte)
|
|
|
}
|
|
|
-
|
|
|
- public class TmidSticsPoint : TableEntity
|
|
|
+ private class TmidPoints
|
|
|
+ {
|
|
|
+ public int points { get; set; } = 0; //累積的點數(只加不減)
|
|
|
+ public int balance { get; set; } = 0; //可用的點數
|
|
|
+ public int level { get; set; } = 0; //等級
|
|
|
+ }
|
|
|
+ private class TmidCoupon
|
|
|
+ {
|
|
|
+ public string code { get; set; }
|
|
|
+ public long exchange { get; set; }
|
|
|
+ }
|
|
|
+ private class TmidLoginTime
|
|
|
{
|
|
|
- public int Get { get; set; }
|
|
|
- public string TaskNum { get; set; }
|
|
|
+ public string product { get; set; }
|
|
|
+ public long time { get; set; }
|
|
|
}
|
|
|
+ private class TmidSokrates
|
|
|
+ {
|
|
|
+ public string t_data { get; set; }
|
|
|
+ public string t_green { get; set; }
|
|
|
+ public string duration { get; set; }
|
|
|
+ public string attendance { get; set; }
|
|
|
+ public string interaction { get; set; }
|
|
|
+ public string learning_duration { get; set; }
|
|
|
+ }
|
|
|
+
|
|
|
+ private readonly Dictionary<string, string> _dicClientIds = new()
|
|
|
+ {
|
|
|
+ { "917d02f2-5b91-404e-a71d-7bdd926ddd81", "HiTeach" },
|
|
|
+ { "c5328340-b8eb-4489-8650-8c8862d7acfe", "HiTeach" },
|
|
|
+ { "118d2d4d-32a3-44c0-808a-792ca73d3706", "HiTeachCC" },
|
|
|
+ { "227082f4-8db0-4517-b281-93dba9428bc7", "HiTeachCC" },
|
|
|
+ { "371a99aa-7efd-4c3a-90a8-95b7db4f42c0", "HiTA" },
|
|
|
+ { "0ed38cde-e7fe-4fa6-9eaa-33ad404eb532", "HiTA" },
|
|
|
+ { "531fecd1-b1a5-469a-93ca-7984e1d392f2", "IES5" },
|
|
|
+ { "c7317f88-7cea-4e48-ac57-a16071f7b884", "IES5" },
|
|
|
+ { "c8de822b-3fcf-4831-adba-cdd14653bf7f", "Account" },
|
|
|
+ { "516148eb-6a38-4657-ba98-a3699061937f", "Account" },
|
|
|
+ { "d7193896-9b12-4046-ad44-c991dd48cc39", "Sokrates" },
|
|
|
+ { "59009e38-6e30-4116-814b-7605939edc47", "Sokrates" },
|
|
|
+ { "626c7285-15aa-4abe-8c0d-2c5ff1381538", "SokAPP" },
|
|
|
+ { "5bcc16a5-7d20-4cc4-b5c2-8ed0416f32b6", "SokAPP" },
|
|
|
+ { "044482b5-d024-4f23-9b55-906884243405", "IRS" },
|
|
|
+ { "5e27b7e3-b36c-4ce9-b838-e94fd0cea080", "IRS" }
|
|
|
+ };
|
|
|
}
|
|
|
|
|
|
}
|