mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-10-06 00:27:00 +08:00
性能优化
This commit is contained in:
4
server/.vscode/settings.json
vendored
4
server/.vscode/settings.json
vendored
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"cSpell.words": [
|
||||
"dcloudio",
|
||||
"endregion",
|
||||
"excelize",
|
||||
"fontsize",
|
||||
"freetype",
|
||||
@@ -9,10 +10,13 @@
|
||||
"gorm",
|
||||
"Infof",
|
||||
"Inno",
|
||||
"Itoa",
|
||||
"jinzhu",
|
||||
"mapstructure",
|
||||
"oneof",
|
||||
"rmvb",
|
||||
"strconv",
|
||||
"struct",
|
||||
"uniapp",
|
||||
"Warnf",
|
||||
"webp",
|
||||
|
@@ -2,16 +2,20 @@ package {{{ .ModuleName }}}
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
"github.com/gin-gonic/gin"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/util"
|
||||
"x_admin/util/excel"
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
|
||||
type {{{ title (toCamelCase .ModuleName) }}}Handler struct {}
|
||||
type {{{ title (toCamelCase .ModuleName) }}}Handler struct {
|
||||
requestGroup singleflight.Group
|
||||
}
|
||||
|
||||
// @Summary {{{ .FunctionName }}}列表
|
||||
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
|
||||
@@ -31,7 +35,7 @@ type {{{ title (toCamelCase .ModuleName) }}}Handler struct {}
|
||||
{{{- end }}}
|
||||
//@Success 200 {object} {{{getPageResp (title (toCamelCase .EntityName)) }}} "成功"
|
||||
//@Router /api/admin/{{{ .ModuleName }}}/list [get]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context) {
|
||||
var page request.PageReq
|
||||
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &page)) {
|
||||
@@ -59,7 +63,7 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) List(c *gin.Context) {
|
||||
{{{- end }}}
|
||||
// @Success 200 {object} response.Response{ data=[]{{{ title (toCamelCase .EntityName) }}}Resp} "成功"
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/listAll [get]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Context) {
|
||||
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
return
|
||||
@@ -79,12 +83,16 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ListAll(c *gin.Context
|
||||
{{{- end }}}
|
||||
// @Success 200 {object} response.Response{ data={{{ title (toCamelCase .EntityName) }}}Resp} "成功"
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/detail [get]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Detail(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Detail(c *gin.Context) {
|
||||
var detailReq {{{ title (toCamelCase .EntityName) }}}DetailReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
|
||||
return
|
||||
}
|
||||
res, err := {{{ title (toCamelCase .EntityName) }}}Service.Detail(detailReq.{{{ title (toCamelCase .PrimaryKey) }}})
|
||||
res, err, _ := hd.requestGroup.Do("{{{ title (toCamelCase .EntityName) }}}:Detail:"+strconv.Itoa(detailReq.{{{ title (toCamelCase .PrimaryKey) }}}), func() (any, error) {
|
||||
v, err := {{{ title (toCamelCase .EntityName) }}}Service.Detail(detailReq.{{{ title (toCamelCase .PrimaryKey) }}})
|
||||
return v, err
|
||||
})
|
||||
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
@@ -100,12 +108,13 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Detail(c *gin.Context)
|
||||
{{{- end }}}
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/add [post]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Add(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Add(c *gin.Context) {
|
||||
var addReq {{{ title (toCamelCase .EntityName) }}}AddReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
return
|
||||
}
|
||||
response.CheckAndResp(c, {{{ title (toCamelCase .EntityName) }}}Service.Add(addReq))
|
||||
createId, e := {{{ title (toCamelCase .EntityName) }}}Service.Add(addReq)
|
||||
response.CheckAndRespWithData(c,createId, e)
|
||||
}
|
||||
// @Summary {{{ .FunctionName }}}编辑
|
||||
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
|
||||
@@ -118,12 +127,12 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Add(c *gin.Context) {
|
||||
{{{- end }}}
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/edit [post]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Edit(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Edit(c *gin.Context) {
|
||||
var editReq {{{ title (toCamelCase .EntityName) }}}EditReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
|
||||
return
|
||||
}
|
||||
response.CheckAndResp(c, {{{ title (toCamelCase .EntityName) }}}Service.Edit(editReq))
|
||||
response.CheckAndRespWithData(c,editReq.{{{ title (toCamelCase .PrimaryKey) }}}, {{{ title (toCamelCase .EntityName) }}}Service.Edit(editReq))
|
||||
}
|
||||
// @Summary {{{ .FunctionName }}}删除
|
||||
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
|
||||
@@ -136,7 +145,7 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Edit(c *gin.Context) {
|
||||
{{{- end }}}
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/del [post]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Del(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) Del(c *gin.Context) {
|
||||
var delReq {{{ title (toCamelCase .EntityName) }}}DelReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
return
|
||||
@@ -161,7 +170,7 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) Del(c *gin.Context) {
|
||||
{{{- end }}}
|
||||
{{{- end }}}
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/ExportFile [get]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ExportFile(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ExportFile(c *gin.Context) {
|
||||
var listReq {{{ title (toCamelCase .EntityName) }}}ListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
return
|
||||
@@ -183,7 +192,7 @@ func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ExportFile(c *gin.Cont
|
||||
// @Tags {{{ .ModuleName }}}-{{{ .FunctionName }}}
|
||||
// @Produce json
|
||||
// @Router /api/admin/{{{ .ModuleName }}}/ImportFile [post]
|
||||
func (hd {{{ title (toCamelCase .ModuleName) }}}Handler) ImportFile(c *gin.Context) {
|
||||
func (hd *{{{ title (toCamelCase .ModuleName) }}}Handler) ImportFile(c *gin.Context) {
|
||||
file, _, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "文件不存在")
|
||||
|
@@ -51,5 +51,5 @@ func {{{ title (toCamelCase .ModuleName) }}}Route(rg *gin.RouterGroup) {
|
||||
r.POST("/{{{ .ModuleName }}}/edit",middleware.RecordLog("{{{ .FunctionName }}}编辑"), handle.Edit)
|
||||
r.POST("/{{{ .ModuleName }}}/del", middleware.RecordLog("{{{ .FunctionName }}}删除"), handle.Del)
|
||||
r.GET("/{{{ .ModuleName }}}/ExportFile", middleware.RecordLog("{{{ .FunctionName }}}导出"), handle.ExportFile)
|
||||
r.POST("/{{{ .ModuleName }}}/ImportFile", handle.ImportFile)
|
||||
r.POST("/{{{ .ModuleName }}}/ImportFile",middleware.RecordLog("{{{ .FunctionName }}}导入"), handle.ImportFile)
|
||||
}
|
@@ -27,13 +27,13 @@ func (service {{{ toCamelCase .EntityName }}}Service) SetCache(obj model.{{{ tit
|
||||
if e != nil {
|
||||
return false
|
||||
}
|
||||
return util.RedisUtil.Set("{{{ toCamelCase .EntityName }}}:id:"+strconv.Itoa(obj.Id), str, 3600)
|
||||
return util.RedisUtil.HSet("{{{ toCamelCase .EntityName }}}",strconv.Itoa(obj.{{{ title (toCamelCase .PrimaryKey) }}}), str, 3600)
|
||||
}
|
||||
|
||||
// 获取缓存
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) GetCache(id int) (model.{{{ title (toCamelCase .EntityName) }}}, error) {
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) GetCache(key int) (model.{{{ title (toCamelCase .EntityName) }}}, error) {
|
||||
var obj model.{{{ title (toCamelCase .EntityName) }}}
|
||||
str := util.RedisUtil.Get("{{{ toCamelCase .EntityName }}}:id:" + strconv.Itoa(id))
|
||||
str := util.RedisUtil.HGet("{{{ toCamelCase .EntityName }}}", strconv.Itoa(key))
|
||||
if str == "" {
|
||||
return obj, errors.New("获取缓存失败")
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) GetCache(id int) (model.{{
|
||||
}
|
||||
// 删除缓存
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) RemoveCache(obj model.{{{ title (toCamelCase .EntityName) }}}) bool {
|
||||
return util.RedisUtil.Del("{{{ toCamelCase .EntityName }}}:id:" + strconv.Itoa(obj.Id))
|
||||
return util.RedisUtil.HDel("{{{ toCamelCase .EntityName }}}", strconv.Itoa(obj.{{{ title (toCamelCase .PrimaryKey) }}}))
|
||||
}
|
||||
|
||||
|
||||
@@ -124,11 +124,11 @@ func (service {{{ toCamelCase .EntityName }}}Service) ListAll(listReq {{{ title
|
||||
}
|
||||
|
||||
// Detail {{{ .FunctionName }}}详情
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Detail(id int) (res {{{ title (toCamelCase .EntityName) }}}Resp, e error) {
|
||||
var obj, err = service.GetCache(id)
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ title (toCamelCase .PrimaryKey) }}} int) (res {{{ title (toCamelCase .EntityName) }}}Resp, e error) {
|
||||
var obj, err = service.GetCache({{{ title (toCamelCase .PrimaryKey) }}})
|
||||
// var obj model.{{{ title (toCamelCase .EntityName) }}}
|
||||
if err != nil {
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", id{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||||
return
|
||||
}
|
||||
@@ -149,15 +149,16 @@ func (service {{{ toCamelCase .EntityName }}}Service) Detail(id int) (res {{{ ti
|
||||
}
|
||||
|
||||
// Add {{{ .FunctionName }}}新增
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ title (toCamelCase .EntityName) }}}AddReq) (e error) {
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ title (toCamelCase .EntityName) }}}AddReq) (createId int,e error) {
|
||||
var obj model.{{{ title (toCamelCase .EntityName) }}}
|
||||
response.Copy(&obj, addReq)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
return e
|
||||
return 0,e
|
||||
}
|
||||
service.SetCache(obj)
|
||||
createId = obj.{{{ title (toCamelCase .PrimaryKey) }}}
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
}
|
||||
@@ -165,7 +166,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ title (toCa
|
||||
// Edit {{{ .FunctionName }}}编辑
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ title (toCamelCase .EntityName) }}}EditReq) (e error) {
|
||||
var obj model.{{{ title (toCamelCase .EntityName) }}}
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", editReq.Id{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", editReq.{{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
// 校验
|
||||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||||
return
|
||||
@@ -182,9 +183,9 @@ func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ title (to
|
||||
}
|
||||
|
||||
// Del {{{ .FunctionName }}}删除
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Del(id int) (e error) {
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Del({{{ title (toCamelCase .PrimaryKey) }}} int) (e error) {
|
||||
var obj model.{{{ title (toCamelCase .EntityName) }}}
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", id{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
err := service.db.Where("{{{ $.PrimaryKey }}} = ?{{{ if contains .AllFields "is_delete" }}} AND is_delete = ?{{{ end }}}", {{{ title (toCamelCase .PrimaryKey) }}}{{{ if contains .AllFields "is_delete" }}}, 0{{{ end }}}).Limit(1).First(&obj).Error
|
||||
// 校验
|
||||
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||||
return
|
||||
|
@@ -1,8 +1,8 @@
|
||||
package monitor_project
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
@@ -13,7 +13,9 @@ import (
|
||||
"golang.org/x/sync/singleflight"
|
||||
)
|
||||
|
||||
type MonitorProjectHandler struct{}
|
||||
type MonitorProjectHandler struct {
|
||||
requestGroup singleflight.Group
|
||||
}
|
||||
|
||||
// @Summary 错误项目列表
|
||||
// @Tags monitor_project-错误项目
|
||||
@@ -27,7 +29,7 @@ type MonitorProjectHandler struct{}
|
||||
// @Success 200 {object} response.Response{data=response.PageResp{lists=[]MonitorProjectResp}} "成功"
|
||||
// @Failure 400 {object} string "请求错误"
|
||||
// @Router /api/admin/monitor_project/list [get]
|
||||
func (hd MonitorProjectHandler) List(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) List(c *gin.Context) {
|
||||
var page request.PageReq
|
||||
var listReq MonitorProjectListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &page)) {
|
||||
@@ -45,14 +47,14 @@ func (hd MonitorProjectHandler) List(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Success 200 {object} response.Response{data=[]MonitorProjectResp} "成功"
|
||||
// @Router /api/admin/monitor_project/listAll [get]
|
||||
var sg singleflight.Group
|
||||
// var sg singleflight.Group
|
||||
|
||||
func (hd MonitorProjectHandler) ListAll(c *gin.Context) {
|
||||
res, err, shared := sg.Do("key", func() (any, error) {
|
||||
func (hd *MonitorProjectHandler) ListAll(c *gin.Context) {
|
||||
res, err, _ := hd.requestGroup.Do("monitor_project:listAll", func() (any, error) {
|
||||
v, err := Service.ListAll()
|
||||
return v, err
|
||||
})
|
||||
fmt.Printf("v: %v, shared: %v\n", res, shared)
|
||||
// fmt.Printf("v: %v, shared: %v\n", res, shared)
|
||||
|
||||
// var listReq MonitorProjectListReq
|
||||
// if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
@@ -68,12 +70,16 @@ func (hd MonitorProjectHandler) ListAll(c *gin.Context) {
|
||||
// @Param id query int false "项目id."
|
||||
// @Success 200 {object} response.Response{data=MonitorProjectResp} "成功"
|
||||
// @Router /api/admin/monitor_project/detail [get]
|
||||
func (hd MonitorProjectHandler) Detail(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) Detail(c *gin.Context) {
|
||||
var detailReq MonitorProjectDetailReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
|
||||
return
|
||||
}
|
||||
res, err := Service.Detail(detailReq.Id)
|
||||
res, err, _ := hd.requestGroup.Do("monitor_project:Detail:"+strconv.Itoa(detailReq.Id), func() (any, error) {
|
||||
v, err := Service.Detail(detailReq.Id)
|
||||
return v, err
|
||||
})
|
||||
// fmt.Printf("v: %v, shared: %v\n", res, shared)
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
@@ -86,12 +92,13 @@ func (hd MonitorProjectHandler) Detail(c *gin.Context) {
|
||||
// @Param projectType body string false "项目类型go java web node php 等."
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_project/add [post]
|
||||
func (hd MonitorProjectHandler) Add(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) Add(c *gin.Context) {
|
||||
var addReq MonitorProjectAddReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
return
|
||||
}
|
||||
response.CheckAndResp(c, Service.Add(addReq))
|
||||
createId, e := Service.Add(addReq)
|
||||
response.CheckAndRespWithData(c, createId, e)
|
||||
}
|
||||
|
||||
// @Summary 错误项目编辑
|
||||
@@ -104,12 +111,12 @@ func (hd MonitorProjectHandler) Add(c *gin.Context) {
|
||||
// @Param projectType body string false "项目类型go java web node php 等."
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_project/edit [post]
|
||||
func (hd MonitorProjectHandler) Edit(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) Edit(c *gin.Context) {
|
||||
var editReq MonitorProjectEditReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
|
||||
return
|
||||
}
|
||||
response.CheckAndResp(c, Service.Edit(editReq))
|
||||
response.CheckAndRespWithData(c, editReq.Id, Service.Edit(editReq))
|
||||
}
|
||||
|
||||
// @Summary 错误项目删除
|
||||
@@ -119,7 +126,7 @@ func (hd MonitorProjectHandler) Edit(c *gin.Context) {
|
||||
// @Param id body int false "项目id."
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_project/del [post]
|
||||
func (hd MonitorProjectHandler) Del(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) Del(c *gin.Context) {
|
||||
var delReq MonitorProjectDelReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
return
|
||||
@@ -135,7 +142,7 @@ func (hd MonitorProjectHandler) Del(c *gin.Context) {
|
||||
// @Param projectName query string false "项目名称."
|
||||
// @Param projectType query string false "项目类型go java web node php 等."
|
||||
// @Router /api/admin/monitor_project/ExportFile [get]
|
||||
func (hd MonitorProjectHandler) ExportFile(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) ExportFile(c *gin.Context) {
|
||||
var listReq MonitorProjectListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
return
|
||||
@@ -156,7 +163,7 @@ func (hd MonitorProjectHandler) ExportFile(c *gin.Context) {
|
||||
// @Summary 错误项目导入
|
||||
// @Tags monitor_project-错误项目
|
||||
// @Produce json
|
||||
func (hd MonitorProjectHandler) ImportFile(c *gin.Context) {
|
||||
func (hd *MonitorProjectHandler) ImportFile(c *gin.Context) {
|
||||
file, _, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
c.String(http.StatusInternalServerError, "文件不存在")
|
||||
@@ -169,9 +176,9 @@ func (hd MonitorProjectHandler) ImportFile(c *gin.Context) {
|
||||
c.String(http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
for _, t := range importList {
|
||||
fmt.Printf("%#v", t)
|
||||
}
|
||||
// for _, t := range importList {
|
||||
// fmt.Printf("%#v", t)
|
||||
// }
|
||||
err = Service.ImportFile(importList)
|
||||
response.CheckAndResp(c, err)
|
||||
}
|
||||
|
@@ -41,13 +41,13 @@ func (service monitorProjectService) SetCache(obj model.MonitorProject) bool {
|
||||
if e != nil {
|
||||
return false
|
||||
}
|
||||
return util.RedisUtil.Set("MonitorProject:id:"+strconv.Itoa(obj.Id), str, 3600)
|
||||
return util.RedisUtil.HSet("MonitorProject", strconv.Itoa(obj.Id), str, 3600)
|
||||
}
|
||||
|
||||
// 获取缓存
|
||||
func (service monitorProjectService) GetCache(id int) (model.MonitorProject, error) {
|
||||
var obj model.MonitorProject
|
||||
str := util.RedisUtil.Get("MonitorProject:id:" + strconv.Itoa(id))
|
||||
str := util.RedisUtil.HGet("MonitorProject", strconv.Itoa(id))
|
||||
if str == "" {
|
||||
return obj, errors.New("获取缓存失败")
|
||||
}
|
||||
@@ -61,7 +61,7 @@ func (service monitorProjectService) GetCache(id int) (model.MonitorProject, err
|
||||
|
||||
// 删除缓存
|
||||
func (service monitorProjectService) RemoveCache(obj model.MonitorProject) bool {
|
||||
return util.RedisUtil.Del("{{{ toCamelCase .EntityName }}}:id:" + strconv.Itoa(obj.Id))
|
||||
return util.RedisUtil.HDel("MonitorProject", strconv.Itoa(obj.Id))
|
||||
}
|
||||
|
||||
// List 错误项目列表
|
||||
@@ -147,16 +147,17 @@ func (service monitorProjectService) Detail(id int) (res MonitorProjectResp, e e
|
||||
}
|
||||
|
||||
// Add 错误项目新增
|
||||
func (service monitorProjectService) Add(addReq MonitorProjectAddReq) (e error) {
|
||||
func (service monitorProjectService) Add(addReq MonitorProjectAddReq) (createId int, e error) {
|
||||
var obj model.MonitorProject
|
||||
response.Copy(&obj, addReq)
|
||||
obj.ProjectKey = util.ToolsUtil.MakeUuid()
|
||||
err := service.db.Create(&obj).Error
|
||||
|
||||
if e = response.CheckMysqlErr(err); e != nil {
|
||||
return e
|
||||
return 0, e
|
||||
}
|
||||
service.SetCache(obj)
|
||||
createId = obj.Id
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
}
|
||||
@@ -194,7 +195,7 @@ func (service monitorProjectService) Del(id int) (e error) {
|
||||
// 删除
|
||||
obj.IsDelete = 1
|
||||
err = service.db.Save(&obj).Error
|
||||
util.RedisUtil.Del("MonitorProject:id:" + strconv.Itoa(obj.Id))
|
||||
service.RemoveCache(obj)
|
||||
e = response.CheckErr(err, "Del Save err")
|
||||
return
|
||||
}
|
||||
|
@@ -38,5 +38,5 @@ func MonitorProjectRoute(rg *gin.RouterGroup) {
|
||||
r.POST("/monitor_project/edit", middleware.RecordLog("错误项目编辑"), handle.Edit)
|
||||
r.POST("/monitor_project/del", middleware.RecordLog("错误项目删除"), handle.Del)
|
||||
r.GET("/monitor_project/ExportFile", middleware.RecordLog("错误项目导出"), handle.ExportFile)
|
||||
r.POST("/monitor_project/ImportFile", handle.ImportFile)
|
||||
r.POST("/monitor_project/ImportFile", middleware.RecordLog("错误项目导入"), handle.ImportFile)
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@@ -14,24 +15,26 @@ var Config = loadConfig(".")
|
||||
// #region envConfig
|
||||
// envConfig 环境配置
|
||||
type envConfig struct {
|
||||
RootPath string // 项目根目录
|
||||
GinMode string `mapstructure:"GIN_MODE"` // gin运行模式
|
||||
PublicUrl string `mapstructure:"PUBLIC_URL"` // 对外发布的Url
|
||||
OssDomain string `mapstructure:"OSS_DOMAIN"` // OSS域名
|
||||
ServerPort int `mapstructure:"SERVER_PORT"` // 服务运行端口
|
||||
DisallowModify bool `mapstructure:"DISALLOW_MODIFY"` // 禁止修改操作 (演示功能,限制POST请求)
|
||||
PublicPrefix string // 资源访问前缀
|
||||
UploadDirectory string `mapstructure:"UPLOAD_DIRECTORY"` // 上传文件路径
|
||||
RedisUrl string `mapstructure:"REDIS_URL"` // Redis源配置
|
||||
RedisPoolSize int // Redis连接池大小
|
||||
DatabaseUrl string `mapstructure:"DATABASE_URL"` // 数据源配置
|
||||
DbTablePrefix string // Mysql表前缀
|
||||
DbDefaultStringSize uint // 数据库string类型字段的默认长度
|
||||
DbMaxIdleConns int // 数据库空闲连接池最大值
|
||||
DbMaxOpenConns int // 数据库连接池最大值
|
||||
DbConnMaxLifetimeSeconds int16 // 连接可复用的最大时间(秒:默认28800秒),请根据这个sql查处的时间设置: show variables like 'wait_timeout'
|
||||
Version string // 版本
|
||||
Secret string // 系统加密字符
|
||||
RootPath string // 项目根目录
|
||||
GinMode string `mapstructure:"GIN_MODE"` // gin运行模式
|
||||
PublicUrl string `mapstructure:"PUBLIC_URL"` // 对外发布的Url
|
||||
OssDomain string `mapstructure:"OSS_DOMAIN"` // OSS域名
|
||||
ServerPort int `mapstructure:"SERVER_PORT"` // 服务运行端口
|
||||
DisallowModify bool `mapstructure:"DISALLOW_MODIFY"` // 禁止修改操作 (演示功能,限制POST请求)
|
||||
PublicPrefix string // 资源访问前缀
|
||||
UploadDirectory string `mapstructure:"UPLOAD_DIRECTORY"` // 上传文件路径
|
||||
RedisUrl string `mapstructure:"REDIS_URL"` // Redis源配置
|
||||
// RedisPoolSize int // Redis连接池大小
|
||||
RedisMaxIdleConns int // Redis空闲连接池最大值
|
||||
RedisConnMaxLifetime time.Duration // Redis连接可复用的最大时间(秒:默认60秒)
|
||||
DatabaseUrl string `mapstructure:"DATABASE_URL"` // 数据源配置
|
||||
DbTablePrefix string // Mysql表前缀
|
||||
DbDefaultStringSize uint // 数据库string类型字段的默认长度
|
||||
DbMaxIdleConns int // 数据库空闲连接池最大值
|
||||
DbMaxOpenConns int // 数据库连接池最大值
|
||||
DbConnMaxLifetimeSeconds int16 // 连接可复用的最大时间(秒:默认28800秒),请根据这个sql查处的时间设置: show variables like 'wait_timeout'
|
||||
Version string // 版本
|
||||
Secret string // 系统加密字符
|
||||
|
||||
RedisPrefix string // Redis键前缀
|
||||
UploadImageSize int64 // 上传图片限制
|
||||
@@ -75,8 +78,10 @@ func loadConfig(envPath string) envConfig {
|
||||
// 上传文件路径
|
||||
UploadDirectory: "/tmp/uploads/x_admin-go/",
|
||||
// Redis源配置
|
||||
RedisUrl: "redis://localhost:6379",
|
||||
RedisPoolSize: 100,
|
||||
RedisUrl: "redis://localhost:6379",
|
||||
// RedisPoolSize: 100,
|
||||
RedisMaxIdleConns: 80,
|
||||
RedisConnMaxLifetime: 60 * time.Second,
|
||||
// 数据源配置
|
||||
DatabaseUrl: "x_admin:x_admin@tcp(localhost:3306)/x_admin?charset=utf8mb4&parseTime=True&loc=Local",
|
||||
DbTablePrefix: "x_",
|
||||
|
@@ -17,7 +17,10 @@ func initRedis() *redis.Client {
|
||||
if err != nil {
|
||||
log.Fatal("initRedis redis.ParseURL err: ", err)
|
||||
}
|
||||
opt.PoolSize = config.Config.RedisPoolSize
|
||||
// opt.PoolSize = config.Config.RedisPoolSize
|
||||
opt.MaxIdleConns = config.Config.RedisMaxIdleConns
|
||||
opt.ConnMaxLifetime = config.Config.RedisConnMaxLifetime
|
||||
|
||||
client := redis.NewClient(opt)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
@@ -35,6 +35,7 @@ require (
|
||||
require (
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/bytedance/sonic v1.11.6 // indirect
|
||||
github.com/bytedance/sonic/loader v0.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
@@ -84,6 +85,7 @@ require (
|
||||
github.com/xuri/nfp v0.0.0-20230919160717-d98342af3f05 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.1 // indirect
|
||||
golang.org/x/arch v0.8.0 // indirect
|
||||
golang.org/x/crypto v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231108232855-2478ac86f678 // indirect
|
||||
|
@@ -2,6 +2,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
|
||||
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
|
||||
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
|
||||
@@ -203,6 +205,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0=
|
||||
go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
|
29
server/middleware/ratelimit.go
Normal file
29
server/middleware/ratelimit.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"go.uber.org/ratelimit"
|
||||
)
|
||||
|
||||
// 限制每秒请求数量
|
||||
// r := rg.Group("/", middleware.RateLimiterMiddleware(200))
|
||||
func RateLimiterMiddleware(rate int) gin.HandlerFunc {
|
||||
rl := ratelimit.New(rate)
|
||||
|
||||
return func(c *gin.Context) {
|
||||
// Try to take a token from the rate limiter.
|
||||
now := rl.Take()
|
||||
|
||||
// Check if we've waited longer than expected. If so, this means the rate
|
||||
// limit has been exceeded.
|
||||
if now.After(time.Now()) {
|
||||
c.AbortWithStatus(http.StatusTooManyRequests)
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
}
|
@@ -2,7 +2,6 @@ package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -46,8 +45,8 @@ func (l *RedisUtil) Get(key string) string {
|
||||
|
||||
func (l *RedisUtil) Set(key string, val string, expiresInSeconds int) {
|
||||
//设置阈值,达到即clear缓存
|
||||
rdsResult := l.Rdb.Set(context.Background(), key, val, time.Duration(expiresInSeconds)*time.Second)
|
||||
fmt.Println("rdsResult: ", rdsResult.String(), "rdsErr: ", rdsResult.Err())
|
||||
l.Rdb.Set(context.Background(), key, val, time.Duration(expiresInSeconds)*time.Second)
|
||||
|
||||
if expiresInSeconds > 0 {
|
||||
// 缓存失效时间
|
||||
nowTime := time.Now().Unix() + int64(expiresInSeconds)
|
||||
|
Reference in New Issue
Block a user