mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	feat: 机器列表新增运行状态 & refactor: 登录账号信息存储与context
This commit is contained in:
		@@ -1,44 +1,47 @@
 | 
			
		||||
package base
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 基础application接口
 | 
			
		||||
type App[T any] interface {
 | 
			
		||||
type App[T model.ModelI] interface {
 | 
			
		||||
 | 
			
		||||
	// 新增一个实体
 | 
			
		||||
	Insert(e T) error
 | 
			
		||||
	Insert(ctx context.Context, e T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	InsertWithDb(db *gorm.DB, e T) error
 | 
			
		||||
	InsertWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
			
		||||
 | 
			
		||||
	// 批量新增实体
 | 
			
		||||
	BatchInsert(models []T) error
 | 
			
		||||
	BatchInsert(ctx context.Context, models []T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	BatchInsertWithDb(db *gorm.DB, es []T) error
 | 
			
		||||
	BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体id更新实体信息
 | 
			
		||||
	UpdateById(e T) error
 | 
			
		||||
	UpdateById(ctx context.Context, e T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	UpdateByIdWithDb(db *gorm.DB, e T) error
 | 
			
		||||
	UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体主键删除实体
 | 
			
		||||
	DeleteById(id uint64) error
 | 
			
		||||
	DeleteById(ctx context.Context, id uint64) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	DeleteByIdWithDb(db *gorm.DB, id uint64) error
 | 
			
		||||
	DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体条件,更新参数udpateFields指定字段
 | 
			
		||||
	Updates(cond any, udpateFields map[string]any) error
 | 
			
		||||
	Updates(ctx context.Context, cond any, udpateFields map[string]any) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体条件删除实体
 | 
			
		||||
	DeleteByCond(cond any) error
 | 
			
		||||
	DeleteByCond(ctx context.Context, cond any) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	DeleteByCondWithDb(db *gorm.DB, cond any) error
 | 
			
		||||
	DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体id查询
 | 
			
		||||
	GetById(e T, id uint64, cols ...string) (T, error)
 | 
			
		||||
@@ -62,7 +65,7 @@ type App[T any] interface {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 基础application接口实现
 | 
			
		||||
type AppImpl[T any, R Repo[T]] struct {
 | 
			
		||||
type AppImpl[T model.ModelI, R Repo[T]] struct {
 | 
			
		||||
	Repo R // repo接口
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -72,57 +75,57 @@ func (ai *AppImpl[T, R]) GetRepo() R {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 新增一个实体 (单纯新增,不做其他业务逻辑处理)
 | 
			
		||||
func (ai *AppImpl[T, R]) Insert(e T) error {
 | 
			
		||||
	return ai.GetRepo().Insert(e)
 | 
			
		||||
func (ai *AppImpl[T, R]) Insert(ctx context.Context, e T) error {
 | 
			
		||||
	return ai.GetRepo().Insert(ctx, e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
func (ai *AppImpl[T, R]) InsertWithDb(db *gorm.DB, e T) error {
 | 
			
		||||
	return ai.GetRepo().InsertWithDb(db, e)
 | 
			
		||||
func (ai *AppImpl[T, R]) InsertWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
			
		||||
	return ai.GetRepo().InsertWithDb(ctx, db, e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 批量新增实体 (单纯新增,不做其他业务逻辑处理)
 | 
			
		||||
func (ai *AppImpl[T, R]) BatchInsert(es []T) error {
 | 
			
		||||
	return ai.GetRepo().BatchInsert(es)
 | 
			
		||||
func (ai *AppImpl[T, R]) BatchInsert(ctx context.Context, es []T) error {
 | 
			
		||||
	return ai.GetRepo().BatchInsert(ctx, es)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
func (ai *AppImpl[T, R]) BatchInsertWithDb(db *gorm.DB, es []T) error {
 | 
			
		||||
	return ai.GetRepo().BatchInsertWithDb(db, es)
 | 
			
		||||
func (ai *AppImpl[T, R]) BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error {
 | 
			
		||||
	return ai.GetRepo().BatchInsertWithDb(ctx, db, es)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据实体id更新实体信息 (单纯更新,不做其他业务逻辑处理)
 | 
			
		||||
func (ai *AppImpl[T, R]) UpdateById(e T) error {
 | 
			
		||||
	return ai.GetRepo().UpdateById(e)
 | 
			
		||||
func (ai *AppImpl[T, R]) UpdateById(ctx context.Context, e T) error {
 | 
			
		||||
	return ai.GetRepo().UpdateById(ctx, e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
func (ai *AppImpl[T, R]) UpdateByIdWithDb(db *gorm.DB, e T) error {
 | 
			
		||||
	return ai.GetRepo().UpdateByIdWithDb(db, e)
 | 
			
		||||
func (ai *AppImpl[T, R]) UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
			
		||||
	return ai.GetRepo().UpdateByIdWithDb(ctx, db, e)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据实体条件,更新参数udpateFields指定字段 (单纯更新,不做其他业务逻辑处理)
 | 
			
		||||
func (ai *AppImpl[T, R]) Updates(cond any, udpateFields map[string]any) error {
 | 
			
		||||
func (ai *AppImpl[T, R]) Updates(ctx context.Context, 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]) DeleteById(ctx context.Context, id uint64) error {
 | 
			
		||||
	return ai.GetRepo().DeleteById(ctx, id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCondWithDb(db, id)
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCondWithDb(ctx, db, id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据指定条件删除实体 (单纯删除实体,不做其他业务逻辑处理)
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByCond(cond any) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCond(cond)
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByCond(ctx context.Context, cond any) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCond(ctx, cond)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCondWithDb(db, cond)
 | 
			
		||||
func (ai *AppImpl[T, R]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
 | 
			
		||||
	return ai.GetRepo().DeleteByCondWithDb(ctx, db, cond)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据实体id查询
 | 
			
		||||
 
 | 
			
		||||
@@ -1,47 +1,50 @@
 | 
			
		||||
package base
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"mayfly-go/pkg/biz"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/gormx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
 | 
			
		||||
	"gorm.io/gorm"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 基础repo接口
 | 
			
		||||
type Repo[T any] interface {
 | 
			
		||||
type Repo[T model.ModelI] interface {
 | 
			
		||||
 | 
			
		||||
	// 新增一个实体
 | 
			
		||||
	Insert(e T) error
 | 
			
		||||
	Insert(ctx context.Context, e T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	InsertWithDb(db *gorm.DB, e T) error
 | 
			
		||||
	InsertWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
			
		||||
 | 
			
		||||
	// 批量新增实体
 | 
			
		||||
	BatchInsert(models []T) error
 | 
			
		||||
	BatchInsert(ctx context.Context, models []T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	BatchInsertWithDb(db *gorm.DB, es []T) error
 | 
			
		||||
	BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体id更新实体信息
 | 
			
		||||
	UpdateById(e T) error
 | 
			
		||||
	UpdateById(ctx context.Context, e T) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	UpdateByIdWithDb(db *gorm.DB, e T) error
 | 
			
		||||
	UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体主键删除实体
 | 
			
		||||
	DeleteById(id uint64) error
 | 
			
		||||
	DeleteById(ctx context.Context, id uint64) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	DeleteByIdWithDb(db *gorm.DB, id uint64) error
 | 
			
		||||
	DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体条件,更新参数udpateFields指定字段
 | 
			
		||||
	Updates(cond any, udpateFields map[string]any) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体条件删除实体
 | 
			
		||||
	DeleteByCond(cond any) error
 | 
			
		||||
	DeleteByCond(ctx context.Context, cond any) error
 | 
			
		||||
 | 
			
		||||
	// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
	DeleteByCondWithDb(db *gorm.DB, cond any) error
 | 
			
		||||
	DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error
 | 
			
		||||
 | 
			
		||||
	// 根据实体id查询
 | 
			
		||||
	GetById(e T, id uint64, cols ...string) error
 | 
			
		||||
@@ -66,52 +69,58 @@ type Repo[T any] interface {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 基础repo接口
 | 
			
		||||
type RepoImpl[T any] struct {
 | 
			
		||||
type RepoImpl[T model.ModelI] struct {
 | 
			
		||||
	M any // 模型实例
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) Insert(e T) error {
 | 
			
		||||
	return gormx.Insert(e)
 | 
			
		||||
func (br *RepoImpl[T]) Insert(ctx context.Context, e T) error {
 | 
			
		||||
	return gormx.Insert(br.setBaseInfo(ctx, e))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) InsertWithDb(db *gorm.DB, e T) error {
 | 
			
		||||
	return gormx.InsertWithDb(db, e)
 | 
			
		||||
func (br *RepoImpl[T]) InsertWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
			
		||||
	return gormx.InsertWithDb(db, br.setBaseInfo(ctx, e))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) BatchInsert(es []T) error {
 | 
			
		||||
func (br *RepoImpl[T]) BatchInsert(ctx context.Context, es []T) error {
 | 
			
		||||
	for _, e := range es {
 | 
			
		||||
		br.setBaseInfo(ctx, e)
 | 
			
		||||
	}
 | 
			
		||||
	return gormx.BatchInsert(es)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 使用指定gorm db执行,主要用于事务执行
 | 
			
		||||
func (br *RepoImpl[T]) BatchInsertWithDb(db *gorm.DB, es []T) error {
 | 
			
		||||
func (br *RepoImpl[T]) BatchInsertWithDb(ctx context.Context, db *gorm.DB, es []T) error {
 | 
			
		||||
	for _, e := range es {
 | 
			
		||||
		br.setBaseInfo(ctx, e)
 | 
			
		||||
	}
 | 
			
		||||
	return gormx.BatchInsertWithDb(db, es)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) UpdateById(e T) error {
 | 
			
		||||
	return gormx.UpdateById(e)
 | 
			
		||||
func (br *RepoImpl[T]) UpdateById(ctx context.Context, e T) error {
 | 
			
		||||
	return gormx.UpdateById(br.setBaseInfo(ctx, e))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) UpdateByIdWithDb(db *gorm.DB, e T) error {
 | 
			
		||||
	return gormx.UpdateByIdWithDb(db, e)
 | 
			
		||||
func (br *RepoImpl[T]) UpdateByIdWithDb(ctx context.Context, db *gorm.DB, e T) error {
 | 
			
		||||
	return gormx.UpdateByIdWithDb(db, br.setBaseInfo(ctx, 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 {
 | 
			
		||||
func (br *RepoImpl[T]) DeleteById(ctx context.Context, id uint64) error {
 | 
			
		||||
	return gormx.DeleteById(br.getModel(), id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByIdWithDb(db *gorm.DB, id uint64) error {
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByIdWithDb(ctx context.Context, db *gorm.DB, id uint64) error {
 | 
			
		||||
	return gormx.DeleteByCondWithDb(db, br.getModel(), id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByCond(cond any) error {
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByCond(ctx context.Context, cond any) error {
 | 
			
		||||
	return gormx.DeleteByCond(br.getModel(), cond)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByCondWithDb(db *gorm.DB, cond any) error {
 | 
			
		||||
func (br *RepoImpl[T]) DeleteByCondWithDb(ctx context.Context, db *gorm.DB, cond any) error {
 | 
			
		||||
	return gormx.DeleteByCondWithDb(db, br.getModel(), cond)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -147,3 +156,11 @@ func (br *RepoImpl[T]) getModel() any {
 | 
			
		||||
	biz.IsTrue(br.M != nil, "base.RepoImpl的M字段不能为空")
 | 
			
		||||
	return br.M
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 从上下文获取登录账号信息,并赋值至实体
 | 
			
		||||
func (br *RepoImpl[T]) setBaseInfo(ctx context.Context, e T) T {
 | 
			
		||||
	if la := contextx.GetLoginAccount(ctx); la != nil {
 | 
			
		||||
		e.SetBaseInfo(la)
 | 
			
		||||
	}
 | 
			
		||||
	return e
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,9 +21,12 @@ func WithLoginAccount(ctx context.Context, la *model.LoginAccount) context.Conte
 | 
			
		||||
	return context.WithValue(ctx, LoginAccountKey, la)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 从context中获取登录账号信息
 | 
			
		||||
// 从context中获取登录账号信息,不存在返回nil
 | 
			
		||||
func GetLoginAccount(ctx context.Context) *model.LoginAccount {
 | 
			
		||||
	return ctx.Value(LoginAccountKey).(*model.LoginAccount)
 | 
			
		||||
	if la, ok := ctx.Value(LoginAccountKey).(*model.LoginAccount); ok {
 | 
			
		||||
		return la
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewTraceId() context.Context {
 | 
			
		||||
@@ -31,10 +34,13 @@ func NewTraceId() context.Context {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func WithTraceId(ctx context.Context) context.Context {
 | 
			
		||||
	return context.WithValue(ctx, TraceIdKey, stringx.Rand(16))
 | 
			
		||||
	return context.WithValue(ctx, TraceIdKey, stringx.RandByChars(16, stringx.Nums+stringx.LowerChars))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 从context中获取traceId
 | 
			
		||||
func GetTraceId(ctx context.Context) string {
 | 
			
		||||
	return ctx.Value(TraceIdKey).(string)
 | 
			
		||||
	if val, ok := ctx.Value(TraceIdKey).(string); ok {
 | 
			
		||||
		return val
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"log/slog"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/utils/runtimex"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"runtime"
 | 
			
		||||
@@ -47,7 +48,7 @@ func Debugf(format string, args ...any) {
 | 
			
		||||
	Log(context.Background(), slog.LevelDebug, fmt.Sprintf(format, args...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DebugWithFields(msg string, mapFields map[string]any) {
 | 
			
		||||
func DebugWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
			
		||||
	Log(context.Background(), slog.LevelDebug, msg, map2Attrs(mapFields)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -68,8 +69,8 @@ func Infof(format string, args ...any) {
 | 
			
		||||
	Log(context.Background(), slog.LevelInfo, fmt.Sprintf(format, args...))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func InfoWithFields(msg string, mapFields map[string]any) {
 | 
			
		||||
	Log(context.Background(), slog.LevelInfo, msg, map2Attrs(mapFields)...)
 | 
			
		||||
func InfoWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
			
		||||
	Log(ctx, slog.LevelInfo, msg, map2Attrs(mapFields)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Warn(msg string, args ...any) {
 | 
			
		||||
@@ -97,8 +98,8 @@ func ErrorTrace(msg string, err error) {
 | 
			
		||||
	Log(context.Background(), slog.LevelError, fmt.Sprintf(msg+" %s\n%s", err.Error(), runtimex.StatckStr(2, 10)))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ErrorWithFields(msg string, mapFields map[string]any) {
 | 
			
		||||
	Log(context.Background(), slog.LevelError, msg, map2Attrs(mapFields)...)
 | 
			
		||||
func ErrorWithFields(ctx context.Context, msg string, mapFields map[string]any) {
 | 
			
		||||
	Log(ctx, slog.LevelError, msg, map2Attrs(mapFields)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Panic(msg string, args ...any) {
 | 
			
		||||
@@ -120,6 +121,10 @@ func Log(ctx context.Context, level slog.Level, msg string, args ...any) {
 | 
			
		||||
func getCommonAttr(ctx context.Context, level slog.Level) []any {
 | 
			
		||||
	commonAttrs := make([]any, 0)
 | 
			
		||||
 | 
			
		||||
	// 尝试从上下文获取traceId,若存在则记录
 | 
			
		||||
	if traceId := contextx.GetTraceId(ctx); traceId != "" {
 | 
			
		||||
		commonAttrs = append(commonAttrs, "tid", traceId)
 | 
			
		||||
	}
 | 
			
		||||
	// 如果系统配置添加方法信息或者为错误级别时则 记录方法信息及行号
 | 
			
		||||
	if GetConfig().AddSource || level == slog.LevelError {
 | 
			
		||||
		// skip [runtime.Callers, getCommonAttr, appendCommonAttr, logx.Log, logx.Info|Debug|Warn|Error..]
 | 
			
		||||
 
 | 
			
		||||
@@ -12,6 +12,15 @@ const (
 | 
			
		||||
	ModelUndeleted   int8 = 0
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 实体接口
 | 
			
		||||
type ModelI interface {
 | 
			
		||||
 | 
			
		||||
	// 使用当前登录账号信息设置实体结构体的基础信息
 | 
			
		||||
	//
 | 
			
		||||
	// 如创建时间,修改时间,创建者,修改者信息
 | 
			
		||||
	SetBaseInfo(account *LoginAccount)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 含有删除字段模型
 | 
			
		||||
type DeletedModel struct {
 | 
			
		||||
	Id         uint64     `json:"id"`
 | 
			
		||||
@@ -19,6 +28,13 @@ type DeletedModel struct {
 | 
			
		||||
	DeleteTime *time.Time `json:"-"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *DeletedModel) SetBaseInfo(account *LoginAccount) {
 | 
			
		||||
	isCreate := m.Id == 0
 | 
			
		||||
	if isCreate {
 | 
			
		||||
		m.IsDeleted = ModelUndeleted
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 基础实体模型,数据表最基础字段,每张表必备字段
 | 
			
		||||
type Model struct {
 | 
			
		||||
	DeletedModel
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package req
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/errorx"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
	"mayfly-go/pkg/utils/anyx"
 | 
			
		||||
@@ -54,7 +55,7 @@ func LogHandler(rc *Ctx) error {
 | 
			
		||||
	req := rc.GinCtx.Request
 | 
			
		||||
	attrMap[req.Method] = req.URL.Path
 | 
			
		||||
 | 
			
		||||
	if la := rc.LoginAccount; la != nil {
 | 
			
		||||
	if la := contextx.GetLoginAccount(rc.MetaCtx); la != nil {
 | 
			
		||||
		attrMap["uid"] = la.Id
 | 
			
		||||
		attrMap["uname"] = la.Username
 | 
			
		||||
	}
 | 
			
		||||
@@ -93,10 +94,10 @@ func LogHandler(rc *Ctx) error {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := rc.Err; err != nil {
 | 
			
		||||
		logx.ErrorWithFields(logMsg, attrMap)
 | 
			
		||||
		logx.ErrorWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	logx.InfoWithFields(logMsg, attrMap)
 | 
			
		||||
	logx.InfoWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/cache"
 | 
			
		||||
	"mayfly-go/pkg/config"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/errorx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"mayfly-go/pkg/rediscli"
 | 
			
		||||
@@ -60,12 +61,10 @@ func PermissionHandler(rc *Ctx) error {
 | 
			
		||||
			return errorx.PermissionErr
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if rc.LoginAccount == nil {
 | 
			
		||||
		rc.LoginAccount = &model.LoginAccount{
 | 
			
		||||
			Id:       userId,
 | 
			
		||||
			Username: userName,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	rc.MetaCtx = contextx.WithLoginAccount(rc.MetaCtx, &model.LoginAccount{
 | 
			
		||||
		Id:       userId,
 | 
			
		||||
		Username: userName,
 | 
			
		||||
	})
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,10 @@
 | 
			
		||||
package req
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"context"
 | 
			
		||||
	"io"
 | 
			
		||||
	"mayfly-go/pkg/biz"
 | 
			
		||||
	"mayfly-go/pkg/contextx"
 | 
			
		||||
	"mayfly-go/pkg/ginx"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"mayfly-go/pkg/utils/assert"
 | 
			
		||||
@@ -16,12 +19,13 @@ type HandlerFunc func(*Ctx)
 | 
			
		||||
type Ctx struct {
 | 
			
		||||
	Conf *Conf // 请求配置
 | 
			
		||||
 | 
			
		||||
	GinCtx       *gin.Context        // gin context
 | 
			
		||||
	LoginAccount *model.LoginAccount // 登录账号信息,只有校验token后才会有值
 | 
			
		||||
	ReqParam     any                 // 请求参数,主要用于记录日志
 | 
			
		||||
	ResData      any                 // 响应结果
 | 
			
		||||
	Err          any                 // 请求错误
 | 
			
		||||
	timed        int64               // 执行时间
 | 
			
		||||
	GinCtx   *gin.Context // gin context
 | 
			
		||||
	ReqParam any          // 请求参数,主要用于记录日志
 | 
			
		||||
	ResData  any          // 响应结果
 | 
			
		||||
	Err      any          // 请求错误
 | 
			
		||||
	timed    int64        // 执行时间
 | 
			
		||||
 | 
			
		||||
	MetaCtx context.Context // 元数据上下文信息,如登录账号(只有校验token后才会有值),traceId等
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rc *Ctx) Handle(handler HandlerFunc) {
 | 
			
		||||
@@ -59,6 +63,15 @@ func (rc *Ctx) Download(reader io.Reader, filename string) {
 | 
			
		||||
	ginx.Download(rc.GinCtx, reader, filename)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 获取当前登录账号信息,不存在则会报错。
 | 
			
		||||
//
 | 
			
		||||
// 若不需要报错,则使用contextx.GetLoginAccount方法
 | 
			
		||||
func (rc *Ctx) GetLoginAccount() *model.LoginAccount {
 | 
			
		||||
	la := contextx.GetLoginAccount(rc.MetaCtx)
 | 
			
		||||
	biz.IsTrue(la != nil, "获取登录账号信息失败, 请确认该接口是否通过鉴权")
 | 
			
		||||
	return la
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (rc *Ctx) WithConf(conf *Conf) *Ctx {
 | 
			
		||||
	rc.Conf = conf
 | 
			
		||||
	return rc
 | 
			
		||||
@@ -87,7 +100,7 @@ func (rc *Ctx) GetLogInfo() *LogInfo {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewCtxWithGin(g *gin.Context) *Ctx {
 | 
			
		||||
	return &Ctx{GinCtx: g}
 | 
			
		||||
	return &Ctx{GinCtx: g, MetaCtx: contextx.NewTraceId()}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 处理器拦截器函数
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,11 @@ func ToMap(jsonStr string) map[string]any {
 | 
			
		||||
	return ToMapByBytes([]byte(jsonStr))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// json字符串转结构体
 | 
			
		||||
func To[T any](jsonStr string, res T) (T, error) {
 | 
			
		||||
	return res, json.Unmarshal([]byte(jsonStr), &res)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// json字节数组转map
 | 
			
		||||
func ToMapByBytes(bytes []byte) map[string]any {
 | 
			
		||||
	var res map[string]any
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,18 @@ import (
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const randChar = "0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
			
		||||
const Nums = "0123456789"
 | 
			
		||||
const LowerChars = "abcdefghigklmnopqrstuvwxyz"
 | 
			
		||||
const UpperChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 | 
			
		||||
 | 
			
		||||
// 生成随机字符串
 | 
			
		||||
func Rand(l int) string {
 | 
			
		||||
	strList := []byte(randChar)
 | 
			
		||||
	return RandByChars(l, Nums+LowerChars+UpperChars)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 根据传入的chars,随机生成指定位数的字符串
 | 
			
		||||
func RandByChars(l int, chars string) string {
 | 
			
		||||
	strList := []byte(chars)
 | 
			
		||||
 | 
			
		||||
	result := []byte{}
 | 
			
		||||
	i := 0
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								server/pkg/utils/stringx/template_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								server/pkg/utils/stringx/template_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
			
		||||
package stringx
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/utils/collx"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestTemplateParse(t *testing.T) {
 | 
			
		||||
	tmpl := `
 | 
			
		||||
	{{if gt .cpu 10*5}}
 | 
			
		||||
		当前服务器[{{.asset.host}}]cpu使用率为{{.cpu}}
 | 
			
		||||
	{{end}}
 | 
			
		||||
	`
 | 
			
		||||
	vars := collx.M{
 | 
			
		||||
		"cpu": 60,
 | 
			
		||||
		"asset": collx.M{
 | 
			
		||||
			"host": "localhost:121",
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	res, _ := TemplateParse(tmpl, vars)
 | 
			
		||||
	res2 := strings.TrimSpace(res)
 | 
			
		||||
	fmt.Println(res2)
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user