|
@@ -845,5 +845,424 @@ namespace TEAMModelOS.Controllers
|
|
}
|
|
}
|
|
return Ok(new { paths ,status=1});
|
|
return Ok(new { paths ,status=1});
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ [ProducesDefaultResponseType]
|
|
|
|
+ [Authorize(Roles = "IES")]
|
|
|
|
+ [AuthToken(Roles = "teacher,admin")]
|
|
|
|
+ [HttpPost("delete-unlink")]
|
|
|
|
+ public async Task<IActionResult> DeleteUnlink(JsonElement json) {
|
|
|
|
+ var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
|
|
|
|
+ int status = 0;
|
|
|
|
+ if (!json.TryGetProperty("scope", out JsonElement scope))
|
|
|
|
+ {
|
|
|
|
+ return Ok(new { status, msg = "参数错误" });
|
|
|
|
+ }
|
|
|
|
+ string containerName = scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase) ? school : userid;
|
|
|
|
+ bool exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:ScanResult:{scope}:{containerName}");
|
|
|
|
+ if (exists)
|
|
|
|
+ {
|
|
|
|
+ return Ok(new { status = 2, msg = "暂无清理项!" });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return Ok(new { status, msg = "暂无清理项!" });
|
|
|
|
+ }
|
|
|
|
+ [ProducesDefaultResponseType]
|
|
|
|
+ [Authorize(Roles = "IES")]
|
|
|
|
+ [AuthToken(Roles = "teacher,admin")]
|
|
|
|
+ [HttpPost("scan-unlink")]
|
|
|
|
+ public async Task<IActionResult> ScanUnlink(JsonElement json)
|
|
|
|
+ {
|
|
|
|
+ var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
|
|
|
|
+ int status = 0;
|
|
|
|
+ if ( !json.TryGetProperty("scope", out JsonElement scope))
|
|
|
|
+ {
|
|
|
|
+ return Ok(new { status, msg = "参数错误" });
|
|
|
|
+ }
|
|
|
|
+ string containerName = scope.ToString().Equals("school", StringComparison.OrdinalIgnoreCase) ? school : userid;
|
|
|
|
+ bool exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:ScanResult:{scope}:{containerName}");
|
|
|
|
+ if (exists)
|
|
|
|
+ {
|
|
|
|
+ var result = await _azureRedis.GetRedisClient(8).StringGetAsync($"Blob:ScanResult:{scope}:{containerName}");
|
|
|
|
+ if (result.HasValue)
|
|
|
|
+ {
|
|
|
|
+ List<UnLink> unLinksData = result.ToString().ToObject<List<UnLink>>();
|
|
|
|
+ if (unLinksData.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ var groupData = unLinksData.GroupBy(x => x.prefix).ToList();
|
|
|
|
+ List<dynamic> summaryData = new List<dynamic>();
|
|
|
|
+ long totalCountData = 0;
|
|
|
|
+ long? totalSizeData = 0;
|
|
|
|
+ groupData.ForEach(x =>
|
|
|
|
+ {
|
|
|
|
+ long count = x.ToList().SelectMany(z => z.blobs).Count();
|
|
|
|
+ long? size = x.Select(y => y.size).Sum();
|
|
|
|
+ totalSizeData += size;
|
|
|
|
+ totalCountData += count;
|
|
|
|
+ summaryData.Add(new { prefix = x.Key, count = count, size = size });
|
|
|
|
+ });
|
|
|
|
+ //为节省服务器开销, 限制只能一天清理一次
|
|
|
|
+
|
|
|
|
+ return Ok(new { status = 1, totalCount = totalCountData, totalSize = totalSizeData, summary = summaryData, unLinks = unLinksData });
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return Ok(new { status = 2, msg = "最近清理过,暂无清理项!" });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return Ok(new { status = 2, msg = "最近清理过,暂无清理项!" });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ List<UnLink> unLinks = new List<UnLink>();
|
|
|
|
+ //文件名(关联路径)导向的文件夹 内容(audio doc image video other thum 缩略图) 学生头像(avatar)
|
|
|
|
+ string[] prefixFile = new string[] { "audio", "doc", "image", "video", "other", "thum", "avatar" };
|
|
|
|
+ foreach (string prefix in prefixFile)
|
|
|
|
+ {
|
|
|
|
+ string tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher;
|
|
|
|
+ switch (true)
|
|
|
|
+ {
|
|
|
|
+ //Bloblog
|
|
|
|
+
|
|
|
|
+ case bool when prefix.Equals("doc", StringComparison.OrdinalIgnoreCase)
|
|
|
|
+ || prefix.Equals("image", StringComparison.OrdinalIgnoreCase)
|
|
|
|
+ || prefix.Equals("video", StringComparison.OrdinalIgnoreCase)
|
|
|
|
+ || prefix.Equals("audio", StringComparison.OrdinalIgnoreCase)
|
|
|
|
+ || prefix.Equals("other", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ // audio/最愛情歌80-89-這些日子以來 (張清芳+范怡文).mp3
|
|
|
|
+ List<KeyValuePair<string, long?>> blobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ blobs.Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ if (blobs.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ string code = $"Bloblog-{containerName}";
|
|
|
|
+ string sql = $"select value c from c where c.url in ({string.Join(",", blobs.Select(z => $"'{z.Key}'"))})";
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<Bloblog>(sql, code);
|
|
|
|
+ if (result.list.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ var urls = result.list.Select(x => x.url).ToHashSet();
|
|
|
|
+ var unlink = blobs.ExceptBy(urls, x => x.Key).ToList();
|
|
|
|
+ long? size = unlink.Select(z => z.Value).Sum();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlink, size = size });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("avatar", StringComparison.OrdinalIgnoreCase) && scope.ToString().Equals("school"):
|
|
|
|
+ {
|
|
|
|
+ List<KeyValuePair<string, long?>> blobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ blobs.Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ if (blobs.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ string code = $"Base-{containerName}";
|
|
|
|
+ List<KeyValuePair<string, long?>> unlink = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ foreach (var blob in blobs)
|
|
|
|
+ {
|
|
|
|
+ string sql = $"select value c from c where contains(c.picture,'{blob.Key}')";
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Student").GetList<Student>(sql, code, pageSize: 1);
|
|
|
|
+ //找不到对应的数据存储
|
|
|
|
+ if (!result.list.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ unlink.Add(blob);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ long? size = unlink.Select(z => z.Value).Sum();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlink, size = size });
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ default: break;
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //文件夹(关联id)导向的文件夹 exam homework art records survey vote item
|
|
|
|
+ string[] prefixDirId = new string[] { "exam", "homework", "art", "records", "survey", "vote", "item" };
|
|
|
|
+ foreach (string prefix in prefixDirId)
|
|
|
|
+ {
|
|
|
|
+ string tbname = string.Empty;
|
|
|
|
+ HashSet<string> ids = new HashSet<string>();
|
|
|
|
+ Dictionary<string, List<KeyValuePair<string, long?>>> recordUrls = new Dictionary<string, List<KeyValuePair<string, long?>>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ var path = blobItem.Name.Split("/");
|
|
|
|
+ if (path.Length > 2)
|
|
|
|
+ {
|
|
|
|
+ string id = path[1];
|
|
|
|
+ ids.Add(id);
|
|
|
|
+ if (recordUrls.ContainsKey(id))
|
|
|
|
+ {
|
|
|
|
+ recordUrls[id].Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ recordUrls[id] = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (path.Length == 2)
|
|
|
|
+ {
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) }, size = blobItem.Properties.ContentLength });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ string code = string.Empty;
|
|
|
|
+ if (ids.Any() && ids.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ string sql = $"select value c.id from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
|
|
|
|
+ switch (true)
|
|
|
|
+ {
|
|
|
|
+ case bool when prefix.Equals("exam", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = Constant.Common;
|
|
|
|
+ code = $"Exam-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("homework", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = Constant.Common;
|
|
|
|
+ code = $"Homework-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("art", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = Constant.Common;
|
|
|
|
+ code = $"Art-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("survey", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = Constant.Common;
|
|
|
|
+ code = $"Survey-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("vote", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = Constant.Common;
|
|
|
|
+ code = $"Vote-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("item", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher;
|
|
|
|
+ code = $"Item-{containerName}";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ case bool when prefix.Equals("records", StringComparison.OrdinalIgnoreCase):
|
|
|
|
+ {
|
|
|
|
+ tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher;
|
|
|
|
+ code = scope.ToString().Equals("school") ? $"LessonRecord-{containerName}" : "LessonRecord";
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ IEnumerable<string> unlink = null;
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<string>(sql, code);
|
|
|
|
+ if (result != null && result.list.Any())
|
|
|
|
+ {
|
|
|
|
+ unlink = ids.Except(result.list);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ unlink = ids;
|
|
|
|
+ }
|
|
|
|
+ var unlinkData = recordUrls.Where(x => unlink.Contains(x.Key));
|
|
|
|
+ var unlinkPaths = unlinkData.SelectMany(z => z.Value).ToList();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlinkPaths, size = unlinkPaths.Select(z => z.Value).Sum() });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //名字导向 试卷(paper)
|
|
|
|
+ {
|
|
|
|
+ string prefix = "paper";
|
|
|
|
+ //List<KeyValuePair<string, long?>> blobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ HashSet<string> paperNames = new HashSet<string>();
|
|
|
|
+ Dictionary<string, List<KeyValuePair<string, long?>>> recordUrls = new Dictionary<string, List<KeyValuePair<string, long?>>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ var path = blobItem.Name.Split("/");
|
|
|
|
+ if (path.Length > 2)
|
|
|
|
+ {
|
|
|
|
+ string paperName = path[1];
|
|
|
|
+ paperNames.Add(paperName);
|
|
|
|
+ if (recordUrls.ContainsKey(paperName))
|
|
|
|
+ {
|
|
|
|
+ recordUrls[paperName].Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ recordUrls[paperName] = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (path.Length == 2)
|
|
|
|
+ {
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) }, size = blobItem.Properties.ContentLength });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ string tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher;
|
|
|
|
+ string code = $"Paper-{containerName}";
|
|
|
|
+ if (paperNames.Any() && paperNames.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ IEnumerable<string> unlink = null;
|
|
|
|
+ string sql = $"select value c.name from c where c.name in ({string.Join(",", paperNames.Select(x => $"'{x}'"))})";
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<string>(sql, code);
|
|
|
|
+ if (result != null && result.list.Any())
|
|
|
|
+ {
|
|
|
|
+ unlink = paperNames.Except(result.list);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ unlink = paperNames;
|
|
|
|
+ }
|
|
|
|
+ var unlinkData = recordUrls.Where(x => unlink.Contains(x.Key));
|
|
|
|
+ var unlinkPaths = unlinkData.SelectMany(z => z.Value).ToList();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlinkPaths, size = unlinkPaths.Select(z => z.Value).Sum() });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //htex hte (res)
|
|
|
|
+ {
|
|
|
|
+ string prefix = "res";
|
|
|
|
+
|
|
|
|
+ //List<KeyValuePair<string, long?>> blobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ HashSet<string> htexNames = new HashSet<string>();
|
|
|
|
+ List<KeyValuePair<string, long?>> hteBlobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ Dictionary<string, List<KeyValuePair<string, long?>>> recordUrls = new Dictionary<string, List<KeyValuePair<string, long?>>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ var path = blobItem.Name.Split("/");
|
|
|
|
+ if (path.Length > 2)
|
|
|
|
+ {
|
|
|
|
+ string htexName = path[1];
|
|
|
|
+ htexNames.Add(htexName);
|
|
|
|
+ if (recordUrls.ContainsKey(htexName))
|
|
|
|
+ {
|
|
|
|
+ recordUrls[htexName].Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ recordUrls[htexName] = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (path.Length == 2)
|
|
|
|
+ {
|
|
|
|
+ string blobName = "";
|
|
|
|
+ if (blobItem.Name.EndsWith(".htex", StringComparison.OrdinalIgnoreCase))
|
|
|
|
+ {
|
|
|
|
+ blobName = blobItem.Name.Substring(0, blobItem.Name.Length - 5);
|
|
|
|
+ }
|
|
|
|
+ if (blobItem.Name.EndsWith(".hte", StringComparison.OrdinalIgnoreCase))
|
|
|
|
+ {
|
|
|
|
+ blobName = blobItem.Name.Substring(0, blobItem.Name.Length - 4);
|
|
|
|
+ }
|
|
|
|
+ if (!string.IsNullOrWhiteSpace(blobName))
|
|
|
|
+ {
|
|
|
|
+ hteBlobs.Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //unLinks.Add(new UnLink { prefix = prefix, blobs = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) }, size = blobItem.Properties.ContentLength });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ string tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher;
|
|
|
|
+ string code = $"Bloblog-{containerName}";
|
|
|
|
+ if (htexNames.Any() && htexNames.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ List<string> unlink = new List<string>();
|
|
|
|
+ foreach (var htexName in htexNames)
|
|
|
|
+ {
|
|
|
|
+
|
|
|
|
+ string sql = $"select value c from c where contains(c.url,'{htexName}') ";
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<Bloblog>(sql, code, pageSize: 1);
|
|
|
|
+ //找不到对应的数据存储
|
|
|
|
+ if (!result.list.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ unlink.Add(htexName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var unlinkData = recordUrls.Where(x => unlink.Contains(x.Key));
|
|
|
|
+ var unlinkPaths = unlinkData.SelectMany(z => z.Value).ToList();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlinkPaths, size = unlinkPaths.Select(z => z.Value).Sum() });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (hteBlobs.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ List<KeyValuePair<string, long?>> unlink = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ foreach (var hteName in hteBlobs)
|
|
|
|
+ {
|
|
|
|
+ string sql = $"select value c from c where contains(c.url,'{hteName}') ";
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<Bloblog>(sql, code, pageSize: 1);
|
|
|
|
+ //找不到对应的数据存储
|
|
|
|
+ if (!result.list.IsNotEmpty())
|
|
|
|
+ {
|
|
|
|
+ unlink.Add(hteName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ long? size = unlink.Select(z => z.Value).Sum();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlink, size = size });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 课纲(syllabus) 节点id fc4b7ac5-24e7-4eba-b0f2-7eccd007b4cd
|
|
|
|
+ {
|
|
|
|
+ string prefix = "syllabus";
|
|
|
|
+ //List<KeyValuePair<string, long?>> blobs = new List<KeyValuePair<string, long?>>();
|
|
|
|
+ HashSet<string> rnodeIds = new HashSet<string>();
|
|
|
|
+ Dictionary<string, List<KeyValuePair<string, long?>>> recordUrls = new Dictionary<string, List<KeyValuePair<string, long?>>>();
|
|
|
|
+ await foreach (BlobItem blobItem in _azureStorage.GetBlobContainerClient(containerName.ToString()).GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: prefix))
|
|
|
|
+ {
|
|
|
|
+ var path = blobItem.Name.Split("/");
|
|
|
|
+ if (path.Length > 2)
|
|
|
|
+ {
|
|
|
|
+ string rnodeId = path[1];
|
|
|
|
+ rnodeIds.Add(rnodeId);
|
|
|
|
+ if (recordUrls.ContainsKey(rnodeId))
|
|
|
|
+ {
|
|
|
|
+ recordUrls[rnodeId].Add(new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength));
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ recordUrls[rnodeId] = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) };
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (path.Length == 2)
|
|
|
|
+ {
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = new List<KeyValuePair<string, long?>> { new KeyValuePair<string, long?>(blobItem.Name, blobItem.Properties.ContentLength) }, size = blobItem.Properties.ContentLength });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (rnodeIds.Any() && rnodeIds.Count > 0)
|
|
|
|
+ {
|
|
|
|
+ string code = $"Syllabus-{containerName}";
|
|
|
|
+ string tbname = scope.ToString().Equals("school") ? Constant.School : Constant.Teacher; ;
|
|
|
|
+ string sql = $"select distinct value b.id from c join b in c.children where c.pk='Syllabus' and b.id in ({string.Join(",", rnodeIds.Select(x => $"'{x}'"))})";
|
|
|
|
+ IEnumerable<string> unlink = null;
|
|
|
|
+ var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).GetList<string>(sql, code);
|
|
|
|
+ if (result != null && result.list.Any())
|
|
|
|
+ {
|
|
|
|
+ unlink = rnodeIds.Except(result.list);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ unlink = rnodeIds;
|
|
|
|
+ }
|
|
|
|
+ var unlinkData = recordUrls.Where(x => unlink.Contains(x.Key));
|
|
|
|
+ var unlinkPaths = unlinkData.SelectMany(z => z.Value).ToList();
|
|
|
|
+ unLinks.Add(new UnLink { prefix = prefix, blobs = unlinkPaths, size = unlinkPaths.Select(z => z.Value).Sum() });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var group = unLinks.GroupBy(x => x.prefix).ToList();
|
|
|
|
+ List<dynamic> summary = new List<dynamic>();
|
|
|
|
+ long totalCount = 0;
|
|
|
|
+ long? totalSize = 0;
|
|
|
|
+ group.ForEach(x => {
|
|
|
|
+ long count = x.ToList().SelectMany(z => z.blobs).Count();
|
|
|
|
+ long? size = x.Select(y => y.size).Sum();
|
|
|
|
+ totalSize += size;
|
|
|
|
+ totalCount += count;
|
|
|
|
+ summary.Add(new { prefix = x.Key, count = count, size = size });
|
|
|
|
+ });
|
|
|
|
+ //为节省服务器开销, 限制只能一天清理一次
|
|
|
|
+ _azureRedis.GetRedisClient(8).StringSet($"Blob:ScanResult:{scope}:{containerName}", unLinks.ToJsonString(), expiry: new TimeSpan(24, 0, 0));
|
|
|
|
+ return Ok(new { status = 1, totalCount, totalSize, summary, unLinks });
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|