mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-12-25 09:06:34 +08:00
refactor: 新增base.Repo与base.App,重构repo与app层代码
This commit is contained in:
145
server/pkg/base/app.go
Normal file
145
server/pkg/base/app.go
Normal file
@@ -0,0 +1,145 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 基础application接口
|
||||
type App[T any] interface {
|
||||
|
||||
// 新增一个实体
|
||||
Insert(e T) error
|
||||
|
||||
// 批量新增实体
|
||||
BatchInsert(models []T) error
|
||||
|
||||
// 根据实体id更新实体信息
|
||||
UpdateById(e T) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
UpdateByIdWithDb(db *gorm.DB, e T) error
|
||||
|
||||
// 根据实体主键删除实体
|
||||
DeleteById(id uint64) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
DeleteByIdWithDb(db *gorm.DB, id uint64) error
|
||||
|
||||
// 根据实体条件,更新参数udpateFields指定字段
|
||||
Updates(cond any, udpateFields map[string]any) error
|
||||
|
||||
// 根据实体条件删除实体
|
||||
DeleteByCond(cond any) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
DeleteByCondWithDb(db *gorm.DB, cond any) error
|
||||
|
||||
// 根据实体id查询
|
||||
GetById(e T, id uint64, cols ...string) (T, error)
|
||||
|
||||
GetByIdIn(list any, ids []uint64, orderBy ...string) error
|
||||
|
||||
// 根据实体条件查询实体信息
|
||||
GetBy(condModel T, cols ...string) error
|
||||
|
||||
// 根据条件查询数据映射至listModels
|
||||
ListByCond(cond any, listModels any, cols ...string) error
|
||||
|
||||
// 获取满足model中不为空的字段值条件的所有数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体
|
||||
// @param cond 条件
|
||||
ListByCondOrder(cond any, list any, order ...string) error
|
||||
|
||||
// 根据指定条件统计model表的数量, cond为条件可以为map等
|
||||
CountByCond(cond any) int64
|
||||
}
|
||||
|
||||
// 基础application接口实现
|
||||
type AppImpl[T any, R Repo[T]] struct {
|
||||
Repo R // repo接口
|
||||
}
|
||||
|
||||
// 获取repo
|
||||
func (ai *AppImpl[T, R]) GetRepo() R {
|
||||
return ai.Repo
|
||||
}
|
||||
|
||||
// 新增一个实体 (单纯新增,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) Insert(e T) error {
|
||||
return ai.GetRepo().Insert(e)
|
||||
}
|
||||
|
||||
// 批量新增实体 (单纯新增,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) BatchInsert(es []T) error {
|
||||
return ai.GetRepo().BatchInsert(es)
|
||||
}
|
||||
|
||||
// 根据实体id更新实体信息 (单纯更新,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) UpdateById(e T) error {
|
||||
return ai.GetRepo().UpdateById(e)
|
||||
}
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
func (ai *AppImpl[T, R]) UpdateByIdWithDb(db *gorm.DB, e T) error {
|
||||
return ai.GetRepo().UpdateByIdWithDb(db, e)
|
||||
}
|
||||
|
||||
// 根据实体条件,更新参数udpateFields指定字段 (单纯更新,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) Updates(cond any, udpateFields map[string]any) error {
|
||||
return ai.GetRepo().Updates(cond, udpateFields)
|
||||
}
|
||||
|
||||
// 根据实体主键删除实体 (单纯删除实体,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) DeleteById(id uint64) error {
|
||||
return ai.GetRepo().DeleteById(id)
|
||||
}
|
||||
|
||||
func (ai *AppImpl[T, R]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
|
||||
return ai.GetRepo().DeleteByCondWithDb(db, id)
|
||||
}
|
||||
|
||||
// 根据指定条件删除实体 (单纯删除实体,不做其他业务逻辑处理)
|
||||
func (ai *AppImpl[T, R]) DeleteByCond(cond any) error {
|
||||
return ai.GetRepo().DeleteByCond(cond)
|
||||
}
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
func (ai *AppImpl[T, R]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
|
||||
return ai.GetRepo().DeleteByCondWithDb(db, cond)
|
||||
}
|
||||
|
||||
// 根据实体id查询
|
||||
func (ai *AppImpl[T, R]) GetById(e T, id uint64, cols ...string) (T, error) {
|
||||
if err := ai.GetRepo().GetById(e, id, cols...); err != nil {
|
||||
return e, err
|
||||
}
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (ai *AppImpl[T, R]) GetByIdIn(list any, ids []uint64, orderBy ...string) error {
|
||||
return ai.GetRepo().GetByIdIn(list, ids, orderBy...)
|
||||
}
|
||||
|
||||
// 根据实体条件查询实体信息
|
||||
func (ai *AppImpl[T, R]) GetBy(condModel T, cols ...string) error {
|
||||
return ai.GetRepo().GetBy(condModel, cols...)
|
||||
}
|
||||
|
||||
// 根据条件查询数据映射至listModels
|
||||
func (ai *AppImpl[T, R]) ListByCond(cond any, listModels any, cols ...string) error {
|
||||
return ai.GetRepo().ListByCond(cond, listModels, cols...)
|
||||
}
|
||||
|
||||
// 获取满足model中不为空的字段值条件的所有数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体
|
||||
// @param cond 条件
|
||||
func (ai *AppImpl[T, R]) ListByCondOrder(cond any, list any, order ...string) error {
|
||||
return ai.GetRepo().ListByCondOrder(cond, list, order...)
|
||||
}
|
||||
|
||||
// 根据指定条件统计model表的数量, cond为条件可以为map等
|
||||
func (ai *AppImpl[T, R]) CountByCond(cond any) int64 {
|
||||
return ai.GetRepo().CountByCond(cond)
|
||||
}
|
||||
149
server/pkg/base/repo.go
Normal file
149
server/pkg/base/repo.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package base
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/gormx"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// 基础repo接口
|
||||
type Repo[T any] interface {
|
||||
|
||||
// 新增一个实体
|
||||
Insert(e T) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
InsertWithDb(db *gorm.DB, e T) error
|
||||
|
||||
// 批量新增实体
|
||||
BatchInsert(models []T) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
BatchInsertWithDb(db *gorm.DB, es []T) error
|
||||
|
||||
// 根据实体id更新实体信息
|
||||
UpdateById(e T) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
UpdateByIdWithDb(db *gorm.DB, e T) error
|
||||
|
||||
// 根据实体主键删除实体
|
||||
DeleteById(id uint64) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
DeleteByIdWithDb(db *gorm.DB, id uint64) error
|
||||
|
||||
// 根据实体条件,更新参数udpateFields指定字段
|
||||
Updates(cond any, udpateFields map[string]any) error
|
||||
|
||||
// 根据实体条件删除实体
|
||||
DeleteByCond(cond any) error
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
DeleteByCondWithDb(db *gorm.DB, cond any) error
|
||||
|
||||
// 根据实体id查询
|
||||
GetById(e T, id uint64, cols ...string) error
|
||||
|
||||
// 根据实体id数组查询对应实体列表,并将响应结果映射至list
|
||||
GetByIdIn(list any, ids []uint64, orderBy ...string) error
|
||||
|
||||
// 根据实体条件查询实体信息
|
||||
GetBy(cond T, cols ...string) error
|
||||
|
||||
// 根据实体条件查询数据映射至listModels
|
||||
ListByCond(cond any, listModels any, cols ...string) error
|
||||
|
||||
// 获取满足model中不为空的字段值条件的所有数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体
|
||||
// @param cond 条件
|
||||
ListByCondOrder(cond any, list any, order ...string) error
|
||||
|
||||
// 根据指定条件统计model表的数量, cond为条件可以为map等
|
||||
CountByCond(cond any) int64
|
||||
}
|
||||
|
||||
// 基础repo接口
|
||||
type RepoImpl[T any] struct {
|
||||
M any // 模型实例
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) Insert(e T) error {
|
||||
return gormx.Insert(e)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) InsertWithDb(db *gorm.DB, e T) error {
|
||||
return gormx.InsertWithDb(db, e)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) BatchInsert(es []T) error {
|
||||
return gormx.BatchInsert(es)
|
||||
}
|
||||
|
||||
// 使用指定gorm db执行,主要用于事务执行
|
||||
func (br *RepoImpl[T]) BatchInsertWithDb(db *gorm.DB, es []T) error {
|
||||
return gormx.BatchInsertWithDb(db, es)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) UpdateById(e T) error {
|
||||
return gormx.UpdateById(e)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) UpdateByIdWithDb(db *gorm.DB, e T) error {
|
||||
return gormx.UpdateByIdWithDb(db, e)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) Updates(cond any, udpateFields map[string]any) error {
|
||||
return gormx.Updates(cond, udpateFields)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) DeleteById(id uint64) error {
|
||||
return gormx.DeleteById(br.getModel(), id)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
|
||||
return gormx.DeleteByCondWithDb(db, br.getModel(), id)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) DeleteByCond(cond any) error {
|
||||
return gormx.DeleteByCond(br.getModel(), cond)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
|
||||
return gormx.DeleteByCondWithDb(db, br.getModel(), cond)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) GetById(e T, id uint64, cols ...string) error {
|
||||
if err := gormx.GetById(e, id, cols...); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) GetByIdIn(list any, ids []uint64, orderBy ...string) error {
|
||||
return gormx.GetByIdIn(br.getModel(), list, ids, orderBy...)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) GetBy(cond T, cols ...string) error {
|
||||
return gormx.GetBy(cond, cols...)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) ListByCond(cond any, listModels any, cols ...string) error {
|
||||
return gormx.ListByCond(br.getModel(), cond, listModels, cols...)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) ListByCondOrder(cond any, list any, order ...string) error {
|
||||
return gormx.ListByCondOrder(br.getModel(), cond, list, order...)
|
||||
}
|
||||
|
||||
func (br *RepoImpl[T]) CountByCond(cond any) int64 {
|
||||
return gormx.CountByCond(br.getModel(), cond)
|
||||
}
|
||||
|
||||
// 获取表的模型实例
|
||||
func (br *RepoImpl[T]) getModel() any {
|
||||
biz.IsTrue(br.M != nil, "base.RepoImpl的M字段不能为空")
|
||||
return br.M
|
||||
}
|
||||
@@ -2,43 +2,41 @@ package biz
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func ErrIsNil(err error, msg string, params ...any) {
|
||||
// 断言错误为ni
|
||||
// @param msgAndParams 消息与参数占位符,第一位为错误消息可包含%s等格式化标识。其余为Sprintf格式化值内容
|
||||
//
|
||||
// ErrIsNil(err)
|
||||
// ErrIsNil(err, "xxxx")
|
||||
// ErrIsNil(err, "xxxx: %s", "yyyy")
|
||||
func ErrIsNil(err error, msgAndParams ...any) {
|
||||
if err != nil {
|
||||
// logx.ErrorTrace(msg, err)
|
||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||
if len(msgAndParams) == 0 {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msgAndParams[0].(string), msgAndParams[1:]...)))
|
||||
}
|
||||
}
|
||||
|
||||
func ErrIsNilAppendErr(err error, msg string) {
|
||||
if err != nil {
|
||||
// logx.ErrorTrace(msg, err)
|
||||
panic(NewBizErr(fmt.Sprintf(msg, err.Error())))
|
||||
}
|
||||
}
|
||||
|
||||
func IsNil(err error) {
|
||||
switch t := err.(type) {
|
||||
case *BizError:
|
||||
panic(t)
|
||||
case error:
|
||||
logx.Error("非业务异常: " + err.Error())
|
||||
panic(NewBizErr(fmt.Sprintf("非业务异常: %s", err.Error())))
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msg, err.Error())))
|
||||
}
|
||||
}
|
||||
|
||||
func IsTrue(exp bool, msg string, params ...any) {
|
||||
if !exp {
|
||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msg, params...)))
|
||||
}
|
||||
}
|
||||
|
||||
func IsTrueBy(exp bool, err BizError) {
|
||||
func IsTrueBy(exp bool, err errorx.BizError) {
|
||||
if !exp {
|
||||
panic(err)
|
||||
}
|
||||
@@ -46,30 +44,30 @@ func IsTrueBy(exp bool, err BizError) {
|
||||
|
||||
func NotEmpty(str string, msg string, params ...any) {
|
||||
if str == "" {
|
||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msg, params...)))
|
||||
}
|
||||
}
|
||||
|
||||
func NotNil(data any, msg string, params ...any) {
|
||||
if reflect.ValueOf(data).IsNil() {
|
||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msg, params...)))
|
||||
}
|
||||
}
|
||||
|
||||
func NotBlank(data any, msg string, params ...any) {
|
||||
if anyx.IsBlank(data) {
|
||||
panic(NewBizErr(fmt.Sprintf(msg, params...)))
|
||||
panic(errorx.NewBiz(fmt.Sprintf(msg, params...)))
|
||||
}
|
||||
}
|
||||
|
||||
func IsEquals(data any, data1 any, msg string) {
|
||||
if data != data1 {
|
||||
panic(NewBizErr(msg))
|
||||
panic(errorx.NewBiz(msg))
|
||||
}
|
||||
}
|
||||
|
||||
func Nil(data any, msg string) {
|
||||
if !reflect.ValueOf(data).IsNil() {
|
||||
panic(NewBizErr(msg))
|
||||
panic(errorx.NewBiz(msg))
|
||||
}
|
||||
}
|
||||
|
||||
11
server/pkg/biz/assert_test.go
Normal file
11
server/pkg/biz/assert_test.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package biz
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestErrIsNil(t *testing.T) {
|
||||
// ErrIsNil(NewBizErr("xxx is error"))
|
||||
// ErrIsNil(NewBizErr("xxx is error"), "格式错误")
|
||||
// ErrIsNil(NewBizErr("xxx is error"), "格式错误: %s, %d", "xxx", 12)
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package biz
|
||||
|
||||
import "fmt"
|
||||
|
||||
// 业务错误
|
||||
type BizError struct {
|
||||
code int16
|
||||
err string
|
||||
}
|
||||
|
||||
var (
|
||||
Success BizError = NewBizErrCode(200, "success")
|
||||
BizErr BizError = NewBizErrCode(400, "biz error")
|
||||
ServerError BizError = NewBizErrCode(500, "server error")
|
||||
PermissionErr BizError = NewBizErrCode(501, "token error")
|
||||
)
|
||||
|
||||
// 错误消息
|
||||
func (e BizError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// 错误码
|
||||
func (e BizError) Code() int16 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e BizError) String() string {
|
||||
return fmt.Sprintf("errCode: %d, errMsg: %s", e.Code(), e.Error())
|
||||
}
|
||||
|
||||
// 创建业务逻辑错误结构体,默认为业务逻辑错误
|
||||
func NewBizErr(msg string) BizError {
|
||||
return BizError{code: BizErr.code, err: msg}
|
||||
}
|
||||
|
||||
// 创建业务逻辑错误结构体,可设置指定错误code
|
||||
func NewBizErrCode(code int16, msg string) BizError {
|
||||
return BizError{code: code, err: msg}
|
||||
}
|
||||
8
server/pkg/cache/str_cache.go
vendored
8
server/pkg/cache/str_cache.go
vendored
@@ -1,7 +1,6 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/rediscli"
|
||||
"strconv"
|
||||
@@ -41,13 +40,12 @@ func GetInt(key string) int {
|
||||
}
|
||||
|
||||
// 如果系统有设置redis信息,则使用redis存,否则存于本机内存。duration == -1则为永久缓存
|
||||
func SetStr(key, value string, duration time.Duration) {
|
||||
func SetStr(key, value string, duration time.Duration) error {
|
||||
if !useRedisCache() {
|
||||
checkCache()
|
||||
tm.Add(key, value, duration)
|
||||
return
|
||||
return tm.Add(key, value, duration)
|
||||
}
|
||||
biz.ErrIsNilAppendErr(rediscli.Set(key, value, duration), "redis set err: %s")
|
||||
return rediscli.Set(key, value, duration)
|
||||
}
|
||||
|
||||
// 删除指定key
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package captcha
|
||||
|
||||
import (
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/rediscli"
|
||||
"time"
|
||||
|
||||
@@ -12,7 +11,7 @@ var store base64Captcha.Store
|
||||
var driver base64Captcha.Driver = base64Captcha.DefaultDriverDigit
|
||||
|
||||
// 生成验证码
|
||||
func Generate() (string, string) {
|
||||
func Generate() (string, string, error) {
|
||||
if store == nil {
|
||||
if rediscli.GetCli() != nil {
|
||||
store = new(RedisStore)
|
||||
@@ -23,9 +22,7 @@ func Generate() (string, string) {
|
||||
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
// 获取
|
||||
id, b64s, err := c.Generate()
|
||||
biz.ErrIsNilAppendErr(err, "获取验证码错误: %s")
|
||||
return id, b64s
|
||||
return c.Generate()
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
|
||||
42
server/pkg/errorx/bizerror.go
Normal file
42
server/pkg/errorx/bizerror.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package errorx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 业务错误
|
||||
type BizError struct {
|
||||
code int16
|
||||
err string
|
||||
}
|
||||
|
||||
var (
|
||||
Success BizError = NewBizCode(200, "success")
|
||||
BizErr BizError = NewBizCode(400, "biz error")
|
||||
ServerError BizError = NewBizCode(500, "server error")
|
||||
PermissionErr BizError = NewBizCode(501, "token error")
|
||||
)
|
||||
|
||||
// 错误消息
|
||||
func (e BizError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// 错误码
|
||||
func (e BizError) Code() int16 {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e BizError) String() string {
|
||||
return fmt.Sprintf("errCode: %d, errMsg: %s", e.Code(), e.Error())
|
||||
}
|
||||
|
||||
// 创建业务逻辑错误结构体,默认为业务逻辑错误
|
||||
func NewBiz(msg string, formats ...any) BizError {
|
||||
return BizError{code: BizErr.code, err: fmt.Sprintf(msg, formats...)}
|
||||
}
|
||||
|
||||
// 创建业务逻辑错误结构体,可设置指定错误code
|
||||
func NewBizCode(code int16, msg string, formats ...any) BizError {
|
||||
return BizError{code: code, err: fmt.Sprintf(msg, formats...)}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package ginx
|
||||
import (
|
||||
"io"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/utils/structx"
|
||||
@@ -100,21 +101,21 @@ func SuccessRes(g *gin.Context, data any) {
|
||||
// 返回失败结果集
|
||||
func ErrorRes(g *gin.Context, err any) {
|
||||
switch t := err.(type) {
|
||||
case biz.BizError:
|
||||
case errorx.BizError:
|
||||
g.JSON(http.StatusOK, model.Error(t))
|
||||
case error:
|
||||
g.JSON(http.StatusOK, model.ServerError())
|
||||
case string:
|
||||
g.JSON(http.StatusOK, model.ServerError())
|
||||
default:
|
||||
logx.Error("未知错误", "errInfo", t)
|
||||
logx.Errorf("未知错误: %v", t)
|
||||
}
|
||||
}
|
||||
|
||||
// 转换参数校验错误为业务异常错误
|
||||
func ConvBindValidationError(data any, err error) error {
|
||||
if e, ok := err.(validator.ValidationErrors); ok {
|
||||
return biz.NewBizErrCode(403, validatorx.Translate2Str(data, e))
|
||||
return errorx.NewBizCode(403, validatorx.Translate2Str(data, e))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package gormx
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/global"
|
||||
"mayfly-go/pkg/model"
|
||||
"strings"
|
||||
@@ -26,8 +25,8 @@ func GetById(model any, id uint64, cols ...string) error {
|
||||
|
||||
// 根据id列表查询实体信息
|
||||
// @param model 数据库映射实体模型
|
||||
func GetByIdIn(model any, list any, ids []uint64, orderBy ...string) {
|
||||
NewQuery(model).In("id", ids).Undeleted().GenGdb().Find(list)
|
||||
func GetByIdIn(model any, list any, ids []uint64, orderBy ...string) error {
|
||||
return NewQuery(model).In("id", ids).Undeleted().GenGdb().Find(list).Error
|
||||
}
|
||||
|
||||
// 获取满足model中不为空的字段值条件的单个对象。model需为指针类型(需要将查询出来的值赋值给model)
|
||||
@@ -40,80 +39,102 @@ func GetBy(model any, cols ...string) error {
|
||||
|
||||
// 根据model指定条件统计数量
|
||||
func CountBy(model any) int64 {
|
||||
var count int64
|
||||
NewQuery(model).WithCondModel(model).Undeleted().GenGdb().Count(&count)
|
||||
return count
|
||||
return CountByCond(model, model)
|
||||
}
|
||||
|
||||
// 根据条件model指定条件统计数量
|
||||
func CountByCond(model any, condModel any) int64 {
|
||||
// 根据条件cond获取指定model表统计数量
|
||||
func CountByCond(model any, cond any) int64 {
|
||||
var count int64
|
||||
NewQuery(model).WithCondModel(condModel).Undeleted().GenGdb().Count(&count)
|
||||
NewQuery(model).WithCondModel(cond).Undeleted().GenGdb().Count(&count)
|
||||
return count
|
||||
}
|
||||
|
||||
// 根据查询条件分页查询数据
|
||||
// 若未指定查询列,则查询列以toModels字段为准
|
||||
func PageQuery[T any](q *QueryCond, pageParam *model.PageParam, toModels T) *model.PageResult[T] {
|
||||
func PageQuery[T any](q *QueryCond, pageParam *model.PageParam, toModels T) (*model.PageResult[T], error) {
|
||||
q.Undeleted()
|
||||
gdb := q.GenGdb()
|
||||
var count int64
|
||||
err := gdb.Count(&count).Error
|
||||
biz.ErrIsNilAppendErr(err, "查询错误: %s")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if count == 0 {
|
||||
return model.EmptyPageResult[T]()
|
||||
return model.EmptyPageResult[T](), nil
|
||||
}
|
||||
|
||||
page := pageParam.PageNum
|
||||
pageSize := pageParam.PageSize
|
||||
err = gdb.Limit(pageSize).Offset((page - 1) * pageSize).Find(toModels).Error
|
||||
biz.ErrIsNilAppendErr(err, "查询失败: %s")
|
||||
return &model.PageResult[T]{Total: count, List: toModels}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &model.PageResult[T]{Total: count, List: toModels}, nil
|
||||
}
|
||||
|
||||
// 获取满足model中不为空的字段值条件的所有数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体,即只包含需要返回的字段结构体
|
||||
func ListBy(model any, list any, cols ...string) {
|
||||
global.Db.Model(model).Select(cols).Where(model).Scopes(UndeleteScope).Order("id desc").Find(list)
|
||||
func ListBy(model any, list any, cols ...string) error {
|
||||
return ListByCond(model, model, list, cols...)
|
||||
}
|
||||
|
||||
// 获取满足cond中不为空的字段值条件的所有model表数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体,即只包含需要返回的字段结构体
|
||||
func ListByCond(model any, cond any, list any, cols ...string) error {
|
||||
return global.Db.Model(model).Select(cols).Where(cond).Scopes(UndeleteScope).Order("id desc").Find(list).Error
|
||||
}
|
||||
|
||||
// 获取满足model中不为空的字段值条件的所有数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体
|
||||
// @param model 数据库映射实体模型
|
||||
func ListByOrder(model any, list any, order ...string) {
|
||||
func ListByOrder(model any, list any, order ...string) error {
|
||||
return ListByCondOrder(model, model, list, order...)
|
||||
}
|
||||
|
||||
// 获取满足cond中不为空的字段值条件的所有model表数据.
|
||||
//
|
||||
// @param list为数组类型 如 var users *[]User,可指定为非model结构体
|
||||
// @param model 数据库映射实体模型
|
||||
func ListByCondOrder(model any, cond any, list any, order ...string) error {
|
||||
var orderByStr string
|
||||
if order == nil {
|
||||
orderByStr = "id desc"
|
||||
} else {
|
||||
orderByStr = strings.Join(order, ",")
|
||||
}
|
||||
global.Db.Model(model).Where(model).Scopes(UndeleteScope).Order(orderByStr).Find(list)
|
||||
return global.Db.Model(model).Where(cond).Scopes(UndeleteScope).Order(orderByStr).Find(list).Error
|
||||
}
|
||||
|
||||
func GetListBySql2Model(sql string, toEntity any, params ...any) error {
|
||||
return global.Db.Raw(sql, params...).Find(toEntity).Error
|
||||
}
|
||||
|
||||
func ExecSql(sql string, params ...any) {
|
||||
global.Db.Exec(sql, params...)
|
||||
func ExecSql(sql string, params ...any) error {
|
||||
return global.Db.Exec(sql, params...).Error
|
||||
}
|
||||
|
||||
// 插入model
|
||||
// @param model 数据库映射实体模型
|
||||
func Insert(model any) error {
|
||||
return InsertWithDb(*global.Db, model)
|
||||
return InsertWithDb(global.Db, model)
|
||||
}
|
||||
|
||||
// 使用指定gormDb插入model
|
||||
func InsertWithDb(db gorm.DB, model any) error {
|
||||
func InsertWithDb(db *gorm.DB, model any) error {
|
||||
return db.Create(model).Error
|
||||
}
|
||||
|
||||
// 批量插入
|
||||
func BatchInsert[T any](models []T) {
|
||||
global.Db.CreateInBatches(models, len(models))
|
||||
func BatchInsert[T any](models []T) error {
|
||||
return BatchInsertWithDb[T](global.Db, models)
|
||||
}
|
||||
|
||||
// 批量插入
|
||||
func BatchInsertWithDb[T any](db *gorm.DB, models []T) error {
|
||||
return db.CreateInBatches(models, len(models)).Error
|
||||
}
|
||||
|
||||
// 根据id更新model,更新字段为model中不为空的值,即int类型不为0,ptr类型不为nil这类字段值
|
||||
@@ -142,16 +163,32 @@ func DeleteByIdWithDb(db *gorm.DB, model_ any, id uint64) error {
|
||||
return db.Model(model_).Where("id = ?", id).Updates(getDeleteColumnValue()).Error
|
||||
}
|
||||
|
||||
// 根据条件删除
|
||||
// 根据model条件删除
|
||||
// @param model 数据库映射实体模型
|
||||
func DeleteByCondition(model_ any) error {
|
||||
return DeleteByConditionWithDb(global.Db, model_)
|
||||
func DeleteBy(model_ any) error {
|
||||
return DeleteByCond(model_, model_)
|
||||
}
|
||||
|
||||
// 根据条件使用指定gromDb删除
|
||||
// 根据cond条件删除指定model表数据
|
||||
//
|
||||
// @param model_ 数据库映射实体模型
|
||||
// @param cond 条件
|
||||
func DeleteByCond(model_ any, cond any) error {
|
||||
return DeleteByCondWithDb(global.Db, model_, cond)
|
||||
}
|
||||
|
||||
// 根据model条件删除
|
||||
// @param model 数据库映射实体模型
|
||||
func DeleteByConditionWithDb(db *gorm.DB, model_ any) error {
|
||||
return db.Model(model_).Where(model_).Updates(getDeleteColumnValue()).Error
|
||||
func DeleteByWithDb(db *gorm.DB, model_ any) error {
|
||||
return DeleteByCondWithDb(db, model_, model_)
|
||||
}
|
||||
|
||||
// 根据cond条件删除指定model表数据
|
||||
//
|
||||
// @param model 数据库映射实体模型
|
||||
// @param cond 条件
|
||||
func DeleteByCondWithDb(db *gorm.DB, model_ any, cond any) error {
|
||||
return db.Model(model_).Where(cond).Updates(getDeleteColumnValue()).Error
|
||||
}
|
||||
|
||||
func getDeleteColumnValue() map[string]any {
|
||||
|
||||
@@ -3,7 +3,7 @@ package model
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/errorx"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -44,17 +44,17 @@ func SuccessNoData() *Result {
|
||||
return &Result{Code: SuccessCode, Msg: SuccessMsg}
|
||||
}
|
||||
|
||||
func Error(bizerr biz.BizError) *Result {
|
||||
func Error(bizerr errorx.BizError) *Result {
|
||||
return &Result{Code: bizerr.Code(), Msg: bizerr.Error()}
|
||||
}
|
||||
|
||||
// 返回服务器错误Result
|
||||
func ServerError() *Result {
|
||||
return Error(biz.ServerError)
|
||||
return Error(errorx.ServerError)
|
||||
}
|
||||
|
||||
func TokenError() *Result {
|
||||
return Error(biz.PermissionErr)
|
||||
return Error(errorx.PermissionErr)
|
||||
}
|
||||
|
||||
func ErrorBy(code int16, msg string) *Result {
|
||||
|
||||
@@ -2,7 +2,7 @@ package req
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/logx"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
"mayfly-go/pkg/utils/runtimex"
|
||||
@@ -76,7 +76,7 @@ func LogHandler(rc *Ctx) error {
|
||||
|
||||
if rc.Err != nil {
|
||||
nFrames := DefaultLogFrames
|
||||
if _, ok := rc.Err.(biz.BizError); ok {
|
||||
if _, ok := rc.Err.(errorx.BizError); ok {
|
||||
nFrames = nFrames / 2
|
||||
}
|
||||
attrMap["error"] = rc.Err
|
||||
@@ -123,7 +123,7 @@ func getErrMsg(rc *Ctx, err any) string {
|
||||
nFrames := DefaultLogFrames
|
||||
var errMsg string
|
||||
switch t := err.(type) {
|
||||
case biz.BizError:
|
||||
case errorx.BizError:
|
||||
errMsg = fmt.Sprintf("\n<-e %s", t.String())
|
||||
nFrames = nFrames / 2
|
||||
case error:
|
||||
|
||||
@@ -3,9 +3,9 @@ package req
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/cache"
|
||||
"mayfly-go/pkg/config"
|
||||
"mayfly-go/pkg/errorx"
|
||||
"mayfly-go/pkg/model"
|
||||
"mayfly-go/pkg/rediscli"
|
||||
"mayfly-go/pkg/utils/anyx"
|
||||
@@ -48,16 +48,16 @@ func PermissionHandler(rc *Ctx) error {
|
||||
tokenStr = rc.GinCtx.Query("token")
|
||||
}
|
||||
if tokenStr == "" {
|
||||
return biz.PermissionErr
|
||||
return errorx.PermissionErr
|
||||
}
|
||||
userId, userName, err := ParseToken(tokenStr)
|
||||
if err != nil || userId == 0 {
|
||||
return biz.PermissionErr
|
||||
return errorx.PermissionErr
|
||||
}
|
||||
// 权限不为nil,并且permission code不为空,则校验是否有权限code
|
||||
if permission != nil && permission.Code != "" {
|
||||
if !permissionCodeRegistry.HasCode(userId, permission.Code) {
|
||||
return biz.PermissionErr
|
||||
return errorx.PermissionErr
|
||||
}
|
||||
}
|
||||
if rc.LoginAccount == nil {
|
||||
|
||||
@@ -2,7 +2,6 @@ package req
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/config"
|
||||
"time"
|
||||
|
||||
@@ -10,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
// 创建用户token
|
||||
func CreateToken(userId uint64, username string) string {
|
||||
func CreateToken(userId uint64, username string) (string, error) {
|
||||
// 带权限创建令牌
|
||||
// 设置有效期,过期需要重新登录获取token
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
||||
@@ -21,8 +20,10 @@ func CreateToken(userId uint64, username string) string {
|
||||
|
||||
// 使用自定义字符串加密 and get the complete encoded token as a string
|
||||
tokenString, err := token.SignedString([]byte(config.Conf.Jwt.Key))
|
||||
biz.ErrIsNilAppendErr(err, "token创建失败: %s")
|
||||
return tokenString
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return tokenString, nil
|
||||
}
|
||||
|
||||
// 解析token,并返回登录者账号信息
|
||||
@@ -38,6 +39,9 @@ func ParseToken(tokenStr string) (uint64, string, error) {
|
||||
if err != nil || token == nil {
|
||||
return 0, "", err
|
||||
}
|
||||
if !token.Valid {
|
||||
return 0, "", errors.New("token invalid")
|
||||
}
|
||||
i := token.Claims.(jwt.MapClaims)
|
||||
return uint64(i["id"].(float64)), i["username"].(string), nil
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func ToString(value any) string {
|
||||
case uint64:
|
||||
return strconv.FormatUint(it, 10)
|
||||
case []byte:
|
||||
return string(value.([]byte))
|
||||
return string(it)
|
||||
default:
|
||||
newValue, _ := json.Marshal(value)
|
||||
return string(newValue)
|
||||
|
||||
@@ -129,7 +129,9 @@ func (manager *ClientManager) WriteMessage() {
|
||||
if cid != "" {
|
||||
cli := manager.GetByUidAndCid(uid, cid)
|
||||
if cli != nil {
|
||||
cli.WriteMsg(msg)
|
||||
if err := cli.WriteMsg(msg); err != nil {
|
||||
logx.Warnf("ws消息发送失败[uid=%d, cid=%s]: %s", uid, cid, err.Error())
|
||||
}
|
||||
} else {
|
||||
logx.Warnf("[uid=%v, cid=%s]的ws连接不存在", uid, cid)
|
||||
}
|
||||
@@ -138,7 +140,9 @@ func (manager *ClientManager) WriteMessage() {
|
||||
|
||||
// cid为空,则向该用户所有客户端发送该消息
|
||||
for _, cli := range manager.GetByUid(uid) {
|
||||
cli.WriteMsg(msg)
|
||||
if err := cli.WriteMsg(msg); err != nil {
|
||||
logx.Warnf("ws消息发送失败[uid=%d, cid=%s]: %s", uid, cli.ClientId, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
Reference in New Issue
Block a user