Jelajahi Sumber

1、grpc增加健康检查
2、grpc增接获取blobSAS签名

李思淳 5 tahun lalu
induk
melakukan
6c92fae94d

+ 46 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksEndpointRouteBuilderExtensions.cs

@@ -0,0 +1,46 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.HealthCheck;
+using Microsoft.AspNetCore.Routing;
+
+namespace Microsoft.AspNetCore.Builder
+{
+    /// <summary>
+    /// Provides extension methods for <see cref="IEndpointRouteBuilder"/> to add gRPC service endpoints.
+    /// </summary>
+    public static class GrpcHealthChecksEndpointRouteBuilderExtensions
+    {
+        /// <summary>
+        /// Maps incoming requests to the gRPC health checks service.
+        /// This service can be queried to discover the health of the server.
+        /// </summary>
+        /// <param name="builder">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
+        /// <returns>An <see cref="GrpcServiceEndpointConventionBuilder"/> for endpoints associated with the service.</returns>
+        public static GrpcServiceEndpointConventionBuilder MapGrpcHealthChecksService(this IEndpointRouteBuilder builder)
+        {
+            if (builder == null)
+            {
+                throw new ArgumentNullException(nameof(builder));
+            }
+
+            return builder.MapGrpcService<HealthServiceImpl>();
+        }
+    }
+}

+ 56 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksPublisher.cs

@@ -0,0 +1,56 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Health.V1;
+using Grpc.HealthCheck;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace Grpc.AspNetCore.HealthChecks
+{
+    internal class GrpcHealthChecksPublisher : IHealthCheckPublisher
+    {
+        private readonly HealthServiceImpl _healthService;
+
+        public GrpcHealthChecksPublisher(HealthServiceImpl healthService)
+        {
+            _healthService = healthService;
+        }
+
+        public Task PublishAsync(HealthReport report, CancellationToken cancellationToken)
+        {
+            foreach (var entry in report.Entries)
+            {
+                var status = entry.Value.Status;
+
+                _healthService.SetStatus(entry.Key, ResolveStatus(status));
+            }
+
+            return Task.CompletedTask;
+        }
+
+        private static HealthCheckResponse.Types.ServingStatus ResolveStatus(HealthStatus status)
+        {
+            return status == HealthStatus.Unhealthy
+                ? HealthCheckResponse.Types.ServingStatus.NotServing
+                : HealthCheckResponse.Types.ServingStatus.Serving;
+        }
+    }
+
+}

+ 52 - 0
TEAMModelGrpc/GrpcHealthCheck/GrpcHealthChecksServiceExtensions.cs

@@ -0,0 +1,52 @@
+#region Copyright notice and license
+
+// Copyright 2019 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using Grpc.AspNetCore.HealthChecks;
+using Grpc.HealthCheck;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
+
+namespace Microsoft.Extensions.DependencyInjection
+{
+    /// <summary>
+    /// Extension methods for the gRPC health checks services.
+    /// </summary>
+    public static class GrpcHealthChecksServiceExtensions
+    {
+        /// <summary>
+        /// Adds gRPC health check services to the specified <see cref="IServiceCollection" />.
+        /// </summary>
+        /// <param name="services">The <see cref="IServiceCollection"/> for adding services.</param>
+        /// <returns>An instance of <see cref="IHealthChecksBuilder"/> from which health checks can be registered.</returns>
+        public static IHealthChecksBuilder AddGrpcHealthChecks(this IServiceCollection services)
+        {
+            if (services == null)
+            {
+                throw new ArgumentNullException(nameof(services));
+            }
+
+            // HealthServiceImpl is designed to be a singleton
+            services.TryAddSingleton<HealthServiceImpl>();
+
+            services.TryAddEnumerable(ServiceDescriptor.Singleton<IHealthCheckPublisher, GrpcHealthChecksPublisher>());
+
+            return services.AddHealthChecks();
+        }
+    }
+}

+ 24 - 0
TEAMModelGrpc/Models/BlobSASDto.cs

@@ -0,0 +1,24 @@
+using ProtoBuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelGrpc.Models
+{
+    [ProtoContract]
+    public class BlobSASDto
+    {
+        /// <summary>
+        /// Blob的URL地址
+        /// </summary>
+        [ProtoMember(1)]
+        public string Url { get; set; }
+
+        /// <summary>
+        /// Blob的SAS签名
+        /// </summary>
+        [ProtoMember(2)]
+        public string SAS { get; set; }
+    }
+}

+ 24 - 0
TEAMModelGrpc/Protos/BlobSASService.proto

@@ -0,0 +1,24 @@
+syntax = "proto3";
+option csharp_namespace = "TMDGrpc.BlobSASService";
+option java_package = "TMDGrpc.BlobSASService";
+package math;
+
+
+service BlobSASService {
+   rpc GetContainerSasUri(Empty) returns(BlobSASDto);
+
+   rpc GetContainerSASRead(BlobSASDto) returns(BlobSASDto);
+
+}
+
+
+
+message Empty {
+}
+
+message BlobSASDto {
+   //Blob的URL地址
+   string Url = 1;
+   //Blob的SAS签名
+   string SAS = 2;
+}

+ 3 - 0
TEAMModelGrpc/Protos/SyllabusService.proto

@@ -14,6 +14,9 @@ service SyllabusService {
    //按树形新增课纲结构
    rpc SaveOrUpdateAsTree(stream SyllabusTreeDto) returns(stream SyllabusTreeDto);
 
+   //删除课纲
+   rpc DeleteSyllabus(Dict) returns(stream SyllabusTreeDto);
+
 }
 
 

+ 83 - 0
TEAMModelGrpc/Protos/VolumeService.proto

@@ -0,0 +1,83 @@
+syntax = "proto3";
+option csharp_namespace = "TMDGrpc.VolumeService";
+option java_package = "TMDGrpc.VolumeService";
+package math;
+
+
+service VolumeService {
+   //保存册别
+   rpc SaveOrUpdateVolume(stream SyllabusVolume) returns(stream SyllabusVolume);
+
+   //查询册别
+   rpc FindVolume(Dict) returns(stream SyllabusVolume);
+
+}
+
+
+
+message SyllabusVolume {
+   //id生成规则
+   string id = 1;
+   //0默认教学课纲的册别 1个人或单独的专题课纲册别 2,系统课纲
+   int32 type = 2;
+   //Type 如果为0 则是学校编码  如果为1 则是seminar 专题/研讨/培训
+   string scopeCode = 3;
+   //学段
+   string periodCode = 4;
+   //学科
+   string subjectCode = 5;
+   //年级
+   string gradeCode = 6;
+   //学期code
+   string semesterCode = 7;
+   //状态
+   int32 status = 8;
+   //册别name
+   string volumeName = 9;
+   //册别code
+   string volumeCode = 10;
+   //创建者醍摩豆id
+   string TEAMModelId = 11;
+   //共编使用者 的醍摩豆id
+   repeated string editors = 12;
+}
+
+//请求参数Dict
+message Dict {
+   //数字Dict
+   map<string,double> NMap = 1;
+   //字符串Dict
+   map<string,string> SMap = 2;
+   //布尔Dict
+   map<string,bool> BMap = 3;
+   //字符串ListMap
+   repeated LSMap LSMap = 4;
+   //数字ListMap
+   repeated LNMap LNMap = 5;
+   //Byte ListMap
+   repeated LBMap LBMap = 6;
+}
+
+//Byte[] Map
+message LBMap {
+   //Key
+   string Key = 1;
+   //byte数组
+   bytes Value = 2;
+}
+
+//数字ListMap
+message LNMap {
+   //Key
+   string Key = 1;
+   //数字数组
+   repeated double Value = 2 [packed = false];
+}
+
+//字符串ListMap
+message LSMap {
+   //数字Dict
+   string Key = 1;
+   //字符串数组
+   repeated string Value = 2;
+}

+ 64 - 0
TEAMModelGrpc/Services/BlobSASService.cs

@@ -0,0 +1,64 @@
+using Google.Protobuf.WellKnownTypes;
+using Grpc.Core;
+using Grpc.Extension.Abstract;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelGrpc.Models;
+using TEAMModelOS.SDK.Module.AzureBlob.Interfaces;
+
+namespace TEAMModelGrpc.Services
+{
+    public class BlobSASService : IGrpcService
+    {
+
+        private readonly IAzureBlobDBRepository _azureBlobDBRepository;
+
+        public BlobSASService(IAzureBlobDBRepository azureBlobDBRepository)
+        {
+            _azureBlobDBRepository = azureBlobDBRepository;
+        }
+
+        public async Task<BlobSASDto> GetContainerSasUri(Empty empty, ServerCallContext context) {
+            (string, string) aaa = _azureBlobDBRepository.GetContainerSasUri();
+            BlobSASDto blobSASDto = new BlobSASDto();
+            blobSASDto.Url = aaa.Item1;
+            blobSASDto.SAS = aaa.Item2;
+            return blobSASDto;
+        }
+
+        public async Task<BlobSASDto> GetContainerSASRead(BlobSASDto blob, ServerCallContext context)
+        {
+            (string, string) a = BlobUrlString(blob.Url);
+            string ContainerName = a.Item1;
+            string BlobName = a.Item2;
+            bool flg = IsBlobName(BlobName);
+            if (flg)
+            {
+                string SAS = _azureBlobDBRepository.GetBlobSasUriRead(ContainerName, BlobName);
+                return new BlobSASDto { Url = SAS };
+            }
+            else throw new Exception();
+            //return responseBuilder.Error(false, ResponseCode.PARAMS_ERROR, "文件名错误").build();
+
+        }
+
+        private static (string, string) BlobUrlString(string sasUrl)
+        {
+            sasUrl = sasUrl.Substring(8);
+            string[] sasUrls = sasUrl.Split("/");
+            string ContainerName;
+            ContainerName = sasUrls[1].Clone().ToString();
+            string item = sasUrls[0] + "/" + sasUrls[1] + "/";
+            string blob = sasUrl.Replace(item, "");
+            return (ContainerName, blob);
+        }
+
+        public static bool IsBlobName(string BlobName)
+        {
+            return System.Text.RegularExpressions.Regex.IsMatch(BlobName,
+             @"(?!((^(con)$)|^(con)\\..*|(^(prn)$)|^(prn)\\..*|(^(aux)$)|^(aux)\\..*|(^(nul)$)|^(nul)\\..*|(^(com)[1-9]$)|^(com)[1-9]\\..*|(^(lpt)[1-9]$)|^(lpt)[1-9]\\..*)|^\\s+|.*\\s$)(^[^\\\\\\:\\<\\>\\*\\?\\\\\\""\\\\|]{1,255}$)");
+        }
+    }
+}

+ 13 - 1
TEAMModelGrpc/Startup.cs

@@ -23,6 +23,7 @@ using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
 using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
 using TEAMModelOS.SDK.Module.AzureTable.Implements;
 using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+using Microsoft.Extensions.Diagnostics.HealthChecks;
 
 namespace TEAMModelGrpc
 {
@@ -40,6 +41,17 @@ namespace TEAMModelGrpc
             services.AddGrpc();
             //添加Grpc扩展
             services.AddGrpcExtensions(_conf);
+            //Grpc健康检查
+            services.AddGrpcHealthChecks()
+               .AddAsyncCheck("", () =>
+               {
+                   var r = new Random();
+                   var result = r.Next() % 5 == 0
+                       ? HealthCheckResult.Unhealthy()
+                       : HealthCheckResult.Healthy();
+
+                   return Task.FromResult(result);
+               }, Array.Empty<string>());
 
             services.AddAuthorization(options =>
             {
@@ -101,7 +113,7 @@ namespace TEAMModelGrpc
             app.UseEndpoints(endpoints =>
             {
                 endpoints.MapGrpcService<KnowledgeService>();
-
+                endpoints.MapGrpcHealthChecksService();
                 endpoints.MapGet("/generateJwtToken", context =>
                 {
                     return context.Response.WriteAsync(GenerateJwtToken(context.Request.Query["name"]));

+ 5 - 0
TEAMModelGrpc/TEAMModelGrpc.csproj

@@ -20,14 +20,19 @@
 
   <ItemGroup>
     <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
+    <PackageReference Include="Grpc.HealthCheck" Version="2.28.1" />
     <PackageReference Include="Grpc.Tools" Version="2.27.0">
       <PrivateAssets>all</PrivateAssets>
       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
     </PackageReference>
+    <PackageReference Include="Microsoft.Extensions.Http" Version="3.1.3" />
     <PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.10.8" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
     <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
   </ItemGroup>
+  <ItemGroup>
+    <Folder Include="GrpcHealthCheck\" />
+  </ItemGroup>
 </Project>

+ 70 - 0
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -4,6 +4,41 @@
         <name>TEAMModelGrpc</name>
     </assembly>
     <members>
+        <member name="T:Microsoft.AspNetCore.Builder.GrpcHealthChecksEndpointRouteBuilderExtensions">
+            <summary>
+            Provides extension methods for <see cref="T:Microsoft.AspNetCore.Routing.IEndpointRouteBuilder"/> to add gRPC service endpoints.
+            </summary>
+        </member>
+        <member name="M:Microsoft.AspNetCore.Builder.GrpcHealthChecksEndpointRouteBuilderExtensions.MapGrpcHealthChecksService(Microsoft.AspNetCore.Routing.IEndpointRouteBuilder)">
+            <summary>
+            Maps incoming requests to the gRPC health checks service.
+            This service can be queried to discover the health of the server.
+            </summary>
+            <param name="builder">The <see cref="T:Microsoft.AspNetCore.Routing.IEndpointRouteBuilder"/> to add the route to.</param>
+            <returns>An <see cref="T:Microsoft.AspNetCore.Builder.GrpcServiceEndpointConventionBuilder"/> for endpoints associated with the service.</returns>
+        </member>
+        <member name="T:Microsoft.Extensions.DependencyInjection.GrpcHealthChecksServiceExtensions">
+            <summary>
+            Extension methods for the gRPC health checks services.
+            </summary>
+        </member>
+        <member name="M:Microsoft.Extensions.DependencyInjection.GrpcHealthChecksServiceExtensions.AddGrpcHealthChecks(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
+            <summary>
+            Adds gRPC health check services to the specified <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection" />.
+            </summary>
+            <param name="services">The <see cref="T:Microsoft.Extensions.DependencyInjection.IServiceCollection"/> for adding services.</param>
+            <returns>An instance of <see cref="T:Microsoft.Extensions.DependencyInjection.IHealthChecksBuilder"/> from which health checks can be registered.</returns>
+        </member>
+        <member name="P:TEAMModelGrpc.Models.BlobSASDto.Url">
+            <summary>
+            Blob的URL地址
+            </summary>
+        </member>
+        <member name="P:TEAMModelGrpc.Models.BlobSASDto.SAS">
+            <summary>
+            Blob的SAS签名
+            </summary>
+        </member>
         <member name="T:TEAMModelGrpc.Models.Dict">
             <summary>
             请求参数Dict
@@ -245,6 +280,32 @@
             <param name="context"></param>
             <returns></returns>
         </member>
+        <member name="M:TEAMModelGrpc.Services.SyllabusService.DeleteSyllabus(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelGrpc.Models.SyllabusTreeDto},Grpc.Core.ServerCallContext)">
+            <summary>
+            删除课纲
+            </summary>
+            <param name="request"></param>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
+        <member name="M:TEAMModelGrpc.Services.VolumeService.SaveOrUpdateVolume(Grpc.Core.IAsyncStreamReader{TEAMModelOS.Service.Models.Syllabus.SyllabusVolume},Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Syllabus.SyllabusVolume},Grpc.Core.ServerCallContext)">
+            <summary>
+            保存册别
+            </summary>
+            <param name="requestStream"></param>
+            <param name="responseStream"></param>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
+        <member name="M:TEAMModelGrpc.Services.VolumeService.FindVolume(TEAMModelGrpc.Models.Dict,Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Syllabus.SyllabusVolume},Grpc.Core.ServerCallContext)">
+            <summary>
+            查询册别
+            </summary>
+            <param name="request"></param>
+            <param name="responseStream"></param>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
         <member name="T:TEAMModelGrpc.GreetReflection">
             <summary>Holder for reflection information generated from Protos/greet.proto</summary>
         </member>
@@ -1271,6 +1332,15 @@
              <param name="context">The context of the server-side call handler being invoked.</param>
              <returns>A task indicating completion of the handler.</returns>
         </member>
+        <member name="M:TMDGrpc.SyllabusService.SyllabusService.SyllabusServiceBase.DeleteSyllabus(TMDGrpc.SyllabusService.Dict,Grpc.Core.IServerStreamWriter{TMDGrpc.SyllabusService.SyllabusTreeDto},Grpc.Core.ServerCallContext)">
+             <summary>
+            删除课纲
+             </summary>
+             <param name="request">The request received from the client.</param>
+             <param name="responseStream">Used for sending responses back to the client.</param>
+             <param name="context">The context of the server-side call handler being invoked.</param>
+             <returns>A task indicating completion of the handler.</returns>
+        </member>
         <member name="M:TMDGrpc.SyllabusService.SyllabusService.BindService(TMDGrpc.SyllabusService.SyllabusService.SyllabusServiceBase)">
             <summary>Creates service definition that can be registered with a server</summary>
             <param name="serviceImpl">An object implementing the server-side handling logic.</param>

+ 1 - 1
TEAMModelGrpc/appsettings.Development.json

@@ -36,7 +36,7 @@
       "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn"
     },
     "Blob": {
-      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn",
+      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=teammodelostest;AccountKey=QB/zYHHCAtZfl9tf4emL1Y9ZXGc6fqZ+nNbCxIHM70HnziC8dMdEAu7+Pa4mbKLlbswV90wWHAF3nMjrKB54Lw==;EndpointSuffix=core.chinacloudapi.cn", //"DefaultEndpointsProtocol=https;AccountName=teammodelstorage;AccountKey=Yq7D4dE6cFuer2d2UZIccTA/i0c3sJ/6ITc8tNOyW+K5f+/lWw9GCos3Mxhj47PyWQgDL8YbVD63B9XcGtrMxQ==;EndpointSuffix=core.chinacloudapi.cn",
       "Container": "teammodelos"
     },
     "CosmosDB": {

+ 21 - 5
TEAMModelOS/Controllers/Learn/HomeWorkController.cs

@@ -47,6 +47,8 @@ namespace TEAMModelOS.Controllers.Learn
             }
             bool flg = false; 
 
+
+            //新增
             if (string.IsNullOrEmpty(request.@params.id)) {
 
                 request.@params.id = Guid.NewGuid().ToString();
@@ -54,10 +56,13 @@ namespace TEAMModelOS.Controllers.Learn
                 flg = true;
             }
 
+            //重新发布
+
 
             HomeWork homeWork = await _cosmos.SaveOrUpdate<HomeWork>(request.@params);
 
-            if (flg) {
+            if (flg)
+            {
                 //根据作业发布对象查找到每一个具体学生生成关联关系表 HomeWorkStudent
                 List<Target> targets = request.@params.target;
                 List<ClassroomStudent> Classrooms = new List<ClassroomStudent>();
@@ -66,11 +71,12 @@ namespace TEAMModelOS.Controllers.Learn
                 {
                     List<ClassroomStudent> classroom = await _cosmos.FindByDict<ClassroomStudent>(new Dictionary<string, object> { { "id", target.classroomCode }, { "scopeCode", target.scopeCode } });
 
-                    if (classroom.IsNotEmpty()) {
+                    if (classroom.IsNotEmpty())
+                    {
                         foreach (string studentid in classroom[0].studentId)
                         {
                             HomeWorkStudent homeWorkStudent = new HomeWorkStudent();
-                            homeWorkStudent.id = Guid.NewGuid().ToString();
+                            homeWorkStudent.id = studentid;
                             homeWorkStudent.homeWorkId = request.@params.id;
                             homeWorkStudent.studentId = studentid;
                             homeWorkStudent.classroom.code = target.classroomCode;
@@ -78,7 +84,7 @@ namespace TEAMModelOS.Controllers.Learn
                             homeWorkStudents.Add(homeWorkStudent);
                         }
                     }
-                    
+
                 }
                 if (homeWorkStudents.IsNotEmpty())
                 {
@@ -95,10 +101,20 @@ namespace TEAMModelOS.Controllers.Learn
                     }
                     await _cosmos.SaveOrUpdateAll<HomeWorkStudent>(homeWorkStudents);
                 }
+            }
+            //else {
+            //    List<Target> targets = request.@params.target;
+            //    foreach (Target target in targets) { 
+            //        List<HomeWorkStudent> classroom = await _cosmos.FindByDict<HomeWorkStudent>(new Dictionary<string, object> { { "id", target.classroomCode }, { "scopeCode", target.scopeCode } });
 
 
 
-            }
+            //    }
+
+
+
+
+            //}
            
 
             return builder.Data(homeWork).build();