From 6b1c3d922699223883ddb3cfc487e2a85e179b07 Mon Sep 17 00:00:00 2001 From: wenjianzhang Date: Mon, 17 May 2021 23:09:35 +0800 Subject: [PATCH] =?UTF-8?q?refactor=F0=9F=8E=A8=20api=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/apis/sys_api.go | 29 +++--- app/admin/apis/sys_config.go | 165 ++++++++++++----------------------- app/admin/apis/sys_menu.go | 32 ++----- app/admin/models/sys_api.go | 34 ++++++++ app/admin/service/sys_api.go | 14 +-- app/other/router/monitor.go | 37 +++----- app/other/router/router.go | 1 - cmd/api/server.go | 42 ++++++--- common/apis/api.go | 15 +++- common/global/topic.go | 3 +- 10 files changed, 171 insertions(+), 201 deletions(-) diff --git a/app/admin/apis/sys_api.go b/app/admin/apis/sys_api.go index 062ae0f9..1631ca4c 100644 --- a/app/admin/apis/sys_api.go +++ b/app/admin/apis/sys_api.go @@ -26,7 +26,6 @@ type SysApi struct { // @Param title query string false "标题" // @Param path query string false "地址" // @Param action query string false "类型" -// @Param parentId query string false "按钮id" // @Param pageSize query int false "页条数" // @Param pageIndex query int false "页码" // @Success 200 {object} response.Response{data=response.Page{list=[]models.SysApi}} "{"code": 200, "data": [...]}" @@ -77,34 +76,26 @@ func (e SysApi) GetSysApiList(c *gin.Context) { // @Router /api/v1/sys_api/{id} [get] // @Security Bearer func (e SysApi) GetSysApi(c *gin.Context) { - e.MakeContext(c) - log := e.GetLogger() - db, err := e.GetOrm() - if err != nil { - log.Error(err) - return - } - control := new(dto.SysApiById) - - //查看详情 - err = e.Bind(control) + s := new(service.SysApi) + err := e.MakeContext(c). + MakeOrm(). + Bind(control). + MakeService(&s.Service). + Errors if err != nil { - log.Warnf("request body bind error, %s", err.Error()) - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") + e.Logger.Error(err) return } + var object models.SysApi //数据权限检查 p := actions.GetPermissionFromContext(c) - serviceSysApi := service.SysApi{} - serviceSysApi.Log = log - serviceSysApi.Orm = db - err = serviceSysApi.GetSysApi(control, p, &object) + err = s.GetSysApi(control, p, &object).Error if err != nil { - log.Errorf("Get SysApi error, %s", err.Error()) + e.Logger.Errorf("Get SysApi error, %s", err.Error()) e.Error(http.StatusInternalServerError, err, "查询失败") return } diff --git a/app/admin/apis/sys_config.go b/app/admin/apis/sys_config.go index 0a13f3f6..67fa7967 100644 --- a/app/admin/apis/sys_config.go +++ b/app/admin/apis/sys_config.go @@ -18,31 +18,24 @@ type SysConfig struct { } func (e SysConfig) GetSysConfigList(c *gin.Context) { - e.MakeContext(c) - log := e.GetLogger() + s := service.SysConfig{} d := new(dto.SysConfigSearch) - db, err := e.GetOrm() + err := e.MakeContext(c). + MakeOrm(). + Bind(d, binding.Query). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) - return - } - err = e.Bind(d, binding.Query) - //查询列表 - //err = d.Bind(c) - if err != nil { - log.Errorf("参数验证失败, error:%s", err) - e.Error(500, err, "参数验证失败") + e.Logger.Error(err) return } + list := make([]models.SysConfig, 0) var count int64 - s := service.SysConfig{} - s.Log = log - s.Orm = db err = s.GetSysConfigPage(d, &list, &count) if err != nil { - log.Errorf("GetSysConfigPage 查询失败, error:%s", err) + e.Logger.Errorf("GetSysConfigPage 查询失败, error:%s", err) e.Error(500, err, "查询失败") return } @@ -51,31 +44,24 @@ func (e SysConfig) GetSysConfigList(c *gin.Context) { // GetSysConfigBySysApp 获取系统配置信息,主要注意这里不在验证数据权限 func (e SysConfig) GetSysConfigBySysApp(c *gin.Context) { - e.Context = c - log := e.GetLogger() d := new(dto.SysConfigSearch) - db, err := e.GetOrm() + s := service.SysConfig{} + err := e.MakeContext(c). + MakeOrm(). + Bind(d, nil). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) - return - } - err = e.Bind(d, binding.Query) - if err != nil { - log.Errorf("参数验证失败, error:%s", err) - e.Error(500, err, "参数验证失败") + e.Logger.Error(err) return } // 控制只读前台的数据 d.IsFrontend = 1 - list := make([]models.SysConfig, 0) - s := service.SysConfig{} - s.Log = log - s.Orm = db err = s.GetSysConfigByKey(d, &list) if err != nil { - log.Errorf("GetSysConfigPage 查询失败, error:%s", err) + e.Logger.Errorf("GetSysConfigPage 查询失败, error:%s", err) e.Error(500, err, "查询失败") return } @@ -90,32 +76,23 @@ func (e SysConfig) GetSysConfigBySysApp(c *gin.Context) { } func (e SysConfig) GetSysConfig(c *gin.Context) { - e.Context = c - log := e.GetLogger() control := new(dto.SysConfigById) - db, err := e.GetOrm() + s := service.SysConfig{} + err := e.MakeContext(c). + MakeOrm(). + Bind(control). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) - return - } - //查看详情 - err = e.Bind(control) - err = control.Bind(c) - if err != nil { - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") + e.Logger.Error(err) return } var object models.SysConfig - serviceSysLoginLog := service.SysConfig{} - serviceSysLoginLog.Log = log - serviceSysLoginLog.Orm = db - err = serviceSysLoginLog.GetSysConfig(control, &object) + err = s.GetSysConfig(control, &object) if err != nil { e.Error(http.StatusUnprocessableEntity, err, "查询失败") - log.Errorf("Orm获取失败, error:%s", err) + e.Logger.Errorf("Orm获取失败, error:%s", err) e.Error(500, err, "Orm获取失败") return } @@ -124,123 +101,93 @@ func (e SysConfig) GetSysConfig(c *gin.Context) { } func (e SysConfig) InsertSysConfig(c *gin.Context) { - e.Context = c - log := e.GetLogger() + s := service.SysConfig{} control := new(dto.SysConfigControl) - db, err := e.GetOrm() + err := e.MakeContext(c). + MakeOrm(). + Bind(control). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) + e.Logger.Error(err) return } - //新增操作 - err = e.Bind(control, binding.JSON) - if err != nil { - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") - return - } object, err := control.Generate() if err != nil { e.Error(http.StatusInternalServerError, err, "模型生成失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") + e.Logger.Errorf("Orm获取失败, error:%s", err) return } // 设置创建人 object.SetCreateBy(user.GetUserId(c)) - serviceSysLoginLog := service.SysConfig{} - serviceSysLoginLog.Orm = db - serviceSysLoginLog.Log = log - err = serviceSysLoginLog.InsertSysConfig(object) + err = s.InsertSysConfig(object) if err != nil { - log.Error(err) + e.Logger.Error(err) e.Error(http.StatusInternalServerError, err, "创建失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") return } - e.OK(object.GetId(), "创建成功") } func (e SysConfig) UpdateSysConfig(c *gin.Context) { - e.Context = c - log := e.GetLogger() + s := service.SysConfig{} control := new(dto.SysConfigControl) - db, err := e.GetOrm() + err := e.MakeContext(c). + MakeOrm(). + Bind(control). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) + e.Logger.Error(err) return } - //更新操作 - err = e.Bind(control, binding.JSON) - - if err != nil { - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") - return - } object, err := control.Generate() if err != nil { e.Error(http.StatusInternalServerError, err, "模型生成失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") + e.Logger.Errorf("Orm获取失败, error:%s", err) return } object.SetUpdateBy(user.GetUserId(c)) - serviceSysLoginLog := service.SysConfig{} - serviceSysLoginLog.Orm = db - serviceSysLoginLog.Log = log - err = serviceSysLoginLog.UpdateSysConfig(object) + err = s.UpdateSysConfig(object) if err != nil { e.Error(http.StatusUnprocessableEntity, err, "更新失败") - log.Errorf("Orm获取失败, error:%s", err) - e.Error(500, err, "Orm获取失败") + e.Logger.Errorf("Orm获取失败, error:%s", err) return } e.OK(object.GetId(), "更新成功") } func (e SysConfig) DeleteSysConfig(c *gin.Context) { - e.Context = c - log := e.GetLogger() + s := service.SysConfig{} control := new(dto.SysConfigById) - db, err := e.GetOrm() + err := e.MakeContext(c). + MakeOrm(). + Bind(control). + MakeService(&s.Service). + Errors if err != nil { - log.Error(err) + e.Logger.Error(err) return } - //删除操作 - err = e.Bind(control, binding.JSON) - if err != nil { - log.Errorf("Bind error: %s", err) - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - return - } object, err := control.GenerateM() if err != nil { e.Error(http.StatusInternalServerError, err, "模型生成失败") - log.Errorf("Orm获取失败, error:%s", err) + e.Logger.Errorf("Orm获取失败, error:%s", err) return } // 设置编辑人 object.SetUpdateBy(user.GetUserId(c)) - serviceSysLoginLog := service.SysConfig{} - serviceSysLoginLog.Orm = db - serviceSysLoginLog.Log = log - err = serviceSysLoginLog.RemoveSysConfig(control, object) + err = s.RemoveSysConfig(control, object) if err != nil { e.Error(http.StatusUnprocessableEntity, err, "删除失败") - log.Errorf("Orm获取失败, error:%s", err) + e.Logger.Errorf("Orm获取失败, error:%s", err) return } e.OK(object.GetId(), "删除成功") diff --git a/app/admin/apis/sys_menu.go b/app/admin/apis/sys_menu.go index 15ab0d15..f4a09ba5 100644 --- a/app/admin/apis/sys_menu.go +++ b/app/admin/apis/sys_menu.go @@ -113,27 +113,20 @@ func (e SysMenu) GetSysMenu(c *gin.Context) { // @Security Bearer func (e SysMenu) InsertSysMenu(c *gin.Context) { control := new(dto.SysMenuControl) + s := new(service.SysMenu) err := e.MakeContext(c). MakeOrm(). + Bind(control). + MakeService(&s.Service). Errors if err != nil { e.Error(http.StatusInternalServerError, err, err.Error()) e.Logger.Error(err) return } - - // 绑定数据 - err = e.Bind(control) - if err != nil { - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - return - } - // 设置创建人 control.SetCreateBy(user.GetUserId(c)) - - serviceSysMenu := service.SysMenu{} - err = serviceSysMenu.MakeLog(e.Logger).MakeOrm(e.Orm).InsertSysMenu(control).Error + err = s.InsertSysMenu(control).Error if err != nil { e.Logger.Error(err) e.Error(http.StatusInternalServerError, err, "创建失败") @@ -156,28 +149,19 @@ func (e SysMenu) InsertSysMenu(c *gin.Context) { // @Security Bearer func (e SysMenu) UpdateSysMenu(c *gin.Context) { control := new(dto.SysMenuControl) + s := new(service.SysMenu) err := e.MakeContext(c). MakeOrm(). + Bind(control). + MakeService(&s.Service). Errors if err != nil { e.Logger.Error(err) return } - // 绑定数据 - err = e.Bind(control) - if err != nil { - e.Error(http.StatusUnprocessableEntity, err, "参数验证失败") - return - } control.SetUpdateBy(user.GetUserId(c)) - - serviceSysMenu := service.SysMenu{} - err = serviceSysMenu. - MakeOrm(e.Orm). - MakeLog(e.Logger). - UpdateSysMenu(control).Error - + err = s.UpdateSysMenu(control).Error if err != nil { e.Logger.Error(err) return diff --git a/app/admin/models/sys_api.go b/app/admin/models/sys_api.go index 20e8ae56..edf131b8 100644 --- a/app/admin/models/sys_api.go +++ b/app/admin/models/sys_api.go @@ -3,6 +3,11 @@ package models import ( // "gorm.io/gorm" + "encoding/json" + "fmt" + "github.com/go-admin-team/go-admin-core/sdk" + "github.com/go-admin-team/go-admin-core/sdk/runtime" + "github.com/go-admin-team/go-admin-core/storage" "go-admin/common/models" ) @@ -31,4 +36,33 @@ func (e *SysApi) Generate() models.ActiveRecord { func (e *SysApi) GetId() interface{} { return e.Id +} + +func SaveSysApi(message storage.Messager) (err error) { + var rb []byte + rb, err = json.Marshal(message.GetValues()) + if err != nil { + fmt.Errorf("json Marshal error, %s", err.Error()) + return err + } + + var l runtime.Routers + err = json.Unmarshal(rb, &l) + if err != nil { + fmt.Errorf("json Unmarshal error, %s", err.Error()) + return err + } + dbList := sdk.Runtime.GetDb() + for _, d := range dbList { + for _, v := range l.List { + err := d.Debug().Where(SysApi{Path: v.RelativePath, Action: v.HttpMethod}). + Attrs(SysApi{Handle: v.Handler}). + FirstOrCreate(&SysApi{}).Error + if err != nil { + err := fmt.Errorf("Models SaveSysApi error: %s \r\n ", err.Error()) + return err + } + } + } + return nil } \ No newline at end of file diff --git a/app/admin/service/sys_api.go b/app/admin/service/sys_api.go index 85df8b9e..1f5fd62a 100644 --- a/app/admin/service/sys_api.go +++ b/app/admin/service/sys_api.go @@ -39,7 +39,7 @@ func (e *SysApi) GetSysApiPage(c *dto.SysApiSearch, p *actions.DataPermission, l } // GetSysApi 获取SysApi对象 -func (e *SysApi) GetSysApi(d *dto.SysApiById, p *actions.DataPermission, model *models.SysApi) error { +func (e *SysApi) GetSysApi(d *dto.SysApiById, p *actions.DataPermission, model *models.SysApi) *SysApi { var data models.SysApi err := e.Orm.Model(&data). @@ -50,11 +50,13 @@ func (e *SysApi) GetSysApi(d *dto.SysApiById, p *actions.DataPermission, model * if err != nil && errors.Is(err, gorm.ErrRecordNotFound) { err = errors.New("查看对象不存在或无权查看") e.Log.Errorf("Service GetSysApi error:%s", err) - return err + e.AddError(err) + return e } if err != nil { e.Log.Errorf("db error:%s", err) - return err + e.AddError(err) + return e } return nil } @@ -62,7 +64,9 @@ func (e *SysApi) GetSysApi(d *dto.SysApiById, p *actions.DataPermission, model * // InsertSysApi 创建SysApi对象 func (e *SysApi) CheckStorageSysApi(c *[]runtime.Router) error { for _, v := range *c { - err := e.Orm.Debug().Where(models.SysApi{Path: v.RelativePath, Action: v.HttpMethod}).Attrs(models.SysApi{Handle: v.Handler}).FirstOrCreate(&models.SysApi{}).Error + err := e.Orm.Debug().Where(models.SysApi{Path: v.RelativePath, Action: v.HttpMethod}). + Attrs(models.SysApi{Handle: v.Handler}). + FirstOrCreate(&models.SysApi{}).Error if err != nil { err := fmt.Errorf("Service CheckStorageSysApi error: %s \r\n ", err.Error()) return err @@ -103,4 +107,4 @@ func (e *SysApi) RemoveSysApi(d *dto.SysApiById, p *actions.DataPermission) erro return errors.New("无权删除该数据") } return nil -} +} \ No newline at end of file diff --git a/app/other/router/monitor.go b/app/other/router/monitor.go index f3c6c788..0ce1ed10 100644 --- a/app/other/router/monitor.go +++ b/app/other/router/monitor.go @@ -1,36 +1,25 @@ package router import ( - "github.com/go-admin-team/go-admin-core/sdk" + "github.com/go-admin-team/go-admin-core/sdk/config" "net/http" "github.com/gin-gonic/gin" - log "github.com/go-admin-team/go-admin-core/logger" "github.com/go-admin-team/go-admin-core/tools/transfer" "github.com/prometheus/client_golang/prometheus/promhttp" ) -func Monitor() { - var r *gin.Engine - h := sdk.Runtime.GetEngine() - if h == nil { - h = gin.New() - sdk.Runtime.SetEngine(h) - } - switch h.(type) { - case *gin.Engine: - r = h.(*gin.Engine) - //开发环境启动监控指标 - setHandle(r) - default: - log.Fatal("not support other engine") - } +func init() { + routerNoCheckRole = append(routerNoCheckRole, registerMonitorRouter) } -func setHandle(r *gin.Engine) { - r.GET("/metrics", transfer.Handler(promhttp.Handler())) - //健康检查 - r.GET("/health", func(c *gin.Context) { - c.Status(http.StatusOK) - }) -} +// 需认证的路由代码 +func registerMonitorRouter(v1 *gin.RouterGroup) { + if config.ApplicationConfig.Mode == "dev" { + v1.GET("/metrics", transfer.Handler(promhttp.Handler())) + //健康检查 + v1.GET("/health", func(c *gin.Context) { + c.Status(http.StatusOK) + }) + } +} \ No newline at end of file diff --git a/app/other/router/router.go b/app/other/router/router.go index a99da845..e43e435b 100644 --- a/app/other/router/router.go +++ b/app/other/router/router.go @@ -1,6 +1,5 @@ package router - import ( "github.com/gin-gonic/gin" jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" diff --git a/cmd/api/server.go b/cmd/api/server.go index 9b40d88a..4ae9c0a9 100644 --- a/cmd/api/server.go +++ b/cmd/api/server.go @@ -3,10 +3,6 @@ package api import ( "context" "fmt" - "github.com/go-admin-team/go-admin-core/sdk/runtime" - "go-admin/app/admin/models" - "go-admin/app/admin/service" - router2 "go-admin/app/other/router" "log" "net/http" "os" @@ -20,8 +16,10 @@ import ( "github.com/go-admin-team/go-admin-core/sdk/pkg" "github.com/go-admin-team/go-admin-core/sdk/pkg/captcha" "github.com/go-admin-team/go-admin-core/sdk/pkg/logger" + "github.com/go-admin-team/go-admin-core/sdk/runtime" "github.com/spf13/cobra" + "go-admin/app/admin/models" "go-admin/app/admin/router" "go-admin/app/jobs" "go-admin/common/database" @@ -31,6 +29,7 @@ import ( var ( configYml string + apiCheck bool StartCmd = &cobra.Command{ Use: "server", Short: "Start API server", @@ -49,6 +48,7 @@ var AppRouters = make([]func(), 0) func init() { StartCmd.PersistentFlags().StringVarP(&configYml, "config", "c", "config/settings.yml", "Start server with provided configuration file") + StartCmd.PersistentFlags().BoolVarP(&apiCheck, "api", "a", false, "Start server with check api data") //注册路由 fixme 其他应用的路由,在本目录新建文件放在init方法 AppRouters = append(AppRouters, router.InitRouter) @@ -105,6 +105,7 @@ func setup() { queue := sdk.Runtime.GetMemoryQueue("") queue.Register(global.LoginLog, models.SaveLoginLog) queue.Register(global.OperateLog, models.SaveOperaLog) + queue.Register(global.ApiCheck, models.SaveSysApi) go queue.Run() } @@ -119,11 +120,6 @@ func run() error { engine = gin.New() } - if config.ApplicationConfig.Mode == "dev" { - //监控 - AppRouters = append(AppRouters, router2.Monitor) - } - for _, f := range AppRouters { f() } @@ -137,11 +133,29 @@ func run() error { jobs.Setup(sdk.Runtime.GetDb()) }() - - serviceApi := service.SysApi{} - serviceApi.Orm = sdk.Runtime.GetDb()["*"] - var routers = sdk.Runtime.GetRouter() - serviceApi.CheckStorageSysApi(&routers) + if apiCheck { + var routers = sdk.Runtime.GetRouter() + q := sdk.Runtime.GetMemoryQueue("") + mp := make(map[string]interface{}, 0) + mp["List"] = routers + message, err := sdk.Runtime.GetStreamMessage("", global.ApiCheck, mp) + if err != nil { + log.Printf("GetStreamMessage error, %s \n", err.Error()) + //日志报错错误,不中断请求 + } else { + err = q.Append(message) + if err != nil { + log.Printf("Append message error, %s \n", err.Error()) + } + } + } + //serviceApi := service.SysApi{} + //serviceApi.Orm = sdk.Runtime.GetDb()["*"] + //var routers = sdk.Runtime.GetRouter() + //err := serviceApi.CheckStorageSysApi(&routers) + //if err != nil { + // log.Println("Server check api data :", err) + //} ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() diff --git a/common/apis/api.go b/common/apis/api.go index cf21cfdc..4708f1c7 100644 --- a/common/apis/api.go +++ b/common/apis/api.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "github.com/gin-gonic/gin/binding" + "go-admin/common/service" "net/http" "github.com/gin-gonic/gin" @@ -21,7 +22,7 @@ type Api struct { Errors error } -func (e *Api) AddError(err error) { +func (e *Api) AddError(err error) { if e.Errors == nil { e.Errors = err } else if err != nil { @@ -44,7 +45,7 @@ func (e Api) GetLogger() *logger.Logger { return api.GetRequestLogger(e.Context) } -func (e Api) Bind(d interface{}, bindings ...binding.Binding) error { +func (e *Api) Bind(d interface{}, bindings ...binding.Binding) *Api { var err error if len(bindings) == 0 { bindings = append(bindings, binding.JSON, nil) @@ -75,10 +76,10 @@ func (e Api) Bind(d interface{}, bindings ...binding.Binding) error { err = e.Context.ShouldBindUri(d) } if err != nil { - return err + e.AddError(err) } } - return nil + return e } // GetOrm 获取Orm DB @@ -109,6 +110,12 @@ func (e *Api) MakeOrm() *Api { return e } +func (e *Api) MakeService(c *service.Service) *Api { + c.Log = e.Logger + c.Orm = e.Orm + return e +} + // Error 通常错误数据处理 func (e Api) Error(code int, err error, msg string) { response.Error(e.Context, code, err, msg) diff --git a/common/global/topic.go b/common/global/topic.go index ae88ce4d..827c9d75 100644 --- a/common/global/topic.go +++ b/common/global/topic.go @@ -3,4 +3,5 @@ package global const ( LoginLog = "login_log_queue" OperateLog = "operate_log_queue" -) + ApiCheck = "api_check_queue" +) \ No newline at end of file