CrazyIter_Bin 2 gadi atpakaļ
vecāks
revīzija
5c86a956c2

+ 2 - 20
TEAMModelOS.FunctionV4/ServiceBus/ActiveTaskTopic.cs

@@ -1638,28 +1638,10 @@ namespace TEAMModelOS.FunctionV4.ServiceBus
                                     if (scope.Equals("private"))
                                     if (scope.Equals("private"))
                                     {
                                     {
                                         int lessonLimit = teacher.lessonLimit;
                                         int lessonLimit = teacher.lessonLimit;
-                                        //获取已经使用的空间大小
-                                        long blobsize = 0;
-                                        var value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", tmdid);
-                                        if (value != default && !value.IsNullOrEmpty)
-                                        {
-                                            JsonElement record = value.ToString().ToObject<JsonElement>();
-                                            if (record.TryGetInt64(out blobsize))
-                                            {
-                                            }
-                                        }
-                                        int blobTotal = teacher.size;
-                                        blobTotal = teacher.size;
-                                        //累加学校分配的空间
-                                        foreach (var schoolInfo in teacher.schools)
-                                        {
-                                            SchoolTeacher st = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<SchoolTeacher>(lessonRecord.tmdid, new PartitionKey($"Teacher-{schoolInfo.schoolId}"));
-                                            blobTotal += st.size;
-                                        }
-
+                                        var space= await BlobService.GetSurplusSpace(tmdid, scope, _option, _azureCosmos, _azureRedis, _azureStorage, _dingDing);
                                         //20230208调整之前  if (blobTotal * 1073741824 - blobsize > 2147483648)  //剩余空间大于2G 
                                         //20230208调整之前  if (blobTotal * 1073741824 - blobsize > 2147483648)  //剩余空间大于2G 
                                         //剩余空间不足,则开启自动清理机制
                                         //剩余空间不足,则开启自动清理机制
-                                        if (blobTotal * 1073741824 - blobsize > 0)
+                                        if (space .surplus> 0)
                                         {
                                         {
                                             //大于0则表示空间充足
                                             //大于0则表示空间充足
                                             lessonLimit = -1;
                                             lessonLimit = -1;

+ 1 - 1
TEAMModelOS.SDK/DI/CoreAPI/CoreAPIHttpService.cs

@@ -387,7 +387,7 @@ namespace TEAMModelOS.SDK
                                 result = $"{responseMessage.StatusCode},推送返回的状态码。";
                                 result = $"{responseMessage.StatusCode},推送返回的状态码。";
 
 
                             }
                             }
-                            //  _dingDing.SendBotMsg($"{location}站点发送消息:\n{url}/service/PushNotify \nheader:  {token.AccessToken} \nresult:{result}\n params:{notifyData.ToJsonString()}", GroupNames.成都开发測試群組).GetAwaiter().GetResult();
+                            // _dingDing.SendBotMsg($"{location}站点发送消息:\n{url}/service/PushNotify \nheader:  {token.AccessToken} \nresult:{result}\n params:{notifyData.ToJsonString()}", GroupNames.成都开发測試群組).GetAwaiter().GetResult();
                            
                            
                         }
                         }
                     }
                     }

+ 130 - 53
TEAMModelOS.SDK/Models/Service/Common/BlobService.cs

@@ -12,8 +12,10 @@ using System.Linq;
 using System.Text;
 using System.Text;
 using System.Text.Json;
 using System.Text.Json;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using TEAMModelOS.Models;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.DI;
 using TEAMModelOS.SDK.Extension;
 using TEAMModelOS.SDK.Extension;
+using TEAMModelOS.SDK.Models;
 
 
 namespace TEAMModelOS.SDK.Services
 namespace TEAMModelOS.SDK.Services
 {
 {
@@ -40,84 +42,159 @@ namespace TEAMModelOS.SDK.Services
                 //如果已经存在,则忽略,不加入队列。
                 //如果已经存在,则忽略,不加入队列。
             }
             }
         }
         }
-        
-        public static async Task<UsedBlob> GetBlobUsed(CosmosClient clientc, BlobContainerClient clients, IDatabase clientr, string scope, string containerName)
+        /// <summary>
+        /// 获取学校或者个人的剩余空间
+        /// </summary>
+        /// <param name="name">学校id 或者醍摩豆id</param>
+        /// <param name="scope"></param>
+        /// <param name="_azureCosmos"></param>
+        /// <param name="_azureRedis"></param>
+        public static async Task<(long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog)> GetSurplusSpace(string name, string scope,Option _option, AzureCosmosFactory _azureCosmos, AzureRedisFactory _azureRedis, AzureStorageFactory _azureStorage,DingDing _dingDing )
         {
         {
-            UsedBlob result = new UsedBlob();
+            //已经存储的空间
+            long usedSize = 0;
+            //分配给教师的
+            long teach = 0;
+            //总空间
+            long total = 0;
+            // 剩余的
+            long surplus = 0;
+            Dictionary<string, double?> catalog = new Dictionary<string, double?>();
             try
             try
             {
             {
-                //学校已经分配给所有教师的空间大小GB。
-                long teach = 0;
-                if (scope.Equals("school"))
+                if (!string.IsNullOrWhiteSpace(name))
                 {
                 {
-                    await foreach (var item in clientc.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{containerName}") }))
+
+                    if ("school".Equals(scope, StringComparison.OrdinalIgnoreCase))
+                    {
+
+                        School school = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(name, new PartitionKey("Base"));
+                        total = school.size;
+                        teach = school.tsize;
+                        //用tsize代替
+                        //await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ",
+                        //    requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{name}") }))
+                        //{
+                        //    var json = await JsonDocument.ParseAsync(item.ContentStream);
+                        //    foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        //    {
+                        //        if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
+                        //        {
+                        //            teach = _size.GetInt32();
+                        //            break;
+                        //        }
+                        //    }
+                        //}
+                    }
+                    else
                     {
                     {
-                        var json = await JsonDocument.ParseAsync(item.ContentStream);
-                        foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
+                        Teacher teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>(name, new PartitionKey("Base"));
+                        total = teacher.size;
+                        foreach (var school in teacher.schools)
                         {
                         {
-                            if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
+                            try
                             {
                             {
-                                teach = _size.GetInt32();
-                                break;
+                                SchoolTeacher schoolTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<SchoolTeacher>(name, new PartitionKey($"Teacher-{school.schoolId}"));
+                                total += schoolTeacher.size;
                             }
                             }
+                            catch (Exception ex) { }
                         }
                         }
                     }
                     }
-                }
-                //使用blob狀況
-                bool getBlobCatalogFromBlob = false; //是否直接去blob取得使用狀況 false:否(Redis)  true:是(Blob)
-                long blobsize = 0;
-                RedisValue value = default;
-                value = clientr.HashGet($"Blob:Record", containerName);
-                if (value != default && !value.IsNullOrEmpty)
-                {
-                    JsonElement record = value.ToString().ToObject<JsonElement>();
-                    if (record.TryGetInt64(out blobsize))
+                    long blobsize = 0;
+                    RedisValue value = default;
+                    value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", name);
+                    if (value != default && !value.IsNullOrEmpty)
                     {
                     {
+                        JsonElement record = value.ToString().ToObject<JsonElement>();
+                        if (record.TryGetInt64(out blobsize))
+                        {
+                        }
                     }
                     }
                     else
                     else
                     {
                     {
-                        getBlobCatalogFromBlob = true;
+                        var client = _azureStorage.GetBlobContainerClient(name);
+                        var size = await client.GetBlobsCatalogSize();
+                        if (size.Item1 > 0)
+                        {
+                            await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", name, size.Item1);
+                        }
+
+                        foreach (var key in size.Item2.Keys)
+                        {
+                            await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", key);
+                            await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
+                        }
+                        usedSize = size.Item1.Value;
+                        //1024 * 1024 * 1024=1073741824  =1G
+                        surplus = (total - teach) * 1073741824 - usedSize;
+                        catalog=size.Item2;
+                        //return (usedSize, teach, total, surplus, catalog = size.Item2);
                     }
                     }
-                }
-                else
-                {
-                    getBlobCatalogFromBlob = true;
-                }
-                Dictionary<string, double?> catalog = new Dictionary<string, double?>();
-                SortedSetEntry[] Scores = clientr.SortedSetRangeByScoreWithScores($"Blob:Catalog:{containerName}");
-                if (Scores != null)
-                {
-                    foreach (var score in Scores)
+
+                    SortedSetEntry[] Scores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Blob:Catalog:{name}");
+                    if (Scores != null)
+                    {
+                        foreach (var score in Scores)
+                        {
+                            double val = score.Score;
+                            string key = score.Element.ToString();
+                            catalog.Add(key, val);
+                        }
+                        usedSize = blobsize;
+                        //1024 * 1024 * 1024=1073741824  =1G
+                        surplus = (total - teach) * 1073741824 - usedSize;
+                        //return (usedSize, teach, total, surplus, catalog);
+                    }
+                    else
                     {
                     {
-                        double val = score.Score;
-                        string key = score.Element.ToString();
-                        catalog.Add(key, val);
+                        //没有缓存
+                        var client = _azureStorage.GetBlobContainerClient(name);
+                        var size = await client.GetBlobsCatalogSize();
+                        if (size.Item1 > 0)
+                        {
+                            await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", name, size.Item1);
+                        }
+                        foreach (var key in size.Item2.Keys)
+                        {
+                            await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", key);
+                            await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
+                        }
+                        usedSize = size.Item1.Value;
+                        //1024 * 1024 * 1024=1073741824  =1G
+                        //surplus 可能为负数
+                        surplus = (total - teach) * 1073741824 - usedSize;
+                        catalog = size.Item2;
+                        //return (usedSize, teach, total, surplus, catalog = size.Item2);
                     }
                     }
                 }
                 }
-                if (!getBlobCatalogFromBlob)
+            }
+            catch (Exception ex)
+            {
+                await _dingDing.SendBotMsg($"IES5,{_option.Location},blob/used-space()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
+                return (usedSize, teach, total, surplus, catalog);
+            }
+            if (usedSize > 0 && total > 0) {
+                double percent= surplus / total * 1073741824 *100;
+                int  tag =11;
+                if (percent <= 10 && percent > 5)
                 {
                 {
-                    result.size = blobsize;
-                    result.catalog = catalog;
-                    result.teach = teach;
-                    return result;
+                    tag = 10;
                 }
                 }
-                else
+                else if (percent <= 5 && percent > 0)
                 {
                 {
-                    var size = await clients.GetBlobsCatalogSize();
-                    result.size = size.Item1;
-                    result.catalog = size.Item2;
-                    result.teach = teach;
-                    return result;
+                    tag = 5;
                 }
                 }
+                else if (percent <= 0)
+                {
+                    tag = 0;
+                }//如果已经扩容请忽略此通知!
+                //if()
             }
             }
-            catch (Exception ex)
-            {
-                //await _dingDing.SendBotMsg($"CoreAPI2,{_option.Location},Channel/Create()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-                return result;
-            }
+            return (usedSize, teach, total, surplus, catalog);
         }
         }
 
 
+        public class BlobSpace{ }
+
         /// <param name="scope">school or private</param>
         /// <param name="scope">school or private</param>
         /// <param name="containerName">school code or tmid</param>
         /// <param name="containerName">school code or tmid</param>
         /// <param name="type">doc, res, item... Empty if no need.</param>
         /// <param name="type">doc, res, item... Empty if no need.</param>

+ 7 - 4
TEAMModelOS/Controllers/Client/HiTAControlller.cs

@@ -256,7 +256,9 @@ namespace TEAMModelOS.Controllers.Client
                             string schoolCodeNow = $"{obj.GetProperty("schoolId")}";
                             string schoolCodeNow = $"{obj.GetProperty("schoolId")}";
                             var clientss = _azureStorage.GetBlobContainerClient(schoolCodeNow);
                             var clientss = _azureStorage.GetBlobContainerClient(schoolCodeNow);
                             //Blob使用狀況
                             //Blob使用狀況
-                            UsedBlob schoolUsedBlob = await BlobService.GetBlobUsed(clientc, clientss, clientr, "school", schoolCodeNow);
+                            //UsedBlob schoolUsedBlob = await BlobService.GetBlobUsed(clientc, clientss, clientr, "school", schoolCodeNow);
+                            (long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog) schoolUsedBlob = await BlobService.GetSurplusSpace(schoolCodeNow, "school", _option, _azureCosmos, _azureRedis, _azureStorage, _dingDing);
+
                             //管理者名單
                             //管理者名單
                             List<Dictionary<string, string>> adminList = new List<Dictionary<string, string>>();
                             List<Dictionary<string, string>> adminList = new List<Dictionary<string, string>>();
                             string querySchool = $"SELECT c.id, c.name FROM c WHERE ARRAY_CONTAINS(c.roles, 'admin', true)";
                             string querySchool = $"SELECT c.id, c.name FROM c WHERE ARRAY_CONTAINS(c.roles, 'admin', true)";
@@ -308,7 +310,7 @@ namespace TEAMModelOS.Controllers.Client
                             schoolExtobj.status = obj.GetProperty("status");
                             schoolExtobj.status = obj.GetProperty("status");
                             schoolExtobj.picture = school.RootElement.GetProperty("picture");
                             schoolExtobj.picture = school.RootElement.GetProperty("picture");
                             schoolExtobj.size = new ExpandoObject();
                             schoolExtobj.size = new ExpandoObject();
-                            schoolExtobj.size.used = schoolUsedBlob.size + schoolUsedBlob.teach * 1073741824;
+                            schoolExtobj.size.used = schoolUsedBlob.usedSize + schoolUsedBlob.teach * 1073741824;
                             long ssize = (school.RootElement.TryGetProperty("size", out JsonElement ssizeJson)) ? ssizeJson.GetInt32() : 0;
                             long ssize = (school.RootElement.TryGetProperty("size", out JsonElement ssizeJson)) ? ssizeJson.GetInt32() : 0;
                             schoolExtobj.size.total = ssize * 1073741824;
                             schoolExtobj.size.total = ssize * 1073741824;
                             schoolExtobj.size.avaliable = schoolExtobj.size.total - schoolExtobj.size.used;
                             schoolExtobj.size.avaliable = schoolExtobj.size.total - schoolExtobj.size.used;
@@ -377,8 +379,9 @@ namespace TEAMModelOS.Controllers.Client
                     size.total = Convert.ToInt64(size.total) * 1073741824;
                     size.total = Convert.ToInt64(size.total) * 1073741824;
 
 
                     ////個人空間使用狀況
                     ////個人空間使用狀況
-                    UsedBlob teacherUsedBlob = await BlobService.GetBlobUsed(clientc, clientst, clientr, "private", id);
-                    size.used = teacherUsedBlob.size;
+                    (long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog) teacherUsedBlob = await BlobService.GetSurplusSpace(id, "private", _option, _azureCosmos, _azureRedis, _azureStorage, _dingDing);
+                   // UsedBlob teacherUsedBlob = await BlobService.GetBlobUsed(clientc, clientst, clientr, "private", id);
+                    size.used = teacherUsedBlob.usedSize;
                     foreach (KeyValuePair<string, double?> blobCatalog in teacherUsedBlob.catalog)
                     foreach (KeyValuePair<string, double?> blobCatalog in teacherUsedBlob.catalog)
                     {
                     {
                         if (blobCatalog.Key.Equals("records"))
                         if (blobCatalog.Key.Equals("records"))

+ 4 - 4
TEAMModelOS/Controllers/Client/HiTeachController.cs

@@ -205,12 +205,12 @@ namespace TEAMModelOS.Controllers.Client
                         size += st.size;
                         size += st.size;
                     }
                     }
                 }
                 }
-
+                (long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog) space = await BlobService.GetSurplusSpace($"{(sp ? request.school : tid)}", request.sp, _option, _azureCosmos, _azureRedis, _azureStorage, _dingDing);
                 //計算學校或個人的使用空間
                 //計算學校或個人的使用空間
-                RedisValue redisValue = r8.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
-                if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
+                //  RedisValue redisValue = r8.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
+                if (space.usedSize>0)
                 {
                 {
-                    usize = Math.Round(bsize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero); //1073741824  1G
+                    usize = Math.Round(space.usedSize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero); //1073741824  1G
                 }
                 }
                 else //如果檢測不到緩存,觸發刷新計算空間
                 else //如果檢測不到緩存,觸發刷新計算空間
                 {
                 {

+ 4 - 4
TEAMModelOS/Controllers/Client/HiTeachccControlller.cs

@@ -174,12 +174,12 @@ namespace TEAMModelOS.Controllers.Client
                 {
                 {
                     (uri, sas) = _azureStorage.GetBlobContainerSAS(request.school, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
                     (uri, sas) = _azureStorage.GetBlobContainerSAS(request.school, BlobContainerSasPermissions.Write | BlobContainerSasPermissions.Read | BlobContainerSasPermissions.List);
                 }
                 }
-
+                (long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog) space = await BlobService.GetSurplusSpace($"{(sp ? request.school : tid)}", request.sp, _option, _azureCosmos, _azureRedis, _azureStorage, _dingDing);
                 //計算學校或個人的使用空間
                 //計算學校或個人的使用空間
-                RedisValue redisValue = r8.HashGet($"Blob:Record", $"{(sp ? request.school : tid)}");
-                if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
+                
+                if (space.usedSize>0)
                 {
                 {
-                    usize = Math.Round(bsize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero); //1073741824  1G
+                    usize = Math.Round(space.usedSize / 1073741824.0 - (sp ? tsize : 0), 2, MidpointRounding.AwayFromZero); //1073741824  1G
                 }
                 }
                 else //如果檢測不到緩存,觸發刷新計算空間
                 else //如果檢測不到緩存,觸發刷新計算空間
                 {
                 {

+ 11 - 97
TEAMModelOS/Controllers/System/BlobController.cs

@@ -57,7 +57,7 @@ namespace TEAMModelOS.Controllers
             _clientFactory = clientFactory;
             _clientFactory = clientFactory;
             _serviceBus = serviceBus;
             _serviceBus = serviceBus;
             _azureRedis = azureRedis;
             _azureRedis = azureRedis;
-            _configuration = configuration; 
+            _configuration = configuration;
             _dingDing = dingDing;
             _dingDing = dingDing;
             _option = option?.Value;
             _option = option?.Value;
             _azureCosmos = azureCosmos;
             _azureCosmos = azureCosmos;
@@ -160,7 +160,7 @@ namespace TEAMModelOS.Controllers
             }
             }
             else
             else
             {
             {
-                return Ok(new BlobAuth { url=$"{azureBlobSAS}",sas="",name = $"{azureBlobSAS}" });
+                return Ok(new BlobAuth { url = $"{azureBlobSAS}", sas = "", name = $"{azureBlobSAS}" });
             };
             };
         }
         }
 
 
@@ -198,7 +198,7 @@ namespace TEAMModelOS.Controllers
         [Authorize(Roles = "IES")]
         [Authorize(Roles = "IES")]
         public async Task<IActionResult> GetText(JsonElement request)
         public async Task<IActionResult> GetText(JsonElement request)
         {
         {
-            request.TryGetProperty("code", out JsonElement code); 
+            request.TryGetProperty("code", out JsonElement code);
             string azureBlobSAS = System.Web.HttpUtility.UrlDecode(code.ToString(), Encoding.UTF8);
             string azureBlobSAS = System.Web.HttpUtility.UrlDecode(code.ToString(), Encoding.UTF8);
             (string, string) a = BlobUrlString(azureBlobSAS);
             (string, string) a = BlobUrlString(azureBlobSAS);
             string ContainerName = a.Item1;
             string ContainerName = a.Item1;
@@ -207,11 +207,11 @@ namespace TEAMModelOS.Controllers
             if (flg)
             if (flg)
             {
             {
                 //TODO 需驗證
                 //TODO 需驗證
-                BlobAuth blobAuth= _azureStorage.GetBlobSasUriRead(ContainerName, BlobName);
-                var  response= await _clientFactory.CreateClient().GetAsync(new Uri(blobAuth.url + blobAuth.sas));
+                BlobAuth blobAuth = _azureStorage.GetBlobSasUriRead(ContainerName, BlobName);
+                var response = await _clientFactory.CreateClient().GetAsync(new Uri(blobAuth.url + blobAuth.sas));
                 response.EnsureSuccessStatusCode();
                 response.EnsureSuccessStatusCode();
-                using var json = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());                
-                return  Ok(json.RootElement);
+                using var json = await JsonDocument.ParseAsync(await response.Content.ReadAsStreamAsync());
+                return Ok(json.RootElement);
             }
             }
             else
             else
             {
             {
@@ -230,96 +230,10 @@ namespace TEAMModelOS.Controllers
         [Authorize(Roles = "IES")]
         [Authorize(Roles = "IES")]
         public async Task<ActionResult> UsedSpace(JsonElement request)
         public async Task<ActionResult> UsedSpace(JsonElement request)
         {
         {
-            long? usedSize = 0;
-            long teach = 0;
-            try
-            {
-                //学校已经分配给所有教师的空间大小GB。
-                request.TryGetProperty("scope", out JsonElement _scope);
-                if (!request.TryGetProperty("containerName", out JsonElement containerName)) return BadRequest();
-                if (_scope.ValueKind.Equals(JsonValueKind.String) && _scope.GetString().Equals("school"))
-                {
-                    var client = _azureCosmos.GetCosmosClient();
-                    await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ",
-                        requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{containerName}") }))
-                    {
-                        var json = await JsonDocument.ParseAsync(item.ContentStream);
-                        foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
-                        {
-                            if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
-                            {
-                                teach = _size.GetInt32();
-                                break;
-                            }
-                        }
-                    }
-                }
-                var name = containerName.GetString();
-                long blobsize = 0;
-                RedisValue value = default;
-                value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", name);
-                if (value != default && !value.IsNullOrEmpty)
-                {
-                    JsonElement record = value.ToString().ToObject<JsonElement>();
-                    if (record.TryGetInt64(out blobsize))
-                    {
-                    }
-                }
-                else
-                {
-                    var client = _azureStorage.GetBlobContainerClient(name);
-                    var size = await client.GetBlobsCatalogSize();
-                    if (size.Item1 > 0)
-                    {
-                        await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", name, size.Item1);
-                    }
-
-                    foreach (var key in size.Item2.Keys)
-                    {
-                        await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", key);
-                        await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
-                    }
-                    usedSize = size.Item1;
-                    return Ok(new { size = size.Item1, catalog = size.Item2, teach });
-                }
-                Dictionary<string, double> catalog = new Dictionary<string, double>();
-                SortedSetEntry[] Scores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Blob:Catalog:{name}");
-                if (Scores != null)
-                {
-                    foreach (var score in Scores)
-                    {
-                        double val = score.Score;
-                        string key = score.Element.ToString();
-                        catalog.Add(key, val);
-                    }
-                    usedSize = blobsize;
-                    return Ok(new { size = blobsize, catalog = catalog, teach });
-                }
-                else
-                {
-                    var client = _azureStorage.GetBlobContainerClient(name);
-                    var size = await client.GetBlobsCatalogSize();
-                    if (size.Item1 > 0)
-                    {
-                        await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", name, size.Item1);
-                    }
-                    foreach (var key in size.Item2.Keys)
-                    {
-                        await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", key);
-                        await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
-                    }
-                    usedSize = size.Item1;
-                    return Ok(new { size = size.Item1, catalog = size.Item2, teach });
-                }
-            }
-            catch (Exception ex)
-            {
-                await _dingDing.SendBotMsg($"IES5,{_option.Location},blob/used-space()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
-            }
-            finally {
-                Console.WriteLine(usedSize);
-            }
-            return BadRequest();
+            request.TryGetProperty("scope", out JsonElement _scope);
+            if (!request.TryGetProperty("containerName", out JsonElement containerName)) return BadRequest();
+            (long usedSize, long teach, long total, long surplus, Dictionary<string, double?> catalog)space =await BlobService.GetSurplusSpace(containerName.ToString(), $"{_scope}",_option, _azureCosmos, _azureRedis, _azureStorage,_dingDing);
+            return Ok(new { size = space.usedSize, catalog = space.catalog, teach=space. teach , surplus = space.surplus, total=space.total });
         }
         }