feat: coco core support
This commit is contained in:
parent
03a3aae71b
commit
b2ad24762a
|
@ -0,0 +1,61 @@
|
|||
syntax = "proto3";
|
||||
|
||||
package controller;
|
||||
|
||||
option go_package = "./;core";
|
||||
|
||||
|
||||
// @route_group: true
|
||||
// @base_url: /api/file
|
||||
// @gen_to: ./core/file_controller.go
|
||||
service File {
|
||||
// @desc: 列表
|
||||
// @author: Young Xu
|
||||
// @method: GET
|
||||
// @api: /list
|
||||
rpc List (ListReq) returns (ListResp);
|
||||
// @desc: 上传
|
||||
// @author: Young Xu
|
||||
// @method: POST
|
||||
// @api: /upload
|
||||
rpc Upload (UploadReq) returns (UploadResp);
|
||||
// @desc: 删除
|
||||
// @author: Young Xu
|
||||
// @method: POST
|
||||
// @api: /delete
|
||||
rpc Delete (DeleteReq) returns (DeleteResp);
|
||||
// @desc: 下载
|
||||
// @author: Young Xu
|
||||
// @method: GET
|
||||
// @api: /download
|
||||
rpc Download (DownloadReq) returns (DownloadResp);
|
||||
}
|
||||
|
||||
|
||||
message ListReq {}
|
||||
|
||||
message ListResp {
|
||||
message Item {
|
||||
string filename = 1; // 文件名
|
||||
string file_size = 2; // 文件大小
|
||||
string created_at = 3; // 上传时间
|
||||
}
|
||||
repeated Item items = 1; // 列表
|
||||
}
|
||||
|
||||
message UploadReq {}
|
||||
|
||||
message UploadResp {}
|
||||
|
||||
message DeleteReq {
|
||||
string filename = 1; // 文件名
|
||||
}
|
||||
|
||||
message DeleteResp {}
|
||||
|
||||
message DownloadReq {
|
||||
// @v: required
|
||||
string f = 1; // 文件地址
|
||||
}
|
||||
|
||||
message DownloadResp {}
|
|
@ -4,7 +4,7 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
@ -31,6 +31,36 @@ type Result struct {
|
|||
type Register struct {
|
||||
// GET参数解析器
|
||||
queryDecoder *schema.Decoder
|
||||
engine *gin.Engine
|
||||
addr string
|
||||
}
|
||||
|
||||
type RegisterOptions func(register *Register)
|
||||
|
||||
// WithGinMode set gin router mode
|
||||
func WithGinMode(mode string) RegisterOptions {
|
||||
return func(register *Register) {
|
||||
gin.SetMode(mode)
|
||||
}
|
||||
}
|
||||
|
||||
// WithRecovery returns a middleware that recovers from any panics and writes a 500 if there was one.
|
||||
func WithRecovery() RegisterOptions {
|
||||
return func(register *Register) {
|
||||
register.engine.Use(gin.Recovery())
|
||||
}
|
||||
}
|
||||
|
||||
func WithCors() RegisterOptions {
|
||||
return func(register *Register) {
|
||||
register.engine.Use(CorsFilter())
|
||||
}
|
||||
}
|
||||
|
||||
func WithListenAddress(addr string) RegisterOptions {
|
||||
return func(register *Register) {
|
||||
register.addr = addr
|
||||
}
|
||||
}
|
||||
|
||||
// NewRegister 实例化注册器
|
||||
|
@ -41,63 +71,79 @@ func NewRegister() *Register {
|
|||
return register
|
||||
}
|
||||
|
||||
func (r *Register) DefaultRouter(opts ...RegisterOptions) *Register {
|
||||
r.engine = gin.New()
|
||||
for _, option := range opts {
|
||||
option(r)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// RegisterStruct 按照 struct 的方法进行路由注册
|
||||
// rout: gin路由 建议传入group 将公共的中间件传递入group中
|
||||
// routers: 绑定自动生成的路由配置文件 proto同级的 autogen_router_module.go 文件中的 AutoGenXXXMap
|
||||
// igs: 需要注册的API组的struct ptr
|
||||
// ig: 需要注册的API组的struct ptr
|
||||
// 对于错误或异常零容忍 直接panic
|
||||
func (r *Register) RegisterStruct(rout gin.IRouter, routers Routers, igs ...interface{}) {
|
||||
func (r *Register) RegisterStruct(routers *Routers, drv interface{}, mws ...gin.HandlerFunc) {
|
||||
if len(routers.Apis) == 0 {
|
||||
logrus.Warnf("%s api list empty, skip registe", routers.StructName)
|
||||
logrus.Warnf("%s api list empty, skip register", routers.StructName)
|
||||
return
|
||||
}
|
||||
|
||||
if len(igs) == 0 {
|
||||
panic("group struct empty")
|
||||
if drv == nil {
|
||||
logrus.Warnf("%s api struct nil, skip register", routers.StructName)
|
||||
return
|
||||
}
|
||||
|
||||
for _, ig := range igs {
|
||||
//bind := ig.(BindGroupRouteSrv) // 你需要实现 BindGroupRouteSrv
|
||||
// 输出一下 rg
|
||||
refVal := reflect.ValueOf(ig)
|
||||
refTyp := reflect.TypeOf(ig)
|
||||
// new router group
|
||||
if r.engine == nil {
|
||||
r.DefaultRouter(WithGinMode(gin.ReleaseMode))
|
||||
}
|
||||
logrus.Infof("base url: %v", routers.BaseURL)
|
||||
newRouter := r.engine.Group(routers.BaseURL, mws...)
|
||||
|
||||
//routConfig := r.routers[bind.Bind()]
|
||||
//if routConfig == nil {
|
||||
// panic("no func to register")
|
||||
//}
|
||||
//if routConfig.Apis == nil {
|
||||
// panic("no func to register")
|
||||
//}
|
||||
// 注册路由公共中间件
|
||||
//if len(routConfig.Middlewares) != 0 {
|
||||
// r.registerMiddleware(rout, routConfig.Middlewares)
|
||||
//}
|
||||
routMap := routers.Apis
|
||||
for m := 0; m < refTyp.NumMethod(); m++ {
|
||||
// 这里取出方法
|
||||
method := refTyp.Method(m)
|
||||
//bind := ig.(BindGroupRouteSrv) // 你需要实现 BindGroupRouteSrv
|
||||
// 输出一下 rg
|
||||
refVal := reflect.ValueOf(drv)
|
||||
refTyp := reflect.TypeOf(drv)
|
||||
|
||||
var node *RouterNode
|
||||
var exist bool
|
||||
if node, exist = routMap[method.Name]; !exist {
|
||||
continue
|
||||
}
|
||||
if routers.BaseURL != "" {
|
||||
node.API = routers.BaseURL + node.API
|
||||
}
|
||||
// 注册路由
|
||||
if err := r.registerHandle(rout, node, method.Func, refVal); err != nil {
|
||||
logrus.Errorf("err: %+v", err)
|
||||
panic("err: " + err.Error())
|
||||
}
|
||||
//routConfig := r.routers[bind.Bind()]
|
||||
//if routConfig == nil {
|
||||
// panic("no func to register")
|
||||
//}
|
||||
//if routConfig.Apis == nil {
|
||||
// panic("no func to register")
|
||||
//}
|
||||
// 注册路由公共中间件
|
||||
//if len(routConfig.Middlewares) != 0 {
|
||||
// r.registerMiddleware(rout, routConfig.Middlewares)
|
||||
//}
|
||||
routMap := routers.Apis
|
||||
for m := 0; m < refTyp.NumMethod(); m++ {
|
||||
// 这里取出方法
|
||||
method := refTyp.Method(m)
|
||||
|
||||
var node *RouterNode
|
||||
var exist bool
|
||||
if node, exist = routMap[method.Name]; !exist {
|
||||
continue
|
||||
}
|
||||
|
||||
// 注册路由
|
||||
if err := r.registerHandle(newRouter, node, method.Func, refVal); err != nil {
|
||||
logrus.Errorf("err: %+v", err)
|
||||
panic("err: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// registerMiddleware 注册中间件
|
||||
func (r *Register) registerMiddleware(router gin.IRouter, mws []gin.HandlerFunc) {
|
||||
router.Use(mws...)
|
||||
// Run 服务运行
|
||||
func (r *Register) Run() {
|
||||
if r.addr == "" {
|
||||
r.addr = ":8080"
|
||||
}
|
||||
if err := r.engine.Run(r.addr); err != nil {
|
||||
logrus.Errorf("run server failed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// registerHandle 注册Handle
|
||||
|
@ -259,9 +305,9 @@ func (r *Register) getCallFunc(rFunc, rGroup reflect.Value) (gin.HandlerFunc, er
|
|||
|
||||
// bindAndValidate 绑定并校验参数
|
||||
func (r *Register) bindAndValidate(c *gin.Context, req interface{}) error {
|
||||
bodyBytes, _ := ioutil.ReadAll(c.Request.Body)
|
||||
bodyBytes, _ := io.ReadAll(c.Request.Body)
|
||||
c.Request.Body.Close()
|
||||
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
|
||||
|
||||
// 校验
|
||||
if c.Request.Method == http.MethodGet {
|
||||
|
@ -312,3 +358,30 @@ func (r *Register) bindAndValidate(c *gin.Context, req interface{}) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CorsFilter 跨域过滤器
|
||||
func CorsFilter() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Header("Access-Control-Allow-Origin", "*")
|
||||
c.Header("Access-Control-Allow-Headers", "*")
|
||||
c.Header("Access-Control-Allow-Methods", "*")
|
||||
c.Header("Access-Control-Expose-Headers", "*")
|
||||
if c.Request.Method == "OPTIONS" {
|
||||
c.String(http.StatusNoContent, "OPTIONS")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ResponseJsonHeader 统一设置返回json格式数据
|
||||
func ResponseJsonHeader() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Content-Type", "application/json")
|
||||
}
|
||||
}
|
||||
|
||||
func ResponseHtmlHeader() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Writer.Header().Set("Content-Type", "text/html")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package core
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
@ -25,6 +26,9 @@ func TestRegister_getCallFunc(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestNewRegister(t *testing.T) {
|
||||
//var reg = NewRegister()
|
||||
//reg.registerHandle()
|
||||
var reg = NewRegister()
|
||||
reg.DefaultRouter(WithGinMode(gin.DebugMode))
|
||||
// protoc core/file_module.proto --coco_out=core --go_out=core
|
||||
//reg.RegisterStruct(AutoGenFileRouterMap, &File{})
|
||||
reg.Run()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue