|
@@ -18,6 +18,7 @@ using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using System.Threading.Tasks;
|
|
using TEAMModelOS.Models;
|
|
using TEAMModelOS.Models;
|
|
using TEAMModelOS.Models.Request;
|
|
using TEAMModelOS.Models.Request;
|
|
|
|
+using TEAMModelOS.SDK;
|
|
using TEAMModelOS.SDK.DI;
|
|
using TEAMModelOS.SDK.DI;
|
|
using TEAMModelOS.SDK.Extension;
|
|
using TEAMModelOS.SDK.Extension;
|
|
using TEAMModelOS.SDK.Models;
|
|
using TEAMModelOS.SDK.Models;
|
|
@@ -37,6 +38,7 @@ namespace TEAMModelOS.Controllers.Client
|
|
private readonly Option _option;
|
|
private readonly Option _option;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly IConfiguration _configuration;
|
|
private readonly SnowflakeId _snowflakeId;
|
|
private readonly SnowflakeId _snowflakeId;
|
|
|
|
+ private readonly CoreAPIHttpService _coreAPIHttpService;
|
|
|
|
|
|
public HiTeachccControlller(
|
|
public HiTeachccControlller(
|
|
AzureStorageFactory azureStorage,
|
|
AzureStorageFactory azureStorage,
|
|
@@ -46,6 +48,7 @@ namespace TEAMModelOS.Controllers.Client
|
|
DingDing dingDing,
|
|
DingDing dingDing,
|
|
IConfiguration configuration,
|
|
IConfiguration configuration,
|
|
SnowflakeId snowflakeId,
|
|
SnowflakeId snowflakeId,
|
|
|
|
+ CoreAPIHttpService coreAPIHttpService,
|
|
IOptionsSnapshot<Option> option)
|
|
IOptionsSnapshot<Option> option)
|
|
{
|
|
{
|
|
_azureStorage = azureStorage;
|
|
_azureStorage = azureStorage;
|
|
@@ -55,6 +58,7 @@ namespace TEAMModelOS.Controllers.Client
|
|
_dingDing = dingDing;
|
|
_dingDing = dingDing;
|
|
_configuration = configuration;
|
|
_configuration = configuration;
|
|
_snowflakeId = snowflakeId;
|
|
_snowflakeId = snowflakeId;
|
|
|
|
+ _coreAPIHttpService = coreAPIHttpService;
|
|
_option = option?.Value;
|
|
_option = option?.Value;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -69,7 +73,7 @@ namespace TEAMModelOS.Controllers.Client
|
|
/// </summary>
|
|
/// </summary>
|
|
/// <param name="request"></param>
|
|
/// <param name="request"></param>
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
- [HttpPost("create-lesson")]
|
|
|
|
|
|
+ [HttpPost("create-lesson")]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status200OK)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesResponseType(StatusCodes.Status400BadRequest)]
|
|
[ProducesDefaultResponseType]
|
|
[ProducesDefaultResponseType]
|
|
@@ -81,19 +85,19 @@ namespace TEAMModelOS.Controllers.Client
|
|
int client = 0; //CC每間教室Client數
|
|
int client = 0; //CC每間教室Client數
|
|
int size = 0; //學校個人總空間
|
|
int size = 0; //學校個人總空間
|
|
int tsize = 0; //學校分配給老師的總空間
|
|
int tsize = 0; //學校分配給老師的總空間
|
|
- double usize = 0; //學校個人已使用空間
|
|
|
|
- JsonElement.ArrayEnumerator members = default; //學生名單
|
|
|
|
|
|
+ double usize = 0; //學校個人已使用空間
|
|
string res = string.Empty;//資源位置加金鑰
|
|
string res = string.Empty;//資源位置加金鑰
|
|
|
|
+ string uri = string.Empty;//學校Blob位置
|
|
|
|
+ string sas = string.Empty;//學校Blob金鑰
|
|
string timezone = string.Empty;
|
|
string timezone = string.Empty;
|
|
-
|
|
|
|
|
|
+ //判斷ID Token
|
|
if (string.IsNullOrWhiteSpace(id_token)) return BadRequest();
|
|
if (string.IsNullOrWhiteSpace(id_token)) return BadRequest();
|
|
var jwt = new JwtSecurityToken(id_token);
|
|
var jwt = new JwtSecurityToken(id_token);
|
|
if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
|
|
if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
|
|
var tid = jwt.Payload.Sub;
|
|
var tid = jwt.Payload.Sub;
|
|
-
|
|
|
|
|
|
+ //初始化
|
|
var redis = _azureRedis.GetRedisClient(8);
|
|
var redis = _azureRedis.GetRedisClient(8);
|
|
var db = _azureCosmos.GetCosmosClient();
|
|
var db = _azureCosmos.GetCosmosClient();
|
|
-
|
|
|
|
var sp = request.sp.Equals("school", StringComparison.OrdinalIgnoreCase);
|
|
var sp = request.sp.Equals("school", StringComparison.OrdinalIgnoreCase);
|
|
try
|
|
try
|
|
{
|
|
{
|
|
@@ -114,10 +118,11 @@ namespace TEAMModelOS.Controllers.Client
|
|
return Ok(new { status = 1, msg = "學校沒有CC授權" });
|
|
return Ok(new { status = 1, msg = "學校沒有CC授權" });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
//取得學校資訊
|
|
//取得學校資訊
|
|
await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryStreamIterator(
|
|
await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, Constant.School).GetItemQueryStreamIterator(
|
|
- queryText: $"SELECT TOP 1 c.id, c.size, c.tsize, c.timeZone FROM c WHERE c.id = {request.school}",
|
|
|
|
- requestOptions: new() { PartitionKey = new("base") }))
|
|
|
|
|
|
+ queryText: $"SELECT TOP 1 c.id, c.size, c.tsize, c.timeZone FROM c WHERE c.id = '{request.school}'",
|
|
|
|
+ requestOptions: new() { PartitionKey = new("Base") }))
|
|
{
|
|
{
|
|
using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
@@ -127,14 +132,18 @@ namespace TEAMModelOS.Controllers.Client
|
|
size = school.GetProperty("size").GetInt32();
|
|
size = school.GetProperty("size").GetInt32();
|
|
tsize = school.GetProperty("tsize").GetInt32();
|
|
tsize = school.GetProperty("tsize").GetInt32();
|
|
}
|
|
}
|
|
|
|
+ else return BadRequest();
|
|
}
|
|
}
|
|
|
|
|
|
//緩存檢查已記錄的授權數是否已滿,未滿則紀錄ID跟時間
|
|
//緩存檢查已記錄的授權數是否已滿,未滿則紀錄ID跟時間
|
|
var cccount = await redis.HashLengthAsync($"CC:License:{request.school}");
|
|
var cccount = await redis.HashLengthAsync($"CC:License:{request.school}");
|
|
if (cccount >= dmax) return Ok(new { status = 2, msg = "學校CC授權已滿" });
|
|
if (cccount >= dmax) return Ok(new { status = 2, msg = "學校CC授權已滿" });
|
|
- else if (await redis.HashSetAsync($"CC:License:{request.school}", tid, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()))
|
|
|
|
|
|
+ else
|
|
{
|
|
{
|
|
- if (cccount == 0 && !string.IsNullOrWhiteSpace(timezone)) //代表不存在緩存,設置TTL
|
|
|
|
|
|
+ //up true 代表新字段,false 代表舊字段更新值
|
|
|
|
+ var up = await redis.HashSetAsync($"CC:License:{request.school}", tid, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
|
|
|
|
+ //代表緩存不存在Hash Key,設置TTL
|
|
|
|
+ if (cccount == 0 && !string.IsNullOrWhiteSpace(timezone))
|
|
{
|
|
{
|
|
//UTC轉換為學校時區計算到晚上24:00為止的TTL
|
|
//UTC轉換為學校時區計算到晚上24:00為止的TTL
|
|
var tz = TimeSpan.Parse(timezone.TrimStart('+'));
|
|
var tz = TimeSpan.Parse(timezone.TrimStart('+'));
|
|
@@ -144,12 +153,9 @@ namespace TEAMModelOS.Controllers.Client
|
|
await redis.KeyExpireAsync($"CC:License:{request.school}", ts);
|
|
await redis.KeyExpireAsync($"CC:License:{request.school}", ts);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- await _dingDing.SendBotMsg($"IES5,{_option.Location}, hiteachcc/create-lesson:()\n HashSetAsync CC:License:{request.school} {tid} 失敗", GroupNames.醍摩豆服務運維群組);
|
|
|
|
- }
|
|
|
|
- //如果是個人,則取出老師空間size覆蓋
|
|
|
|
- if (request.sp.Equals("private"))
|
|
|
|
|
|
+
|
|
|
|
+ //如果是個人,則取出老師空間size覆蓋,是學校拿取Blob容器金鑰
|
|
|
|
+ if (!sp)
|
|
{
|
|
{
|
|
Teacher teacher = await db.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(tid, new PartitionKey("Base"));
|
|
Teacher teacher = await db.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(tid, new PartitionKey("Base"));
|
|
size = teacher.size;
|
|
size = teacher.size;
|
|
@@ -159,11 +165,16 @@ namespace TEAMModelOS.Controllers.Client
|
|
size += st.size;
|
|
size += st.size;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ (uri, sas) = _azureStorage.GetBlobContainerSAS(request.school, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
|
|
|
|
+ }
|
|
|
|
+
|
|
//計算學校或個人的使用空間
|
|
//計算學校或個人的使用空間
|
|
RedisValue redisValue = redis.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
|
|
RedisValue redisValue = redis.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
|
|
if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
|
|
if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
|
|
{
|
|
{
|
|
- usize = Math.Round(bsize / 1073741824.0, 2, MidpointRounding.AwayFromZero) - (sp ? tsize : 0); //1073741824 1G
|
|
|
|
|
|
+ usize = Math.Round(bsize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero) ; //1073741824 1G
|
|
}
|
|
}
|
|
else //如果檢測不到緩存,觸發刷新計算空間
|
|
else //如果檢測不到緩存,觸發刷新計算空間
|
|
{
|
|
{
|
|
@@ -171,38 +182,28 @@ namespace TEAMModelOS.Controllers.Client
|
|
messageBlob.ApplicationProperties.Add("name", "BlobRoot");
|
|
messageBlob.ApplicationProperties.Add("name", "BlobRoot");
|
|
await _serviceBus.GetServiceBusClient().SendMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), messageBlob);
|
|
await _serviceBus.GetServiceBusClient().SendMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), messageBlob);
|
|
}
|
|
}
|
|
|
|
+
|
|
//取得學校或個人名單
|
|
//取得學校或個人名單
|
|
- await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, sp ? Constant.School : Constant.Teacher).GetItemQueryStreamIterator(
|
|
|
|
- queryText: $"SELECT TOP 1 c.members FROM c WHERE c.id = {request.school}",
|
|
|
|
- requestOptions: new() { PartitionKey = new(sp ? $"GroupList-{request.school}" : "GroupList") }))
|
|
|
|
- {
|
|
|
|
- using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
|
|
- if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
|
|
- {
|
|
|
|
- var root = json.RootElement.GetProperty("Documents").EnumerateArray().First();
|
|
|
|
- members = root.GetProperty("members").EnumerateArray();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ (List<RMember> students, _) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, db, _dingDing, new List<string>() { request.sid }, request.school);
|
|
|
|
+
|
|
//取得學校或個人資源
|
|
//取得學校或個人資源
|
|
if (!string.IsNullOrWhiteSpace(request.rid))
|
|
if (!string.IsNullOrWhiteSpace(request.rid))
|
|
{
|
|
{
|
|
var rp = request.rp.Equals("school", StringComparison.OrdinalIgnoreCase);
|
|
var rp = request.rp.Equals("school", StringComparison.OrdinalIgnoreCase);
|
|
await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, rp ? Constant.School : Constant.Teacher).GetItemQueryStreamIterator(
|
|
await foreach (Response item in db.GetContainer(Constant.TEAMModelOS, rp ? Constant.School : Constant.Teacher).GetItemQueryStreamIterator(
|
|
- queryText: $"SELECT TOP 1 c.url FROM c WHERE c.id = {request.school}",
|
|
|
|
- requestOptions: new() { PartitionKey = new(rp ? $"BlobLog-{request.school}" : "GroupList") }))
|
|
|
|
|
|
+ queryText: $"SELECT TOP 1 c.url FROM c WHERE c.id = '{request.rid}'",
|
|
|
|
+ requestOptions: new() { PartitionKey = new($"Bloblog-{(rp ? request.school : tid)}") }))
|
|
{
|
|
{
|
|
using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
using var json = await JsonDocument.ParseAsync(item.ContentStream);
|
|
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
|
|
{
|
|
{
|
|
var root = json.RootElement.GetProperty("Documents").EnumerateArray().First();
|
|
var root = json.RootElement.GetProperty("Documents").EnumerateArray().First();
|
|
var url = root.GetProperty("url").GetString();
|
|
var url = root.GetProperty("url").GetString();
|
|
- res = _azureStorage.GetBlobSAS($"Bloblog-{(rp ? request.school : tid)}", url, BlobSasPermissions.Read);
|
|
|
|
|
|
+ res = _azureStorage.GetBlobSAS((rp ? request.school : tid), url, BlobSasPermissions.Read);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
-
|
|
|
|
//開課記錄保存
|
|
//開課記錄保存
|
|
LessonRecord lr = new()
|
|
LessonRecord lr = new()
|
|
{
|
|
{
|
|
@@ -222,7 +223,7 @@ namespace TEAMModelOS.Controllers.Client
|
|
messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
|
|
messageChange.ApplicationProperties.Add("name", "LessonRecordEvent");
|
|
await _serviceBus.GetServiceBusClient().SendMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), messageChange);
|
|
await _serviceBus.GetServiceBusClient().SendMessageAsync(_configuration.GetValue<string>("Azure:ServiceBus:ActiveTask"), messageChange);
|
|
|
|
|
|
- return Ok(new { status = 200, lr.id, client, members, res, size, usize });
|
|
|
|
|
|
+ return Ok(new { status = 200, lr.id, client, students, res, size, usize, uri, sas });
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
catch (Exception ex)
|
|
{
|
|
{
|