Browse Source

Merge branch 'develop3.0' of http://106.12.23.251:10080/TEAMMODEL/TEAMModelOS into develop3.0

CrazyIter 5 năm trước cách đây
mục cha
commit
18dcc6f488

+ 72 - 0
TEAMModelOS.GRPC/Startup.cs

@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text.Json;
+using System.Threading.Tasks;
+using Grpc.Extension.Abstract;
+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;
+using TEAMModelOS.SDK.Module.AzureBlob.Configuration;
+using TEAMModelOS.SDK.Module.AzureCosmosDB.Configuration;
+using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.SDK.Module.AzureTable.Implements;
+using TEAMModelOS.SDK.Module.AzureTable.Interfaces;
+
+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.
+        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+        {
+            if (env.IsDevelopment())
+            {
+                app.UseDeveloperExceptionPage();
+            }
+
+            app.UseRouting();
+
+            app.UseEndpoints(endpoints =>
+            {
+                //endpoints.MapGrpcService<GreeterService>();
+
+                endpoints.MapGet("/", async context =>
+                {
+                    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所在程序集下的IGrpcService)
+            app.UseGrpcExtensions<KnowledgeService>(options =>
+            {
+                //CodeFirst配制
+                options.GlobalPackage = "TMDOSGRPC";
+                options.ProtoNameSpace = "TMDOSGRPC";
+            })
+            //CodeFirst生成proto
+            .UseProtoGenerate("Protos", false);
+        }
+    }
+}

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

@@ -0,0 +1,33 @@
+<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>
+    <None Remove="Protos\KnowledgeService.proto" />
+  </ItemGroup>
+  <ItemGroup>
+    <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>
+    <Protobuf Include="Protos\KnowledgeService.proto" GrpcServices="Server" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Services\Core\" />
+    <Folder Include="Services\Courses\" />
+    <Folder Include="Services\Exam\" />
+    <Folder Include="Services\Learn\" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\TEAMModelOS.SDK\TEAMModelOS.SDK.csproj" />
+    <ProjectReference Include="..\TEAMModelOS.Service\TEAMModelOS.Service.csproj" />
+  </ItemGroup>
+</Project>

+ 69 - 0
TEAMModelOS.GRPC/appsettings.Development.json

@@ -0,0 +1,69 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Debug",
+      "System": "Information",
+      "Grpc": "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=="
+    }
+  }
+}

+ 67 - 0
TEAMModelOS.GRPC/appsettings.json

@@ -0,0 +1,67 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft": "Warning",
+      "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=="
+    }
+  }
+}

+ 20 - 0
TEAMModelOS.Grpc/Models/Dtos/RequestDict.cs

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

+ 16 - 0
TEAMModelOS.Grpc/Models/Dtos/ResponseList.cs

@@ -0,0 +1,16 @@
+//using ProtoBuf;
+//using System;
+//using System.Collections.Generic;
+//using System.Linq;
+//using System.Threading.Tasks;
+
+//namespace TEAMModelOS.GRPC.Models.Dtos
+//{
+//    [ProtoContract]
+//    public class ResponseList<T>
+//    {
+
+//        [ProtoMember(1)]
+//        public List<T> response { get; set; }
+//    }
+//}

+ 31 - 0
TEAMModelOS.Grpc/Protos/KnowledgeService.proto

@@ -0,0 +1,31 @@
+syntax = "proto3";
+option csharp_namespace = "TMDOSGRPC.KnowledgeService";
+package TMDOSGRPC.KnowledgeService;
+
+
+service KnowledgeService {
+   rpc FinKnowledge1(RequestDict) returns(stream Knowledge);
+
+}
+
+
+
+message RequestDict {
+   //查询dict
+   map<string,string> dict = 1;
+}
+
+message Knowledge {
+   string id = 1;
+   int32 type = 2;
+   string name = 3;
+   string alias = 4;
+   string subjectCode = 5;
+   string scopeCode = 6;
+   int32 order = 7;
+   int32 status = 8;
+   repeated string points = 9;
+   string knowledgeId = 10;
+   int32 source = 11;
+   string period = 12;
+}

+ 61 - 0
TEAMModelOS.Grpc/Services/Syllabus/KnowledgeService.cs

@@ -0,0 +1,61 @@
+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 TEAMModelOS.SDK.Helper.Common.JsonHelper;
+using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
+using TEAMModelOS.Service.Models.Syllabus;
+using TEAMModelOS.GRPC.Models.Dtos;
+
+
+namespace TEAMModelOS.GRPC.Services.Syllabus
+{
+    public class KnowledgeService : IGrpcService
+    {
+        public IAzureCosmosDBV3Repository cosmosDBV3Repository;
+
+        public KnowledgeService(IAzureCosmosDBV3Repository cosmosDBV3Repository)
+        {
+            this.cosmosDBV3Repository = cosmosDBV3Repository;
+        }
+
+        //[Authorize]
+        public async Task FinKnowledge1(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);
+        //}
+
+    }
+}

+ 138 - 0
TEAMModelOS.Grpc/TEAMModelOS.GRPC.xml

@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>TEAMModelOS.GRPC</name>
+    </assembly>
+    <members>
+        <member name="P:TEAMModelOS.GRPC.Models.Dtos.RequestDict.dict">
+            <summary>
+            查询dict
+            </summary>
+        </member>
+        <member name="T:Helloworld.HelloworldReflection">
+            <summary>Holder for reflection information generated from Protos/helloworld.proto</summary>
+        </member>
+        <member name="P:Helloworld.HelloworldReflection.Descriptor">
+            <summary>File descriptor for Protos/helloworld.proto</summary>
+        </member>
+        <member name="T:Helloworld.HelloRequest">
+            <summary>
+            The request message containing the user's name.
+            </summary>
+        </member>
+        <member name="F:Helloworld.HelloRequest.NameFieldNumber">
+            <summary>Field number for the "name" field.</summary>
+        </member>
+        <member name="T:Helloworld.HelloReply">
+            <summary>
+            The response message containing the greetings
+            </summary>
+        </member>
+        <member name="F:Helloworld.HelloReply.MessageFieldNumber">
+            <summary>Field number for the "message" field.</summary>
+        </member>
+        <member name="T:Helloworld.Greeter">
+            <summary>
+            The greeting service definition.
+            </summary>
+        </member>
+        <member name="P:Helloworld.Greeter.Descriptor">
+            <summary>Service descriptor</summary>
+        </member>
+        <member name="T:Helloworld.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)">
+            <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: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)">
+            <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)">
+            <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>

+ 7 - 0
TEAMModelOS.Service/Models/Learn/LeanProcess.cs

@@ -23,8 +23,15 @@ namespace TEAMModelOS.Service.Models.Learn
         
         public string id { get; set; }
         public string name { get; set; }
+
         [Required(ErrorMessage = "{0} 必须填写")]
         public string subjectCode { get; set; }
+
+        /// <summary>
+        /// 学段code
+        /// </summary>
+        [Required(ErrorMessage = "{0} 必须填写")]
+        public string periodCode { get; set; }
         /// <summary>
         /// 活动介绍
         /// </summary>

+ 14 - 0
TEAMModelOS.Service/Models/Syllabus/Knowledge.cs

@@ -1,4 +1,5 @@
 using Newtonsoft.Json;
+using ProtoBuf;
 using System;
 using System.Collections.Generic;
 using System.ComponentModel.DataAnnotations;
@@ -10,22 +11,27 @@ using TEAMModelOS.SDK.Module.AzureCosmosDBV3;
 namespace TEAMModelOS.Service.Models.Syllabus
 {
     [CosmosDB(RU = 400, Name = "Knowledge", Cache = true)]
+    [ProtoContract]
     public class Knowledge: ID
     {
+        [ProtoMember(1)]
         public string id { get; set; }
         /// <summary>
         /// 标记为知识块,0=知识块 ,1 知识点
         /// </summary>
+        [ProtoMember(2)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public int type { get; set; } = 0;
         /// <summary>
         /// 名称
         /// </summary>
+        [ProtoMember(3)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public string name { get; set; }
         /// <summary>
         /// 描述
         /// </summary>
+        [ProtoMember(4)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public string alias { get; set; }
 
@@ -33,29 +39,34 @@ namespace TEAMModelOS.Service.Models.Syllabus
         /// 学科
         /// </summary>
         ///[Required(ErrorMessage = "{0} 必须填写")]
+        [ProtoMember(5)]
         public string subjectCode { get; set; }
 
         /// <summary>
         /// 学校编码 如果是教师私人知识点为醍摩豆id 否则为学校编码 
         /// </summary>
         [Required(ErrorMessage = "{0} 必须填写")]
+        [ProtoMember(6)]
         [PartitionKey]
         public string scopeCode { get; set; }
 
 
 
+        [ProtoMember(7)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public int order { get; set; }
 
         /// <summary>
         /// 删除状态0 删除 1 有效
         /// </summary>
+        [ProtoMember(8)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public int status { get; set; } = 1;
 
         /// <summary>
         /// 知识点 id
         /// </summary>
+        [ProtoMember(9)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public List<string> points { get; set; }
 
@@ -63,12 +74,14 @@ namespace TEAMModelOS.Service.Models.Syllabus
         /// <summary>
         ///  来自于标准表 Rowkey
         /// </summary>
+        [ProtoMember(10)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public string knowledgeId { get; set; }
 
         /// <summary>
         /// 0 标准,1自建,2.....
         /// </summary>
+        [ProtoMember(11)]
         [Required(ErrorMessage = "{0} 必须填写")]
         public int source { get; set; }
 
@@ -76,6 +89,7 @@ namespace TEAMModelOS.Service.Models.Syllabus
         /// 学段 私有的没有学段
         /// </summary>
         ///[Required(ErrorMessage = "{0} 必须填写")]
+        [ProtoMember(12)]
         public string period { get; set; }
 
         ///// <summary>

+ 2 - 2
TEAMModelOS/ClientApp/src/components/student-analysis/total/BaseGeniusLine.vue

@@ -24,8 +24,8 @@
 
                 myLine.showLoading({
                     text: '',
-                    color: '#4cbbff',
-                    textColor: '#4cbbff',
+                    color: '#E6E6E6',
+                    textColor: '#E4E9EC',
                     maskColor: 'rgba(0, 0, 0, 0)'
                 })
 

+ 15 - 0
TEAMModelOS/ClientApp/src/components/student-analysis/total/map.js

@@ -0,0 +1,15 @@
+"5a569451-d7b6-4bc5-85dc-4c97ba593090", "97752929-bee6-458e-b5ae-af16ee73a1e9",
+    "b32dcb15-9f13-4e8f-9f65-80e55e3b257d", "5160a86b-2d44-466f-bd82-ed08148f6607",
+    "9e6a3b59-bdeb-4b21-90ec-903ef9847864", "6d1f223d-a84e-4fab-b015-fe1c4298834b",
+    "72571322-43d9-4777-b3b1-a6a5a4bf4e10", "bf4707a6-f541-46b9-85b2-82aa6077ba27",
+    "9dd91708-be01-4947-850c-77b88e7cf2ad", "24d9f39f-906a-4ca6-bc4f-8f9307d51d5a",
+    "4acee7e2-434c-4257-9331-8c42fba14a3b", "170125f4-4cfc-40eb-aae4-7a82840a6297",
+    "6b14df14-17ae-4f47-a1e4-16738268feba", "a9c1ada9-232f-4993-bf63-3c279e5ecaac",
+    "4ff7b031-a45c-4b02-921e-933be73bb38a", "a96ebded-aeb0-42c8-ab90-8b1ab8a4a489",
+    "e3564799-3b9a-4b5d-a904-f09565f98890", "64b4326f-1f76-4c7c-8fb7-5940894e2205",
+    "4e43d507-8af1-4b21-b09e-7fe8533104e8", "25032d80-b88c-42c1-8ffd-1a30815859aa",
+    "b1baff75-fdf9-4020-acfb-af6497017f4b", "c6e8bdaf-9738-48f6-bd7f-5bc6d6444684",
+    "d75000f7-168a-4521-b056-780ef38114cc", "f6c768e8-12ea-445c-8df1-750736294a80",
+    "5ac2805d-b31d-44a3-9058-1239d5557270", "49512c48-f38a-452e-8bb9-170728cb271e",
+    "57088641-14d1-498d-ae8e-61627e0d8e4a", "2222f52f-cc3f-4ac3-96b8-638078455f64",
+    "1687d096-4d58-4828-97de-d31e23784b36", "45ae3d97-cd76-4c53-a821-e220367eb2c2" 

+ 5 - 3
TEAMModelOS/ClientApp/src/store/module/totalAnalysis.js

@@ -178,7 +178,7 @@ export default {
                     console.log('Cache-Achievement')
                     r(context.state.achievementData)
                 } else {
-                    apiTools.totalAnalysis.getAchievementData({ 'ExamCode': '1371cb0c-6c72-4c1c-868a-aac00e74a0fb' }).then(res => { // api请求
+                    apiTools.totalAnalysis.getAchievementData({ 'examCode': '1371cb0c-6c72-4c1c-868a-aac00e74a0fb' }).then(res => { // api请求
                         context.commit('getAchievementData', res.result.data) // 提交到vuex保存数据
                         context.commit('updateCurSubject', res.result.data.average.datas.map(item => item.name)[2]) // 提交到vuex保存数据
                         console.log('API-Achievement')
@@ -242,7 +242,8 @@ export default {
             let params = {
                 // Subject: context.state.currentSubject
                 subjectCode: 'Subject_Math',
-                scopeCode: 'qcs',
+                scopeCode: '1371cb0c-6c72-4c1c-868a-aac00e74a0fb',
+                schoolCode:'qcs',
                 examCode: '1371cb0c-6c72-4c1c-868a-aac00e74a0fb'
             }
             return new Promise((r, j) => {
@@ -267,8 +268,9 @@ export default {
             let params = {
                 // Subject: context.state.currentSubject
                 subjectCode: 'Subject_Math',
-                scopeCode: 'qcs',
+                scopeCode: '1371cb0c-6c72-4c1c-868a-aac00e74a0fb',
                 type: '5',
+                schoolCode: 'qcs',
                 examCode: '1371cb0c-6c72-4c1c-868a-aac00e74a0fb'
             }
             return new Promise((r, j) => {

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/EvaluationList/TotalIndex.vue

@@ -67,7 +67,7 @@
                             <div class="section-box">
                                 <div class="exam-data-item block-item">
                                     <div class="item-content">
-                                        <div class="item-num">16</div>
+                                        <div class="item-num">{{ examList.length }}</div>
                                         <div class="item-name">{{$t('totalAnalysis.ti_text12')}}</div>
                                     </div>
                                 </div>
@@ -305,7 +305,7 @@
 
             // 获取评测列表
             getExamList() {
-                this.$api.totalAnalysis.getExamList({ schoolCode: 'qcs',scopeCode: 'qcs' }).then(res => { // api请求
+                this.$api.totalAnalysis.getExamList({ scopeCode: 'qcs' }).then(res => { // api请求
                     this.examList = res.result.data
                     this.originList = res.result.data
                     this.searchList = this.examList.length ? this.examList.map(item => item.name) : []

+ 2 - 2
TEAMModelOS/ClientApp/src/view/student-analysis/total-analysis/index.vue

@@ -259,7 +259,7 @@
 
             // 如果路由跳转到成绩分析页面带有考试序号参数则跳转到当前考试
             if (examIndex || examIndex === 0) {
-                this.$api.totalAnalysis.getExamList({ Code: 'qcs' }).then(res => { // api请求
+                this.$api.totalAnalysis.getExamList({ scopeCode: 'qcs' }).then(res => { // api请求
                     this.currentExamItem = res.result.data[examIndex]
                     console.log(this.currentExamItem)
                     this.subjectSplitList = this.currentExamItem.conditions.subject
@@ -271,7 +271,7 @@
                     console.log(err)
                 })
             } else if (!examIndex && examIndex !== 0) { // 如果是首次进入则读取上次考试,如果没有上次考试则默认读取第一个
-                this.$api.totalAnalysis.getExamList({ Code: 'qcs' }).then(res => { // api请求
+                this.$api.totalAnalysis.getExamList({ scopeCode: 'qcs' }).then(res => { // api请求
                     let existExam = JSON.parse(sessionStorage.getItem('c_exam'))
                     let list = res.result.data
                     if (existExam) {

+ 24 - 18
TEAMModelOS/Controllers/Analysis/AchievementController.cs

@@ -450,7 +450,7 @@ namespace TEAMModelOS.Controllers.Analysis
             JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
             List<Dictionary<string, object>> scatterAnalysis = new List<Dictionary<string, object>>();
             //Dictionary<string, object> scatterAnalysis = new Dictionary<string, object>();
-            List<SimpleExam> exams = await azureCosmosDBRepository.FindByDict<SimpleExam>(request.@params);
+            List<ExamResult> exams = await azureCosmosDBRepository.FindByDict<ExamResult>(request.@params);
             Dictionary<string, object> stuMap = new Dictionary<string, object>
             {
                 { "schoolCode", "Habook" }
@@ -474,9 +474,9 @@ namespace TEAMModelOS.Controllers.Analysis
             if (exams.IsNotEmpty())
             {
                 //提取班级信息
-                List<Dictionary<string, int[]>> classToName = exams[0].Classes;
+                List<Dictionary<string, int[]>> classToName = exams[0].classes;
                 //提取学生ID信息
-                List<string> idToName = exams[0].Ids;
+                List<string> idToName = exams[0].ids;
                 exams.ForEach(e =>
                 {
                     Dictionary<string, object> detail = new Dictionary<string, object>
@@ -486,10 +486,10 @@ namespace TEAMModelOS.Controllers.Analysis
                     List<List<string>> datas = new List<List<string>>();
                     Dictionary<string, object> subject = new Dictionary<string, object>
                     {
-                        { "name", e.Subject }
+                        { "name", e.subjectCode }
                     };
-                    double[] point = StringHelper.ListTodouble(e.Point);
-                    double[,] result = StringHelper.ListToDouble(e.Result);
+                    double[] point = StringHelper.ListTodouble(e.point);
+                    double[,] result = StringHelper.ListToDouble(e.result);
                     try
                     {
                         var cdm = new ClouDASMatrix(result, point);
@@ -504,16 +504,16 @@ namespace TEAMModelOS.Controllers.Analysis
                         //需小心的题型
                         List<int[]> careful = cdm.CarefulTopic;
                         int i = 0;
-                        for (int k = e.Ids.Count - 1; k >= 0; k--)
+                        for (int k = e.ids.Count - 1; k >= 0; k--)
                         {
-                            if (e.Ids[k].Equals("0"))
+                            if (e.ids[k].Equals("0"))
                             {
-                                e.Ids.Remove(e.Ids[k]);
+                                e.ids.Remove(e.ids[k]);
                             }
                         }
-                        e.Ids.ForEach(s =>
+                        e.ids.ForEach(s =>
                         {
-                            if (e.Result[i].Sum() != 0)
+                            if (e.result[i].Sum() != 0)
                             {
                                 List<string> info = new List<string>
                                 {
@@ -522,11 +522,11 @@ namespace TEAMModelOS.Controllers.Analysis
                                     sta[i].ToString(),
                                     pass[i].ToString(),
                                     i + 1 + "",
-                                    e.Result[i].Sum().ToString()
+                                    e.result[i].Sum().ToString()
                                 };
                                 int right = 0;
                                 int wrong = 0;
-                                foreach (int p in e.Result[i])
+                                foreach (int p in e.result[i])
                                 {
                                     if (p > 0)
                                     {
@@ -585,21 +585,24 @@ namespace TEAMModelOS.Controllers.Analysis
             JsonRPCResponseBuilder builder = JsonRPCResponseBuilder.custom();
             HashSet<string> classList = new HashSet<string>();
             List<Dictionary<string, object>> exerciseScatter = new List<Dictionary<string, object>>();
-            //Dictionary<string, object> scatterAnalysis = new Dictionary<string, object>();
+            Dictionary<string, object> scatterAnalysis = new Dictionary<string, object>();
             request.@params.TryGetValue("subjectCode", out object subjectCode);
             request.@params.TryGetValue("schoolCode", out object schoolCode);
             request.@params.TryGetValue("examCode", out object examCode);
+            request.@params.TryGetValue("scopeCode", out object scopeCode);
             Dictionary<string, object> sub = new Dictionary<string, object>
             {
-                { "subjectCode",  subjectCode.ToString()}
+                { "subjectCode",  subjectCode.ToString()},
+                { "scopeCode",scopeCode.ToString()}
             };
             Dictionary<string, object> examMap = new Dictionary<string, object>
             {
                 { "subjectCode", subjectCode.ToString()},
-                { "examCode", examCode.ToString()}
+                { "examCode", scopeCode.ToString()},
+                { "schoolCode", schoolCode.ToString()}
             };
             List<ExamResult> exams = await azureCosmosDBRepository.FindByDict<ExamResult>(examMap);
-            List<ExamPaper> paper = await azureCosmosDBRepository.FindByDict<ExamPaper>(sub);
+            List<ExamPaper> paper = await azureCosmosDBRepository.FindByDict<ExamPaper> (sub);
             List<string> key = new List<string>
             {
                 "id",
@@ -801,9 +804,12 @@ namespace TEAMModelOS.Controllers.Analysis
             request.@params.TryGetValue("subjectCode", out object subjectCode);
             request.@params.TryGetValue("schoolCode", out object schoolCode);
             request.@params.TryGetValue("examCode", out object examCode);
+            request.@params.TryGetValue("scopeCode", out object scopeCode);
             Dictionary<string, object> sub = new Dictionary<string, object>
             {
-                { "subjectCode",  subjectCode.ToString()}
+                { "subjectCode",  subjectCode.ToString()},
+                { "scopeCode",scopeCode.ToString()}
+                
             };
             Dictionary<string, object> examMap = new Dictionary<string, object>
             {