OnePsycho 5 năm trước cách đây
mục cha
commit
d0bcbc9482
31 tập tin đã thay đổi với 706 bổ sung163 xóa
  1. 20 0
      TEAMModelGrpc/Models/RequestDict.cs
  2. 27 0
      TEAMModelGrpc/Program.cs
  3. 12 0
      TEAMModelGrpc/Properties/launchSettings.json
  4. 3 3
      TEAMModelOS.Grpc/Protos/KnowledgeService.proto
  5. 21 0
      TEAMModelGrpc/Protos/greet.proto
  6. 26 0
      TEAMModelGrpc/Services/GreeterService.cs
  7. 72 0
      TEAMModelGrpc/Services/KnowledgeService.cs
  8. 20 1
      TEAMModelOS.GRPC/Startup.cs
  9. 28 0
      TEAMModelGrpc/TEAMModelGrpc.csproj
  10. 84 0
      TEAMModelGrpc/TEAMModelOS.GRPC.xml
  11. 62 0
      TEAMModelGrpc/appsettings.Development.json
  12. 15 0
      TEAMModelGrpc/appsettings.json
  13. 0 23
      TEAMModelOS.GRPC/TEAMModelOS.GRPC.csproj
  14. 2 1
      TEAMModelOS.Grpc/Services/GreeterService.cs
  15. 15 3
      TEAMModelOS.Grpc/Services/Syllabus/KnowledgeService.cs
  16. 19 0
      TEAMModelOS.Grpc/Startup.cs
  17. 36 90
      TEAMModelOS.Grpc/TEAMModelOS.GRPC.xml
  18. 14 6
      TEAMModelOS.Grpc/TEAMModelOS.Grpc.csproj
  19. 112 1
      TEAMModelOS.Grpc/appsettings.Development.json
  20. 1 0
      TEAMModelOS.Grpc/appsettings.json
  21. 10 10
      TEAMModelOS.SDK/Module/Grpc/Common/Internal/ProtoGenerator.cs
  22. 3 1
      TEAMModelOS.Service/TEAMModelOS.Service.csproj
  23. 11 5
      TEAMModelOS.sln
  24. 1 1
      TEAMModelOS/ClientApp/src/view/Home.vue
  25. 7 0
      TEAMModelOS/ClientApp/src/view/selflearning/CreateLearnUnit.less
  26. 7 4
      TEAMModelOS/ClientApp/src/view/selflearning/CreateLearnUnit.vue
  27. 7 0
      TEAMModelOS/ClientApp/src/view/selflearning/CreateOrderLearn.less
  28. 8 5
      TEAMModelOS/ClientApp/src/view/selflearning/CreateOrderLearn.vue
  29. 28 1
      TEAMModelOS/ClientApp/src/view/selflearning/ManageOrderLearn.less
  30. 13 4
      TEAMModelOS/ClientApp/src/view/selflearning/ManageOrderLearn.vue
  31. 22 4
      TEAMModelOS/ClientApp/src/view/selflearning/ManageUnit.vue

+ 20 - 0
TEAMModelGrpc/Models/RequestDict.cs

@@ -0,0 +1,20 @@
+using ProtoBuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace TEAMModelGrpc.Models
+{
+    [ProtoContract]
+    public class RequestDict
+    {
+        /// <summary>
+        /// 查询dict
+        /// </summary>
+        [ProtoMember(1)]
+        public Dictionary<string, string> dict { get; set; }
+
+
+    }
+}

+ 27 - 0
TEAMModelGrpc/Program.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Hosting;
+
+namespace TEAMModelGrpc
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            CreateHostBuilder(args).Build().Run();
+        }
+
+        // Additional configuration is required to successfully run gRPC on macOS.
+        // For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
+        public static IHostBuilder CreateHostBuilder(string[] args) =>
+            Host.CreateDefaultBuilder(args)
+                .ConfigureWebHostDefaults(webBuilder =>
+                {
+                    webBuilder.UseStartup<Startup>();
+                });
+    }
+}

+ 12 - 0
TEAMModelGrpc/Properties/launchSettings.json

@@ -0,0 +1,12 @@
+{
+  "profiles": {
+    "TEAMModelGrpc": {
+      "commandName": "Project",
+      "launchBrowser": false,
+      "applicationUrl": "https://localhost:5001",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    }
+  }
+}

+ 3 - 3
TEAMModelOS.Grpc/Protos/KnowledgeService.proto

@@ -1,10 +1,10 @@
 syntax = "proto3";
-option csharp_namespace = "TMDOSGRPC.KnowledgeService";
-package TMDOSGRPC.KnowledgeService;
+option csharp_namespace = "TEAMModelGrpc";
+package math;
 
 
 service KnowledgeService {
-   rpc FinKnowledge1(RequestDict) returns(stream Knowledge);
+   rpc FinKnowledge(RequestDict) returns(stream Knowledge);
 
 }
 

+ 21 - 0
TEAMModelGrpc/Protos/greet.proto

@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+option csharp_namespace = "TEAMModelGrpc";
+
+package greet;
+
+// The greeting service definition.
+service Greeter {
+  // Sends a greeting
+  rpc SayHello (HelloRequest) returns (HelloReply);
+}
+
+// The request message containing the user's name.
+message HelloRequest {
+  string name = 1;
+}
+
+// The response message containing the greetings.
+message HelloReply {
+  string message = 1;
+}

+ 26 - 0
TEAMModelGrpc/Services/GreeterService.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Microsoft.Extensions.Logging;
+
+namespace TEAMModelGrpc
+{
+    public class GreeterService : Greeter.GreeterBase
+    {
+        private readonly ILogger<GreeterService> _logger;
+        public GreeterService(ILogger<GreeterService> logger)
+        {
+            _logger = logger;
+        }
+
+        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
+        {
+            return Task.FromResult(new HelloReply
+            {
+                Message = "Hello " + request.Name
+            });
+        }
+    }
+}

+ 72 - 0
TEAMModelGrpc/Services/KnowledgeService.cs

@@ -0,0 +1,72 @@
+using Grpc.Core;
+using Grpc.Extension.Abstract;
+using Microsoft.AspNetCore.Authorization;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using TEAMModelGrpc.Models;
+using TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.Service.Models.Syllabus;
+
+namespace TEAMModelGrpc.Services
+{
+    /// <summary>
+    /// 
+    /// </summary>
+    public class KnowledgeService : IGrpcService
+    {
+        public IAzureCosmosDBV3Repository cosmosDBV3Repository;
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="cosmosDBV3Repository"></param>
+        public KnowledgeService(IAzureCosmosDBV3Repository cosmosDBV3Repository)
+        {
+            this.cosmosDBV3Repository = cosmosDBV3Repository;
+        }
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="request"></param>
+        /// <param name="responseStream"></param>
+        /// <param name="context"></param>
+        /// <returns></returns>
+        //[Authorize]
+        public async Task FinKnowledge(RequestDict request, IServerStreamWriter<Knowledge> responseStream, ServerCallContext context)
+        {
+            string a = request.dict.ToJson();
+            Dictionary<string, object> keyValuePairs = JsonNetHelper.FromJson<Dictionary<string, object>>(a);
+            List<Knowledge> knowledges = await cosmosDBV3Repository.FindByDict<Knowledge>(keyValuePairs);
+
+            knowledges.ForEach(x =>
+            {
+                responseStream.WriteAsync(x);
+            });
+            //ResponseList<Knowledge> listKnowledge = new ResponseList<Knowledge>();
+            //listKnowledge.response = knowledges;
+            //return await Task.FromResult(listKnowledge);
+        }
+        //[Authorize]
+        //public async Task FinKnowledge(string request, IServerStreamWriter<Family> responseStream, ServerCallContext context)
+        //{
+        //    Console.WriteLine("gRPC ");
+        //    string a = request.ToJson();
+        //    Dictionary<string, object> keyValuePairs = JsonNetHelper.FromJson<Dictionary<string, object>>(request);
+        //    List<Family> knowledges = await cosmosDBV3Repository.FindByDict<Family>(keyValuePairs);
+        //    ListKnowledge listKnowledge = new ListKnowledge();
+        //    listKnowledge.knowledges = knowledges;
+        //    knowledges.ForEach(x =>
+        //    {
+        //        responseStream.WriteAsync(x);
+        //    });
+        //    //foreach (Family family in knowledges)
+        //    //{
+        //    //    await responseStream.WriteAsync(family);
+        //    //}
+        //    //return await Task.FromResult(listKnowledge);
+        //}
+
+    }
+}

+ 20 - 1
TEAMModelOS.GRPC/Startup.cs

@@ -2,21 +2,31 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using Grpc.Extension.AspNetCore;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
+using TEAMModelGrpc.Services;
 
-namespace TEAMModelOS.Grpc
+namespace TEAMModelGrpc
 {
     public class Startup
     {
+        private IConfiguration _conf;
+        public Startup(IConfiguration conf)
+        {
+            _conf = conf;
+        }
         // This method gets called by the runtime. Use this method to add services to the container.
         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
         public void ConfigureServices(IServiceCollection services)
         {
             services.AddGrpc();
+            //添加Grpc扩展
+            services.AddGrpcExtensions(_conf);
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -38,6 +48,15 @@ namespace TEAMModelOS.Grpc
                     await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
                 });
             });
+            //CodeFirst的Grpc(会自动扫描TStartup所在程序集下的IGrpcSerivce)
+            app.UseGrpcExtensions<KnowledgeService>(options =>
+            {
+                //CodeFirst配制
+                options.GlobalPackage = "math";
+                options.ProtoNameSpace = "TEAMModelGrpc";
+            })
+            //CodeFirst生成proto
+            .UseProtoGenerate("protos", false);
         }
     }
 }

+ 28 - 0
TEAMModelGrpc/TEAMModelGrpc.csproj

@@ -0,0 +1,28 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+  <PropertyGroup>
+    <TargetFramework>netcoreapp3.1</TargetFramework>
+  </PropertyGroup>
+
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile>TEAMModelOS.GRPC.xml</DocumentationFile>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
+    <PackageReference Include="Grpc.Tools" Version="2.27.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
+    <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
+  </ItemGroup>
+
+</Project>

+ 84 - 0
TEAMModelGrpc/TEAMModelOS.GRPC.xml

@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>TEAMModelGrpc</name>
+    </assembly>
+    <members>
+        <member name="P:TEAMModelGrpc.Models.RequestDict.dict">
+            <summary>
+            查询dict
+            </summary>
+        </member>
+        <member name="T:TEAMModelGrpc.Services.KnowledgeService">
+            <summary>
+            
+            </summary>
+        </member>
+        <member name="M:TEAMModelGrpc.Services.KnowledgeService.#ctor(TEAMModelOS.SDK.Module.AzureCosmosDBV3.IAzureCosmosDBV3Repository)">
+            <summary>
+            
+            </summary>
+            <param name="cosmosDBV3Repository"></param>
+        </member>
+        <member name="M:TEAMModelGrpc.Services.KnowledgeService.FinKnowledge(TEAMModelGrpc.Models.RequestDict,Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Syllabus.Knowledge},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>
+        <member name="P:TEAMModelGrpc.GreetReflection.Descriptor">
+            <summary>File descriptor for Protos/greet.proto</summary>
+        </member>
+        <member name="T:TEAMModelGrpc.HelloRequest">
+            <summary>
+            The request message containing the user's name.
+            </summary>
+        </member>
+        <member name="F:TEAMModelGrpc.HelloRequest.NameFieldNumber">
+            <summary>Field number for the "name" field.</summary>
+        </member>
+        <member name="T:TEAMModelGrpc.HelloReply">
+            <summary>
+            The response message containing the greetings.
+            </summary>
+        </member>
+        <member name="F:TEAMModelGrpc.HelloReply.MessageFieldNumber">
+            <summary>Field number for the "message" field.</summary>
+        </member>
+        <member name="T:TEAMModelGrpc.Greeter">
+            <summary>
+            The greeting service definition.
+            </summary>
+        </member>
+        <member name="P:TEAMModelGrpc.Greeter.Descriptor">
+            <summary>Service descriptor</summary>
+        </member>
+        <member name="T:TEAMModelGrpc.Greeter.GreeterBase">
+            <summary>Base class for server-side implementations of Greeter</summary>
+        </member>
+        <member name="M:TEAMModelGrpc.Greeter.GreeterBase.SayHello(TEAMModelGrpc.HelloRequest,Grpc.Core.ServerCallContext)">
+            <summary>
+            Sends a greeting
+            </summary>
+            <param name="request">The request received from the client.</param>
+            <param name="context">The context of the server-side call handler being invoked.</param>
+            <returns>The response to send back to the client (wrapped by a task).</returns>
+        </member>
+        <member name="M:TEAMModelGrpc.Greeter.BindService(TEAMModelGrpc.Greeter.GreeterBase)">
+            <summary>Creates service definition that can be registered with a server</summary>
+            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+        </member>
+        <member name="M:TEAMModelGrpc.Greeter.BindService(Grpc.Core.ServiceBinderBase,TEAMModelGrpc.Greeter.GreeterBase)">
+            <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
+            Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+            <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+        </member>
+    </members>
+</doc>

+ 62 - 0
TEAMModelGrpc/appsettings.Development.json

@@ -0,0 +1,62 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Grpc": "Information",
+      "Microsoft": "Information"
+    }
+  },
+  "urls": "https://*:5000",
+  "GrpcServer": {
+    //用于grpc启动后注册到服务发现的ip地址段
+    "ServiceAddress": "192.168.*.*:",
+    //是否启用服务注册和服务发现,默认是true
+    "EnableDiscovery": false,
+    //服务发现服务器地址
+    "DiscoveryUrl": "http://106.12.23.251:8500",
+    //注册到服务发现的服务名称
+    "DiscoveryServiceName": "TMDOSgRPC",
+    //服务发现主动TTL的时间(秒)
+    "DiscoveryTTLInterval": 10,
+    //注册到服务发现的服务Tag
+    "DiscoveryServiceTags": "v-1.0.0.1",
+    //默认错误码
+    "DefaultErrorCode": 4300000,
+    //Jaeger配制(OpenTracing)
+    "Jaeger": {
+      //是否启用Jaeger,默认false
+      "Enable": false,
+      "AgentIp": "192.168.8.11",
+      "AgentPort": 5775
+    }
+  },
+  "Azure": {
+    "Table": {
+      "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",
+      "Container": "teammodelos"
+    },
+    "CosmosDB": {
+      "ConnectionString": "https://192.168.8.128:8081",
+      "ConnectionKey": "ddwAeGSf8Lsf1kxPXmdqnyzzi3CkJ0KW2BTPZ7Zq1N7qbJic5j7AaQ+WbF86F3rnzuDgGM1yg8O7BUFo93iA8w==",
+      "Database": "TEAMModelOS",
+      "CollectionThroughput": 400,
+      "ScanModel": [ "TEAMModelOS.Service" ]
+    },
+    "Redis": {
+      "ConnectionString": "106.12.23.251:6379,password=habook,ssl=false,abortConnect=False,defaultDatabase=13,writeBuffer=10240,poolsize=50,prefix=habook:"
+    }
+  },
+  "HaBookAuth": {
+    "TeamModelRegistUrl": "https://account.habookaclass.biz/regist?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "TeamModelLoginUrl": "https://account.habookaclass.biz/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "AccountUrl": "https://api.habookaclass.biz/account",
+    "ServiceUrl": "https://api.habookaclass.biz/service",
+    "UserInfoKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJpZCIsImF1ZCI6ImNoZW5nZHVJZCIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYwNTIzNjcsIm5iZiI6MTUzNjA1MjM2NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.RGKDVtwFEp4OBctlHOuF6yqyI21fTz4cinCxjFCxkSQ",
+    "SchoolCodeKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzY2hvb2xDb2RlIiwiYXVkIjoiY2hlbmdkdVNjaG9vbENvZGUiLCJpc3MiOiJodHRwczovL2FwaS5oYWJvb2thY2xhc3MuYml6IiwiaWF0IjoxNTM2MDUyNDI3LCJuYmYiOjE1MzYwNTI0MjcsImV4cCI6MTU2NzU1NTIwMCwiaWRwIjoiSGFib29rIENvcmVTZXJ2aWNlIn0.8m5VH3Nz4N9EdMz8AexTOEuDVitcJZFKy9DfW_UQkSY",
+    "SmsKey": "Basic ZmYwMWM0YTJjODdmZmNkYTUyNjhmMDEwOmE0YTE5YTVjNTU2ZWVhZTNjZmZhNTI0Mg=="
+  }
+}

+ 15 - 0
TEAMModelGrpc/appsettings.json

@@ -0,0 +1,15 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "Microsoft.Hosting.Lifetime": "Information"
+    }
+  },
+  "AllowedHosts": "*",
+  "Kestrel": {
+    "EndpointDefaults": {
+      "Protocols": "Http2"
+    }
+  }
+}

+ 0 - 23
TEAMModelOS.GRPC/TEAMModelOS.GRPC.csproj

@@ -1,23 +0,0 @@
-<Project Sdk="Microsoft.NET.Sdk.Web">
-
-  <PropertyGroup>
-    <TargetFramework>netcoreapp3.1</TargetFramework>
-  </PropertyGroup>
-
-  <ItemGroup>
-    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
-  </ItemGroup>
-
-  <ItemGroup>
-    <Folder Include="Services\Core\" />
-    <Folder Include="Services\Courses\" />
-    <Folder Include="Services\Exam\" />
-    <Folder Include="Services\Learn\" />
-    <Folder Include="Services\Syllabus\" />
-  </ItemGroup>
-
-</Project>

+ 2 - 1
TEAMModelOS.Grpc/Services/GreeterService.cs

@@ -4,7 +4,7 @@ using System.Linq;
 using System.Threading.Tasks;
 using Grpc.Core;
 using Microsoft.Extensions.Logging;
-
+using TEAMModelOS.Grpc;
 namespace TEAMModelOS.Grpc
 {
     public class GreeterService : Greeter.GreeterBase
@@ -23,4 +23,5 @@ namespace TEAMModelOS.Grpc
             });
         }
     }
+
 }

+ 15 - 3
TEAMModelOS.Grpc/Services/Syllabus/KnowledgeService.cs

@@ -13,17 +13,29 @@ using TEAMModelOS.GRPC.Models.Dtos;
 
 namespace TEAMModelOS.GRPC.Services.Syllabus
 {
+    /// <summary>
+    /// 
+    /// </summary>
     public class KnowledgeService : IGrpcService
     {
         public IAzureCosmosDBV3Repository cosmosDBV3Repository;
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="cosmosDBV3Repository"></param>
         public KnowledgeService(IAzureCosmosDBV3Repository cosmosDBV3Repository)
         {
             this.cosmosDBV3Repository = cosmosDBV3Repository;
         }
-
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="request"></param>
+        /// <param name="responseStream"></param>
+        /// <param name="context"></param>
+        /// <returns></returns>
         //[Authorize]
-        public async Task FinKnowledge1(RequestDict request, IServerStreamWriter<Knowledge> responseStream, ServerCallContext context)
+        public async Task FinKnowledge(RequestDict request, IServerStreamWriter<Knowledge> responseStream, ServerCallContext context)
         {
             string a = request.dict.ToJson();
             Dictionary<string, object> keyValuePairs = JsonNetHelper.FromJson<Dictionary<string, object>>(a);

+ 19 - 0
TEAMModelOS.Grpc/Startup.cs

@@ -2,21 +2,31 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Threading.Tasks;
+using Grpc.Extension.AspNetCore;
 using Microsoft.AspNetCore.Builder;
 using Microsoft.AspNetCore.Hosting;
 using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Configuration;
 using Microsoft.Extensions.DependencyInjection;
 using Microsoft.Extensions.Hosting;
+using TEAMModelOS.GRPC.Services.Syllabus;
 
 namespace TEAMModelOS.Grpc
 {
     public class Startup
     {
+        private IConfiguration _conf;
+        public Startup(IConfiguration conf)
+        {
+            _conf = conf;
+        }
         // This method gets called by the runtime. Use this method to add services to the container.
         // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
         public void ConfigureServices(IServiceCollection services)
         {
             services.AddGrpc();
+            //添加Grpc扩展
+            services.AddGrpcExtensions(_conf);
         }
 
         // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@@ -38,6 +48,15 @@ namespace TEAMModelOS.Grpc
                     await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
                 });
             });
+            //CodeFirst的Grpc(会自动扫描TStartup所在程序集下的IGrpcSerivce)
+            app.UseGrpcExtensions<KnowledgeService>(options =>
+            {
+                //CodeFirst配制
+                options.GlobalPackage = "math";
+                options.ProtoNameSpace = "MathGrpc";
+            })
+            //CodeFirst生成proto
+            .UseProtoGenerate("protos", false);
         }
     }
 }

+ 36 - 90
TEAMModelOS.Grpc/TEAMModelOS.GRPC.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <doc>
     <assembly>
-        <name>TEAMModelOS.GRPC</name>
+        <name>TEAMModelOS.Grpc</name>
     </assembly>
     <members>
         <member name="P:TEAMModelOS.GRPC.Models.Dtos.RequestDict.dict">
@@ -9,40 +9,60 @@
             查询dict
             </summary>
         </member>
-        <member name="T:Helloworld.HelloworldReflection">
-            <summary>Holder for reflection information generated from Protos/helloworld.proto</summary>
+        <member name="T:TEAMModelOS.GRPC.Services.Syllabus.KnowledgeService">
+            <summary>
+            
+            </summary>
         </member>
-        <member name="P:Helloworld.HelloworldReflection.Descriptor">
-            <summary>File descriptor for Protos/helloworld.proto</summary>
+        <member name="M:TEAMModelOS.GRPC.Services.Syllabus.KnowledgeService.#ctor(TEAMModelOS.SDK.Module.AzureCosmosDBV3.IAzureCosmosDBV3Repository)">
+            <summary>
+            
+            </summary>
+            <param name="cosmosDBV3Repository"></param>
         </member>
-        <member name="T:Helloworld.HelloRequest">
+        <member name="M:TEAMModelOS.GRPC.Services.Syllabus.KnowledgeService.FinKnowledge(TEAMModelOS.GRPC.Models.Dtos.RequestDict,Grpc.Core.IServerStreamWriter{TEAMModelOS.Service.Models.Syllabus.Knowledge},Grpc.Core.ServerCallContext)">
+            <summary>
+            
+            </summary>
+            <param name="request"></param>
+            <param name="responseStream"></param>
+            <param name="context"></param>
+            <returns></returns>
+        </member>
+        <member name="T:TEAMModelOS.Grpc.GreetReflection">
+            <summary>Holder for reflection information generated from Protos/greet.proto</summary>
+        </member>
+        <member name="P:TEAMModelOS.Grpc.GreetReflection.Descriptor">
+            <summary>File descriptor for Protos/greet.proto</summary>
+        </member>
+        <member name="T:TEAMModelOS.Grpc.HelloRequest">
             <summary>
             The request message containing the user's name.
             </summary>
         </member>
-        <member name="F:Helloworld.HelloRequest.NameFieldNumber">
+        <member name="F:TEAMModelOS.Grpc.HelloRequest.NameFieldNumber">
             <summary>Field number for the "name" field.</summary>
         </member>
-        <member name="T:Helloworld.HelloReply">
+        <member name="T:TEAMModelOS.Grpc.HelloReply">
             <summary>
-            The response message containing the greetings
+            The response message containing the greetings.
             </summary>
         </member>
-        <member name="F:Helloworld.HelloReply.MessageFieldNumber">
+        <member name="F:TEAMModelOS.Grpc.HelloReply.MessageFieldNumber">
             <summary>Field number for the "message" field.</summary>
         </member>
-        <member name="T:Helloworld.Greeter">
+        <member name="T:TEAMModelOS.Grpc.Greeter">
             <summary>
             The greeting service definition.
             </summary>
         </member>
-        <member name="P:Helloworld.Greeter.Descriptor">
+        <member name="P:TEAMModelOS.Grpc.Greeter.Descriptor">
             <summary>Service descriptor</summary>
         </member>
-        <member name="T:Helloworld.Greeter.GreeterBase">
+        <member name="T:TEAMModelOS.Grpc.Greeter.GreeterBase">
             <summary>Base class for server-side implementations of Greeter</summary>
         </member>
-        <member name="M:Helloworld.Greeter.GreeterBase.SayHello(Helloworld.HelloRequest,Grpc.Core.ServerCallContext)">
+        <member name="M:TEAMModelOS.Grpc.Greeter.GreeterBase.SayHello(TEAMModelOS.Grpc.HelloRequest,Grpc.Core.ServerCallContext)">
             <summary>
             Sends a greeting
             </summary>
@@ -50,85 +70,11 @@
             <param name="context">The context of the server-side call handler being invoked.</param>
             <returns>The response to send back to the client (wrapped by a task).</returns>
         </member>
-        <member name="M:Helloworld.Greeter.GreeterBase.SayHelloStream(Grpc.Core.IAsyncStreamReader{Helloworld.HelloRequest},Grpc.Core.ServerCallContext)">
-            <summary>
-            Stream Sends a greeting
-            </summary>
-            <param name="requestStream">Used for reading requests from the client.</param>
-            <param name="context">The context of the server-side call handler being invoked.</param>
-            <returns>The response to send back to the client (wrapped by a task).</returns>
-        </member>
-        <member name="M:Helloworld.Greeter.BindService(Helloworld.Greeter.GreeterBase)">
-            <summary>Creates service definition that can be registered with a server</summary>
-            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-        </member>
-        <member name="M:Helloworld.Greeter.BindService(Grpc.Core.ServiceBinderBase,Helloworld.Greeter.GreeterBase)">
-            <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
-            Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
-            <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
-            <param name="serviceImpl">An object implementing the server-side handling logic.</param>
-        </member>
-        <member name="T:TMDOSGRPC.KnowledgeService.KnowledgeServiceReflection">
-            <summary>Holder for reflection information generated from Protos/KnowledgeService.proto</summary>
-        </member>
-        <member name="P:TMDOSGRPC.KnowledgeService.KnowledgeServiceReflection.Descriptor">
-            <summary>File descriptor for Protos/KnowledgeService.proto</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.RequestDict.DictFieldNumber">
-            <summary>Field number for the "dict" field.</summary>
-        </member>
-        <member name="P:TMDOSGRPC.KnowledgeService.RequestDict.Dict">
-             <summary>
-            查询dict
-             </summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.IdFieldNumber">
-            <summary>Field number for the "id" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.TypeFieldNumber">
-            <summary>Field number for the "type" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.NameFieldNumber">
-            <summary>Field number for the "name" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.AliasFieldNumber">
-            <summary>Field number for the "alias" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.SubjectCodeFieldNumber">
-            <summary>Field number for the "subjectCode" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.ScopeCodeFieldNumber">
-            <summary>Field number for the "scopeCode" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.OrderFieldNumber">
-            <summary>Field number for the "order" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.StatusFieldNumber">
-            <summary>Field number for the "status" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.PointsFieldNumber">
-            <summary>Field number for the "points" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.KnowledgeIdFieldNumber">
-            <summary>Field number for the "knowledgeId" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.SourceFieldNumber">
-            <summary>Field number for the "source" field.</summary>
-        </member>
-        <member name="F:TMDOSGRPC.KnowledgeService.Knowledge.PeriodFieldNumber">
-            <summary>Field number for the "period" field.</summary>
-        </member>
-        <member name="P:TMDOSGRPC.KnowledgeService.KnowledgeService.Descriptor">
-            <summary>Service descriptor</summary>
-        </member>
-        <member name="T:TMDOSGRPC.KnowledgeService.KnowledgeService.KnowledgeServiceBase">
-            <summary>Base class for server-side implementations of KnowledgeService</summary>
-        </member>
-        <member name="M:TMDOSGRPC.KnowledgeService.KnowledgeService.BindService(TMDOSGRPC.KnowledgeService.KnowledgeService.KnowledgeServiceBase)">
+        <member name="M:TEAMModelOS.Grpc.Greeter.BindService(TEAMModelOS.Grpc.Greeter.GreeterBase)">
             <summary>Creates service definition that can be registered with a server</summary>
             <param name="serviceImpl">An object implementing the server-side handling logic.</param>
         </member>
-        <member name="M:TMDOSGRPC.KnowledgeService.KnowledgeService.BindService(Grpc.Core.ServiceBinderBase,TMDOSGRPC.KnowledgeService.KnowledgeService.KnowledgeServiceBase)">
+        <member name="M:TEAMModelOS.Grpc.Greeter.BindService(Grpc.Core.ServiceBinderBase,TEAMModelOS.Grpc.Greeter.GreeterBase)">
             <summary>Register service method with a service binder with or without implementation. Useful when customizing the  service binding logic.
             Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
             <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>

+ 14 - 6
TEAMModelOS.Grpc/TEAMModelOS.Grpc.csproj

@@ -3,21 +3,29 @@
   <PropertyGroup>
     <TargetFramework>netcoreapp3.1</TargetFramework>
   </PropertyGroup>
-
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
+    <DocumentationFile>TEAMModelOS.GRPC.xml</DocumentationFile>
+  </PropertyGroup>
+ 
   <ItemGroup>
-    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
+    <PackageReference Include="Grpc.AspNetCore" Version="2.24.0" />
+    <PackageReference Include="Grpc.Tools" Version="2.24.0">
+      <PrivateAssets>all</PrivateAssets>
+      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+    </PackageReference>
   </ItemGroup>
-
   <ItemGroup>
-    <PackageReference Include="Grpc.AspNetCore" Version="2.27.0" />
+    <Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
   </ItemGroup>
-
   <ItemGroup>
     <Folder Include="Services\Core\" />
     <Folder Include="Services\Courses\" />
     <Folder Include="Services\Exam\" />
     <Folder Include="Services\Learn\" />
-    <Folder Include="Services\Syllabus\" />
   </ItemGroup>
 
+  <ItemGroup>
+    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
+    <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
+  </ItemGroup>
 </Project>

+ 112 - 1
TEAMModelOS.Grpc/appsettings.Development.json

@@ -4,7 +4,118 @@
       "Default": "Debug",
       "System": "Information",
       "Grpc": "Information",
-      "Microsoft": "Information"
+      "Microsoft": "Information",
+      "Microsoft.Hosting.Lifetime": "Information"
     }
+  },
+  "urls": "https://*:5001",
+  "GrpcServer": {
+    //用于grpc启动后注册到服务发现的ip地址段
+    "ServiceAddress": "192.168.*.*:",
+    //是否启用服务注册和服务发现,默认是true
+    "EnableDiscovery": true,
+    //服务发现服务器地址
+    "DiscoveryUrl": "http://106.12.23.251:8500",
+    //注册到服务发现的服务名称
+    "DiscoveryServiceName": "TEAMModelOS.GRPC",
+    //服务发现主动TTL的时间(秒)
+    "DiscoveryTTLInterval": 10,
+    //注册到服务发现的服务Tag
+    "DiscoveryServiceTags": "v-1.0.0.1",
+    //默认错误码
+    "DefaultErrorCode": 4300000,
+    //Jaeger配制(OpenTracing)
+    "Jaeger": {
+      //是否启用Jaeger,默认false
+      "Enable": false,
+      "AgentIp": "192.168.8.11",
+      "AgentPort": 5775
+    }
+  },
+  "AllowedHosts": "*",
+  "Kestrel": {
+    "EndpointDefaults": {
+      "Protocols": "Http2"
+    },
+    "Azure": {
+      "Table": {
+        "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",
+        "Container": "teammodelos"
+      },
+      "CosmosDB": {
+        "ConnectionString": "https://192.168.8.128:8081",
+        "ConnectionKey": "ddwAeGSf8Lsf1kxPXmdqnyzzi3CkJ0KW2BTPZ7Zq1N7qbJic5j7AaQ+WbF86F3rnzuDgGM1yg8O7BUFo93iA8w==",
+        "Database": "TEAMModelOS",
+        "CollectionThroughput": 400,
+        "ScanModel": [ "TEAMModelOS.Service" ]
+      },
+      "Redis": {
+        "ConnectionString": "106.12.23.251:6379,password=habook,ssl=false,abortConnect=False,defaultDatabase=13,writeBuffer=10240,poolsize=50,prefix=habook:"
+      }
+    },
+    "HaBookAuth": {
+      "TeamModelRegistUrl": "https://account.habookaclass.biz/regist?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+      "TeamModelLoginUrl": "https://account.habookaclass.biz/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+      "AccountUrl": "https://api.habookaclass.biz/account",
+      "ServiceUrl": "https://api.habookaclass.biz/service",
+      "UserInfoKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJpZCIsImF1ZCI6ImNoZW5nZHVJZCIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYwNTIzNjcsIm5iZiI6MTUzNjA1MjM2NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.RGKDVtwFEp4OBctlHOuF6yqyI21fTz4cinCxjFCxkSQ",
+      "SchoolCodeKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzY2hvb2xDb2RlIiwiYXVkIjoiY2hlbmdkdVNjaG9vbENvZGUiLCJpc3MiOiJodHRwczovL2FwaS5oYWJvb2thY2xhc3MuYml6IiwiaWF0IjoxNTM2MDUyNDI3LCJuYmYiOjE1MzYwNTI0MjcsImV4cCI6MTU2NzU1NTIwMCwiaWRwIjoiSGFib29rIENvcmVTZXJ2aWNlIn0.8m5VH3Nz4N9EdMz8AexTOEuDVitcJZFKy9DfW_UQkSY",
+      "SmsKey": "Basic ZmYwMWM0YTJjODdmZmNkYTUyNjhmMDEwOmE0YTE5YTVjNTU2ZWVhZTNjZmZhNTI0Mg=="
+    }
+  },
+  "urls": "https://*:5000",
+  "GrpcServer": {
+    //用于grpc启动后注册到服务发现的ip地址段
+    "ServiceAddress": "192.168.*.*:",
+    //是否启用服务注册和服务发现,默认是true
+    "EnableDiscovery": false,
+    //服务发现服务器地址
+    "DiscoveryUrl": "http://106.12.23.251:8500",
+    //注册到服务发现的服务名称
+    "DiscoveryServiceName": "TMDOSgRPC",
+    //服务发现主动TTL的时间(秒)
+    "DiscoveryTTLInterval": 10,
+    //注册到服务发现的服务Tag
+    "DiscoveryServiceTags": "v-1.0.0.1",
+    //默认错误码
+    "DefaultErrorCode": 4300000,
+    //Jaeger配制(OpenTracing)
+    "Jaeger": {
+      //是否启用Jaeger,默认false
+      "Enable": false,
+      "AgentIp": "192.168.8.11",
+      "AgentPort": 5775
+    }
+  },
+  "Azure": {
+    "Table": {
+      "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",
+      "Container": "teammodelos"
+    },
+    "CosmosDB": {
+      "ConnectionString": "https://192.168.8.128:8081",
+      "ConnectionKey": "ddwAeGSf8Lsf1kxPXmdqnyzzi3CkJ0KW2BTPZ7Zq1N7qbJic5j7AaQ+WbF86F3rnzuDgGM1yg8O7BUFo93iA8w==",
+      "Database": "TEAMModelOS",
+      "CollectionThroughput": 400,
+      "ScanModel": [ "TEAMModelOS.Service" ]
+    },
+    "Redis": {
+      "ConnectionString": "106.12.23.251:6379,password=habook,ssl=false,abortConnect=False,defaultDatabase=13,writeBuffer=10240,poolsize=50,prefix=habook:"
+    }
+  },
+  "HaBookAuth": {
+    "TeamModelRegistUrl": "https://account.habookaclass.biz/regist?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "TeamModelLoginUrl": "https://account.habookaclass.biz/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJsb2dpbiIsImF1ZCI6ImNoZW5nZHVMb2dpbiIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYxMzUwNDcsIm5iZiI6MTUzNjEzNTA0NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.F4AnkbJrMRoZvJ6SC-lqZEYIYSoq5x8lvX6_a3YqSgM&callback=",
+    "AccountUrl": "https://api.habookaclass.biz/account",
+    "ServiceUrl": "https://api.habookaclass.biz/service",
+    "UserInfoKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJpZCIsImF1ZCI6ImNoZW5nZHVJZCIsImlzcyI6Imh0dHBzOi8vYXBpLmhhYm9va2FjbGFzcy5iaXoiLCJpYXQiOjE1MzYwNTIzNjcsIm5iZiI6MTUzNjA1MjM2NywiZXhwIjoxNTY3NTU1MjAwLCJpZHAiOiJIYWJvb2sgQ29yZVNlcnZpY2UifQ.RGKDVtwFEp4OBctlHOuF6yqyI21fTz4cinCxjFCxkSQ",
+    "SchoolCodeKey": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzY2hvb2xDb2RlIiwiYXVkIjoiY2hlbmdkdVNjaG9vbENvZGUiLCJpc3MiOiJodHRwczovL2FwaS5oYWJvb2thY2xhc3MuYml6IiwiaWF0IjoxNTM2MDUyNDI3LCJuYmYiOjE1MzYwNTI0MjcsImV4cCI6MTU2NzU1NTIwMCwiaWRwIjoiSGFib29rIENvcmVTZXJ2aWNlIn0.8m5VH3Nz4N9EdMz8AexTOEuDVitcJZFKy9DfW_UQkSY",
+    "SmsKey": "Basic ZmYwMWM0YTJjODdmZmNkYTUyNjhmMDEwOmE0YTE5YTVjNTU2ZWVhZTNjZmZhNTI0Mg=="
   }
 }

+ 1 - 0
TEAMModelOS.Grpc/appsettings.json

@@ -6,6 +6,7 @@
       "Microsoft.Hosting.Lifetime": "Information"
     }
   },
+  "urls": "https://*:5000",
   "AllowedHosts": "*",
   "Kestrel": {
     "EndpointDefaults": {

+ 10 - 10
TEAMModelOS.SDK/Module/Grpc/Common/Internal/ProtoGenerator.cs

@@ -63,7 +63,7 @@ namespace Grpc.Extension.Common.Internal
         /// <summary>
         /// 生成grpc的message的proto内容
         /// </summary>
-        private static string GenGrpcMessageProto(string pkgName,string srvName, List<string> msgProtos, bool spiltProto)
+        private static string GenGrpcMessageProto(string pkgName, List<string> msgProtos, bool spiltProto)
         {
             var sb = new StringBuilder();
             if (spiltProto)
@@ -71,11 +71,11 @@ namespace Grpc.Extension.Common.Internal
                 sb.AppendLine("syntax = \"proto3\";");
                 if (!string.IsNullOrWhiteSpace(GrpcExtensionsOptions.Instance.ProtoNameSpace))
                 {
-                    sb.AppendLine("option csharp_namespace = \"" + GrpcExtensionsOptions.Instance.ProtoNameSpace.Trim() + "." + srvName + "\";");
+                    sb.AppendLine("option csharp_namespace = \"" + GrpcExtensionsOptions.Instance.ProtoNameSpace.Trim() + "\";");
                 }
                 if (!string.IsNullOrWhiteSpace(pkgName))
                 {
-                    sb.AppendLine($"package {pkgName.Trim() + "." + srvName};");
+                    sb.AppendLine($"package {pkgName.Trim()};");
                 }
             }
             sb.AppendLine();
@@ -127,11 +127,11 @@ namespace Grpc.Extension.Common.Internal
             sb.AppendLine("syntax = \"proto3\";");
             if (!string.IsNullOrWhiteSpace(GrpcExtensionsOptions.Instance.ProtoNameSpace))
             {
-                sb.AppendLine("option csharp_namespace = \"" + GrpcExtensionsOptions.Instance.ProtoNameSpace.Trim() +"."+ srvName + "\";");
+                sb.AppendLine("option csharp_namespace = \"" + GrpcExtensionsOptions.Instance.ProtoNameSpace.Trim() + "\";");
             }
             if (!string.IsNullOrWhiteSpace(pkgName))
             {
-                sb.AppendLine($"package {pkgName.Trim()+"."+ srvName};");
+                sb.AppendLine($"package {pkgName.Trim()};");
             }
             if (spiltProto)
             {
@@ -159,7 +159,7 @@ namespace Grpc.Extension.Common.Internal
                         responseName = "stream " + responseName;
                         break;
                 }
-                ProtoCommentGenerator.AddServiceComment(q,sb);
+                ProtoCommentGenerator.AddServiceComment(q, sb);
                 sb.AppendLine(string.Format(template, q.MethodName, requestName, responseName) + ";" + Environment.NewLine);
             });
 
@@ -169,7 +169,7 @@ namespace Grpc.Extension.Common.Internal
         /// <summary>
         /// 生成proto文件
         /// </summary>
-        public static void Gen(string dir,bool spiltProto)
+        public static void Gen(string dir, bool spiltProto)
         {
             if (ProtoInfo.Methods == null || ProtoInfo.Methods.Count == 0) return;
             if (!Directory.Exists(dir))
@@ -186,7 +186,7 @@ namespace Grpc.Extension.Common.Internal
 
                 #region message
                 var protoName = srv;//grp.Key;
-                var msgProtoName = $"{protoName}{(spiltProto ? ".message":"")}.proto";
+                var msgProtoName = $"{protoName}{(spiltProto ? ".message" : "")}.proto";
                 var msgProtoPath = Path.Combine(dir, msgProtoName);
                 var msgProtos = new List<string>();
                 var rqNames = grp.ToList().Select(q => q.RequestName).ToList();
@@ -196,11 +196,11 @@ namespace Grpc.Extension.Common.Internal
                 {
                     msgProtos.Add(GetProto(n));
                 }
-                var msgProtoContent = GenGrpcMessageProto(pkg ,srv, msgProtos, spiltProto);
+                var msgProtoContent = GenGrpcMessageProto(pkg, msgProtos, spiltProto);
                 #endregion
 
                 #region service
-                var srvProtoName = $"{protoName}{(spiltProto ? ".service":"")}.proto";
+                var srvProtoName = $"{protoName}{(spiltProto ? ".service" : "")}.proto";
                 var srvProtoPath = Path.Combine(dir, srvProtoName);
                 var methodInfos = grp.ToList();
                 var srvProtoContent = GenGrpcServiceProto(msgProtoName, pkg, srv, methodInfos, spiltProto);

+ 3 - 1
TEAMModelOS.Service/TEAMModelOS.Service.csproj

@@ -9,5 +9,7 @@
   <ItemGroup>
     <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
   </ItemGroup>
-
+  <ItemGroup>
+    <PackageReference Include="protobuf-net" Version="2.4.6" />
+  </ItemGroup>
 </Project>

+ 11 - 5
TEAMModelOS.sln

@@ -9,7 +9,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS", "TEAMModelOS\
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Service", "TEAMModelOS.Service\TEAMModelOS.Service.csproj", "{04508AB6-CD54-46B4-B96D-9672EB66761B}"
 EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Grpc", "TEAMModelOS.Grpc\TEAMModelOS.Grpc.csproj", "{AE65CCDD-DD2B-46E9-8D65-82E09C46A4C0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TEAMModelOS.Grpc", "TEAMModelOS.Grpc\TEAMModelOS.Grpc.csproj", "{BD5B38BD-F2B8-4EB7-B060-9D757DC4D430}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TEAMModelGrpc", "TEAMModelGrpc\TEAMModelGrpc.csproj", "{7E4E8BEA-D487-45B5-A46D-16610B14CBD2}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -29,10 +31,14 @@ Global
 		{04508AB6-CD54-46B4-B96D-9672EB66761B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{04508AB6-CD54-46B4-B96D-9672EB66761B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{04508AB6-CD54-46B4-B96D-9672EB66761B}.Release|Any CPU.Build.0 = Release|Any CPU
-		{AE65CCDD-DD2B-46E9-8D65-82E09C46A4C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{AE65CCDD-DD2B-46E9-8D65-82E09C46A4C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{AE65CCDD-DD2B-46E9-8D65-82E09C46A4C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{AE65CCDD-DD2B-46E9-8D65-82E09C46A4C0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{BD5B38BD-F2B8-4EB7-B060-9D757DC4D430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{BD5B38BD-F2B8-4EB7-B060-9D757DC4D430}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{BD5B38BD-F2B8-4EB7-B060-9D757DC4D430}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{BD5B38BD-F2B8-4EB7-B060-9D757DC4D430}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7E4E8BEA-D487-45B5-A46D-16610B14CBD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7E4E8BEA-D487-45B5-A46D-16610B14CBD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7E4E8BEA-D487-45B5-A46D-16610B14CBD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7E4E8BEA-D487-45B5-A46D-16610B14CBD2}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE

+ 1 - 1
TEAMModelOS/ClientApp/src/view/Home.vue

@@ -67,7 +67,7 @@
                         </template>
                         <MenuItem name="3-1" to="/home/syllabus">课纲管理<span style="color:aqua;margin-left:5px;">√</span></MenuItem>
                         <MenuItem name="3-3" to="/home/teachcontent">内容管理<span style="color:aqua;margin-left:5px;">√</span></MenuItem>
-                        <MenuItem name="3-4" to="/home/evaluation/testPaperList">题目/库管理<span style="color:aqua;margin-left:5px;">待完善</span></MenuItem>
+                        <MenuItem name="3-4" to="/home/evaluation/testPaperList">题目/库管理<span style="color:aqua;margin-left:5px;"></span></MenuItem>
                         <MenuItem name="3-5" to="/home/knowledge">知识点管理<span style="color:aqua;margin-left:5px;">√</span></MenuItem>
                     </Submenu>
                     <Submenu name="learnActivity">

+ 7 - 0
TEAMModelOS/ClientApp/src/view/selflearning/CreateLearnUnit.less

@@ -181,4 +181,11 @@
     display: inline-block;
     vertical-align: sub;
     margin-right: 5px;
+}
+.btn-save {
+    color: rgb(107, 223, 195);
+    float: right;
+    cursor: pointer;
+    margin-top: 6px;
+    margin-right: 40px;
 }

+ 7 - 4
TEAMModelOS/ClientApp/src/view/selflearning/CreateLearnUnit.vue

@@ -4,10 +4,11 @@
             <span class="name-label">名称:</span>
             <Input v-model="learnUnit.name" placeholder="请输入名称..." :class="checkName ? '':'my-error-style'" style="width: 300px" @on-blur="checkUnitName" />
             <span style="color:#ed4014;margin-left:15px;" v-show="!checkName">名称不能为空</span>
-            <span class="header-btn-save" @click="saveLearnUnitData()">
+            <!--<span class="header-btn-save" @click="saveLearnUnitData()">
                 <Icon type="ios-albums-outline" color="#1CD0A1" style="margin-right:5px;" />
                 保存数据
-            </span>
+            </span>-->
+            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveLearnUnitData">保存数据</Button>
         </div>
         <div class="learn-unit-main">
             <Split v-model="split1">
@@ -82,6 +83,7 @@
     export default {
         data() {
             return {
+                isLoading: false,
                 sasString: '',
                 previewFile: {},
                 previewStatus: false,
@@ -138,7 +140,7 @@
                     this.checkName = false
                 } else {
                     this.checkName = true
-                    console.log(this.learnUnit)
+                    this.isLoading = true
                     let requestData = {
                         id: this.learnUnit.id,
                         name: this.learnUnit.name,
@@ -154,9 +156,10 @@
                             } else {
                                 this.$Message.error('API ERROR!')
                             }
+                            this.isLoading = false
                         },
                         (err) => {
-
+                            this.isLoading = false
                         }
                     )
 

+ 7 - 0
TEAMModelOS/ClientApp/src/view/selflearning/CreateOrderLearn.less

@@ -250,4 +250,11 @@
 }
 .content-file-item{
     margin-bottom:4px;
+}
+.btn-save {
+    color: rgb(107, 223, 195);
+    float: right;
+    cursor: pointer;
+    margin-top: 6px;
+    margin-right: 40px;
 }

+ 8 - 5
TEAMModelOS/ClientApp/src/view/selflearning/CreateOrderLearn.vue

@@ -4,10 +4,11 @@
             <span class="order-learn-title">
                 创建编序式学习
             </span>
-            <span class="header-btn-save" @click="saveData()">
+            <!--<span class="header-btn-save" @click="saveData()">
                 <Icon type="ios-albums-outline" color="#1CD0A1" style="margin-right:5px;" />
                 保存数据
-            </span>
+            </span>-->
+            <Button class="btn-save" type="text" :loading="isLoading" ghost icon="ios-albums-outline" @click="saveData">保存评测</Button>
         </div>
         <div class="order-learn-main">
             <!-- 基础信息表单 -->
@@ -186,7 +187,7 @@
         },
         data() {
             return {
-                
+                isLoading: false,
                 goToManageStatus: false,
                 demoLoginInfo: {
                     user: 'admin',
@@ -331,21 +332,23 @@
             saveData() {
                 let check = this.checkData()
                 if (check) {
+                    this.isLoading = true
                     this.orderLearnInfo.creator = this.demoLoginInfo.TEAMModelId
                     this.orderLearnInfo.scopeCode = this.demoLoginInfo.TEAMModelId
                     this.orderLearnInfo.type = '1'//教学情境
+                    this.orderLearnInfo.target = ['三年级五班']//学习对象
                     this.$api.learnActivity.SaveOrderLearn(this.orderLearnInfo).then(
                         res => {
                             if (res.error == null) {
                                 this.orderLearnInfo.id = res.result.data.id
-                                //this.$Message.success('数据保存成功!')
                                 this.goToManageStatus = true
                             } else {
                                 this.$Message.error('API ERROR!')
                             }
+                            this.isLoading = false
                         },
                         err => {
-
+                            this.isLoading = false
                         }
                     )
                 } else {

+ 28 - 1
TEAMModelOS/ClientApp/src/view/selflearning/ManageOrderLearn.less

@@ -128,9 +128,36 @@
                 background: #333333;
             }
 
-            .order-learn-file-item {
+            .order-learn-file-wrap {
                 color: white;
                 margin-top: 5px;
+
+                .order-learn-file-item {
+                    margin-bottom: 2px;
+                    font-size:16px;
+                    .file-item-action {
+                        display: none;
+                        float: right;
+                        padding-right: 20px;
+                    }
+
+                    .action-icon{
+                        margin-right:10px;
+                        font-size:16px;
+                        cursor:pointer;
+                        &:hover{
+                            color:aqua;
+                        }
+                    } 
+                    &:hover {
+                        background: #404040;
+                        padding-left: 5px;
+                        border-radius: 5px;
+                    }
+                    &:hover .file-item-action{
+                        display:inline-block;
+                    }
+                }
             }
         }
 

+ 13 - 4
TEAMModelOS/ClientApp/src/view/selflearning/ManageOrderLearn.vue

@@ -119,11 +119,16 @@
                                             </p>
                                             <div style="margin-bottom:30px;">
                                                 <NoData v-if="orderLearnList.length == 0"></NoData>
-                                                <div v-if="orderLearnList.length > 0" class="order-learn-file-item">
+                                                <div v-if="orderLearnList.length > 0" class="order-learn-file-wrap">
                                                     <NoData v-if="orderLearnList[currentLearnIndex].steps[currentStepIndex].resource.length == 0"></NoData>
-                                                    <p v-for="(item,index) in orderLearnList[currentLearnIndex].steps[currentStepIndex].resource">
-                                                        {{item.fileName}}
-                                                    </p>
+                                                    <div class="order-learn-file-item" v-for="(item,index) in orderLearnList[currentLearnIndex].steps[currentStepIndex].resource">
+                                                        <span>{{item.fileName}}</span>
+                                                        <span class="file-item-action">
+                                                            <Icon type="md-download" class="action-icon" title="下载"  @click="downloadFile(item)"/>
+                                                            <Icon v-if="item.type == 'video' || item.type == 'picture' || item.extension == 'pdf'" type="md-eye" class="action-icon" title="预览" @click="clickToPreview(item)" />
+                                                            <!--<Icon type="md-close" class="action-icon" title="删除" />-->
+                                                        </span>
+                                                    </div>
                                                 </div>
 
                                             </div>
@@ -169,6 +174,7 @@
         },
         data() {
             return {
+                sasString:'',
                 editStatus: false,
                 split1: 0.2,
                 split2: 0.2,
@@ -185,6 +191,9 @@
             }
         },
         methods: {
+            downloadFile(item) {
+                window.location.href = item.blobUrl + this.sasString
+            },
             confirmEdit() {
                 let orderLearnInfo = this.orderLearnList[this.currentLearnIndex]
                 

+ 22 - 4
TEAMModelOS/ClientApp/src/view/selflearning/ManageUnit.vue

@@ -12,9 +12,9 @@
         <div class="unit-main-wrap">
             <div class="unit-main-header">
                 <span class="unit-main-label">自学资源</span>
-                <span v-if="type == 1" class="unit-main-action" @click="editUnit"><Icon type="ios-create-outline" size="20"/>编辑内容</span>
+                <span v-if="type == 1" class="unit-main-action" @click="editUnit"><Icon type="ios-create-outline" size="20" />编辑内容</span>
                 <span v-if="type == 1" class="unit-main-action"><Icon type="ios-send" size="20" />发布内容</span>
-                <span v-if="type == 0" class="unit-main-action" @click="chooseUnit"><Icon type="md-checkmark" size="20" style="margin-right:5px;"/>选择</span>
+                <span v-if="type == 0" class="unit-main-action" @click="chooseUnit"><Icon type="md-checkmark" size="20" style="margin-right:5px;" />选择</span>
             </div>
             <div class="unit-content-wrap" v-if="unitList.length > 0">
                 <vuescroll>
@@ -36,8 +36,8 @@
                                 <span>{{item.fileName}}</span>
                             </div>
                             <span class="content-file-item-action">
-                                <Icon type="md-download" class="action-icon" title="下载" />
-                                <Icon type="md-eye" class="action-icon" title="预览" />
+                                <Icon type="md-download" class="action-icon" title="下载" @click="downloadFile(item)" />
+                                <Icon v-if="item.type == 'video' || item.type == 'picture' || item.extension == 'pdf'" type="md-eye" class="action-icon" title="预览" @click="clickToPreview(item)" />
                                 <Icon type="md-close" class="action-icon" title="删除" />
                             </span>
                         </div>
@@ -59,6 +59,14 @@
                @on-ok="confirmEdit">
             <p>确认跳转到最小单元编辑页面?</p>
         </Modal>
+        <Modal v-model="previewStatus" :title="previewFile.fileName" width="800px" class="dark-iview-modal">
+            <video v-if="previewFile.type == 'video'" id="previewVideo" :src="previewFile.blobUrl+sasString" width="780" controls="controls">
+                {{$t('teachContent.tips8')}}
+            </video>
+            <img v-if="previewFile.type == 'picture'" :src="previewFile.blobUrl+sasString" width="780" style="border-radius:5px;" />
+            <embed v-if="previewFile.type == 'document'" :src="previewFile.blobUrl+sasString" width="780" height="600" />
+            <div slot="footer"></div>
+        </Modal>
     </div>
 </template>
 <script>
@@ -78,6 +86,9 @@
         },
         data() {
             return {
+                previewStatus: false,
+                previewFile: {},
+                sasString:'',
                 editUnitStatus: false,
                 isLoading: false,
                 unitList: [],
@@ -85,6 +96,13 @@
             }
         },
         methods: {
+            clickToPreview(file) {
+                this.previewStatus = true
+                this.previewFile = file
+            },
+            downloadFile(item) {
+                window.location.href = item.blobUrl + this.sasString
+            },
             chooseUnit() {
                 this.$emit('chooseUnit',this.unitList[this.currentUnitIndex])
             },