| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 | package handlerimport (	"fmt"	"git.ikuban.com/server/kratos-utils/v2/http/middleware"	ku_annotations "git.ikuban.com/server/kubanapis/kuban/api/annotations"	"github.com/go-kratos/kratos/v2/transport/http"	openapi_v3 "github.com/google/gnostic/openapiv3"	"github.com/jhump/protoreflect/desc"	"github.com/jhump/protoreflect/grpcreflect"	"google.golang.org/genproto/googleapis/api/annotations"	"google.golang.org/grpc"	"google.golang.org/protobuf/proto")func RegisterRoute(s *http.Server, srv any, svcDesc grpc.ServiceDesc) {	r := s.Route("/api/")	// 加载完整的服务描述符	fullSvcDesc, err := grpcreflect.LoadServiceDescriptor(&svcDesc)	if err != nil {		panic(fmt.Sprintf("加载服务描述符失败 err:%v", err))	}	// 注册一元方法handler	for _, md := range svcDesc.Methods {		// 获取方法option		option := GetOptionByServiceDescriptor(fullSvcDesc, svcDesc.ServiceName, md.MethodName)		// 跳过不需要生成http方法的		if !option.GenHttp {			continue		}		// 注册http接口		r.POST(option.Path, unaryHandler(srv, md, option))	}	// 注册流式方法handler	for _, std := range svcDesc.Streams {		// 获取方法option		option := GetOptionByServiceDescriptor(fullSvcDesc, svcDesc.ServiceName, std.StreamName)		// 跳过不需要生成http方法的		if !option.GenHttp {			continue		}		switch {		case std.ClientStreams && std.ServerStreams:			// 双向流		case std.ClientStreams && !std.ServerStreams:			// 客户端流		case !std.ClientStreams && std.ServerStreams:			// 服务端流			r.POST(option.Path, serverStreamHandler(srv, std, option))		}	}}func GetOptionByServiceDescriptor(sd *desc.ServiceDescriptor, serviceName, methodName string) *middleware.Option {	// 获取方法描述符	md := sd.FindMethodByName(methodName)	if md == nil {		panic(fmt.Sprintf("未找到方法描述符 service:%v, method:%v", serviceName, methodName))	}	// option	option := &middleware.Option{}	// 获取方法option	methodOptions := md.GetMethodOptions()	operation := proto.GetExtension(methodOptions, openapi_v3.E_Operation).(*openapi_v3.Operation)	if operation == nil {		// 跳过不需要生成http方法的		option.GenHttp = false		return option	}	option.GenHttp = true	// 不需要认证的	if len(operation.Security) == 0 {		option.NotAuth = true	}	// 解析自定义option [操作记录]	customOptions := proto.GetExtension(methodOptions, ku_annotations.E_Options).(*ku_annotations.Options)	if customOptions.GetOperationRecord().GetEnabled() {		option.OperationRecord = true	}	// 路由	rule := proto.GetExtension(methodOptions, annotations.E_Http).(*annotations.HttpRule)	if rule != nil {		switch httpRule := rule.GetPattern().(type) {		case *annotations.HttpRule_Post:			option.Path = httpRule.Post		}	}	if option.Path == "" {		option.Path = fmt.Sprintf("/%s/%s", serviceName, methodName)	}	return option}
 |