feat: Add English comments

This commit is contained in:
chris
2023-07-20 10:09:32 +08:00
parent cf8036ef16
commit 82b028a21a
11 changed files with 39 additions and 80 deletions

View File

@@ -21,7 +21,7 @@ log:
log_level: debug log_level: debug
encoding: console # json or console encoding: console # json or console
log_file_name: "./storage/logs/server.log" log_file_name: "./storage/logs/server.log"
max_backups: 30 # 日志文件最多保存多少个备份 max_backups: 30
max_age: 7 # 文件最多保存多少天 max_age: 7
max_size: 1024 # 每个日志文件保存的最大尺寸 单位M max_size: 1024
compress: true # 是否压缩 compress: true

View File

@@ -21,7 +21,7 @@ log:
log_level: info log_level: info
encoding: json # json or console encoding: json # json or console
log_file_name: "./storage/logs/server.log" log_file_name: "./storage/logs/server.log"
max_backups: 30 # 日志文件最多保存多少个备份 max_backups: 30
max_age: 7 # 文件最多保存多少天 max_age: 7
max_size: 1024 # 每个日志文件保存的最大尺寸 单位M max_size: 1024
compress: true # 是否压缩 compress: true

View File

@@ -17,7 +17,7 @@ import (
func RequestLogMiddleware(logger *log.Logger) gin.HandlerFunc { func RequestLogMiddleware(logger *log.Logger) gin.HandlerFunc {
return func(ctx *gin.Context) { return func(ctx *gin.Context) {
// 每次请求都初始化一次配置 // The configuration is initialized once per request
trace := md5.Md5(uuid.GenUUID()) trace := md5.Md5(uuid.GenUUID())
logger.NewContext(ctx, zap.String("trace", trace)) logger.NewContext(ctx, zap.String("trace", trace))
logger.NewContext(ctx, zap.String("request_method", ctx.Request.Method)) logger.NewContext(ctx, zap.String("request_method", ctx.Request.Method))

View File

@@ -3,6 +3,7 @@ package migration
import ( import (
"github.com/go-nunu/nunu-layout-advanced/internal/model" "github.com/go-nunu/nunu-layout-advanced/internal/model"
"github.com/go-nunu/nunu-layout-advanced/pkg/log" "github.com/go-nunu/nunu-layout-advanced/pkg/log"
"go.uber.org/zap"
"gorm.io/gorm" "gorm.io/gorm"
) )
@@ -18,6 +19,9 @@ func NewMigrate(db *gorm.DB, log *log.Logger) *Migrate {
} }
} }
func (m *Migrate) Run() { func (m *Migrate) Run() {
m.db.AutoMigrate(&model.User{}) if err := m.db.AutoMigrate(&model.User{}); err != nil {
m.log.Error("user migrate error", zap.Error(err))
return
}
m.log.Info("AutoMigrate end") m.log.Info("AutoMigrate end")
} }

View File

@@ -19,11 +19,12 @@ func NewServerHTTP(
r.Use( r.Use(
middleware.CORSMiddleware(), middleware.CORSMiddleware(),
middleware.ResponseLogMiddleware(logger), middleware.ResponseLogMiddleware(logger),
middleware.RequestLogMiddleware(logger),
//middleware.SignMiddleware(log), //middleware.SignMiddleware(log),
) )
// 无权限路由 // No route group has permission
noAuthRouter := r.Group("/").Use(middleware.RequestLogMiddleware(logger)) noAuthRouter := r.Group("/")
{ {
noAuthRouter.GET("/", func(ctx *gin.Context) { noAuthRouter.GET("/", func(ctx *gin.Context) {
@@ -36,14 +37,14 @@ func NewServerHTTP(
noAuthRouter.POST("/register", userHandler.Register) noAuthRouter.POST("/register", userHandler.Register)
noAuthRouter.POST("/login", userHandler.Login) noAuthRouter.POST("/login", userHandler.Login)
} }
// 非严格权限路由 // Non-strict permission routing group
noStrictAuthRouter := r.Group("/").Use(middleware.NoStrictAuth(jwt, logger), middleware.RequestLogMiddleware(logger)) noStrictAuthRouter := r.Group("/").Use(middleware.NoStrictAuth(jwt, logger))
{ {
noStrictAuthRouter.GET("/user", userHandler.GetProfile) noStrictAuthRouter.GET("/user", userHandler.GetProfile)
} }
// 严格权限路由 // Strict permission routing group
strictAuthRouter := r.Group("/").Use(middleware.StrictAuth(jwt, logger), middleware.RequestLogMiddleware(logger)) strictAuthRouter := r.Group("/").Use(middleware.StrictAuth(jwt, logger))
{ {
strictAuthRouter.PUT("/user", userHandler.UpdateProfile) strictAuthRouter.PUT("/user", userHandler.UpdateProfile)
} }

View File

@@ -36,7 +36,6 @@ type UserService interface {
Login(ctx context.Context, req *LoginRequest) (string, error) Login(ctx context.Context, req *LoginRequest) (string, error)
GetProfile(ctx context.Context, userId string) (*model.User, error) GetProfile(ctx context.Context, userId string) (*model.User, error)
UpdateProfile(ctx context.Context, userId string, req *UpdateProfileRequest) error UpdateProfile(ctx context.Context, userId string, req *UpdateProfileRequest) error
GenerateToken(ctx context.Context, userId string) (string, error)
} }
type userService struct { type userService struct {
@@ -61,12 +60,12 @@ func (s *userService) Register(ctx context.Context, req *RegisterRequest) error
if err != nil { if err != nil {
return errors.Wrap(err, "failed to hash password") return errors.Wrap(err, "failed to hash password")
} }
// 生成用户ID // Generate user ID
userId, err := s.sid.GenString() userId, err := s.sid.GenString()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to generate user ID") return errors.Wrap(err, "failed to generate user ID")
} }
// 创建用户 // Create a user
user := &model.User{ user := &model.User{
UserId: userId, UserId: userId,
Username: req.Username, Username: req.Username,
@@ -90,8 +89,7 @@ func (s *userService) Login(ctx context.Context, req *LoginRequest) (string, err
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to hash password") return "", errors.Wrap(err, "failed to hash password")
} }
// 生成JWT token token, err := s.jwt.GenToken(user.UserId, time.Now().Add(time.Hour*24*90))
token, err := s.GenerateToken(ctx, user.UserId)
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to generate JWT token") return "", errors.Wrap(err, "failed to generate JWT token")
} }
@@ -123,13 +121,3 @@ func (s *userService) UpdateProfile(ctx context.Context, userId string, req *Upd
return nil return nil
} }
func (s *userService) GenerateToken(ctx context.Context, userId string) (string, error) {
// 生成JWT token
token, err := s.jwt.GenToken(userId, time.Now().Add(time.Hour*24*90))
if err != nil {
return "", errors.Wrap(err, "failed to generate JWT token")
}
return token, nil
}

View File

@@ -36,21 +36,6 @@ func (m *MockUserService) EXPECT() *MockUserServiceMockRecorder {
return m.recorder return m.recorder
} }
// GenerateToken mocks base method.
func (m *MockUserService) GenerateToken(ctx context.Context, userId string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GenerateToken", ctx, userId)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GenerateToken indicates an expected call of GenerateToken.
func (mr *MockUserServiceMockRecorder) GenerateToken(ctx, userId interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GenerateToken", reflect.TypeOf((*MockUserService)(nil).GenerateToken), ctx, userId)
}
// GetProfile mocks base method. // GetProfile mocks base method.
func (m *MockUserService) GetProfile(ctx context.Context, userId string) (*model.User, error) { func (m *MockUserService) GetProfile(ctx context.Context, userId string) (*model.User, error) {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View File

@@ -18,15 +18,12 @@ func NewSid() *Sid {
return &Sid{sf} return &Sid{sf}
} }
func (s Sid) GenString() (string, error) { func (s Sid) GenString() (string, error) {
// 生成分布式ID
id, err := s.sf.NextID() id, err := s.sf.NextID()
if err != nil { if err != nil {
return "", errors.Wrap(err, "failed to generate sonyflake ID") return "", errors.Wrap(err, "failed to generate sonyflake ID")
} }
// 将ID转换为字符串
return convert.IntToBase62(int(id)), nil return convert.IntToBase62(int(id)), nil
} }
func (s Sid) GenUint64() (uint64, error) { func (s Sid) GenUint64() (uint64, error) {
// 生成分布式ID
return s.sf.NextID() return s.sf.NextID()
} }

View File

@@ -21,9 +21,8 @@ func NewLog(conf *viper.Viper) *Logger {
} }
func initZap(conf *viper.Viper) *Logger { func initZap(conf *viper.Viper) *Logger {
// 日志地址 "out.log" 自定义 // log address "out.log" User-defined
lp := conf.GetString("log.log_file_name") lp := conf.GetString("log.log_file_name")
// 日志级别 DEBUG,ERROR, INFO
lv := conf.GetString("log.log_level") lv := conf.GetString("log.log_level")
var level zapcore.Level var level zapcore.Level
//debug<info<warn<error<fatal<panic //debug<info<warn<error<fatal<panic
@@ -40,11 +39,11 @@ func initZap(conf *viper.Viper) *Logger {
level = zap.InfoLevel level = zap.InfoLevel
} }
hook := lumberjack.Logger{ hook := lumberjack.Logger{
Filename: lp, // 日志文件路径 Filename: lp, // Log file path
MaxSize: conf.GetInt("log.max_size"), // 每个日志文件保存的最大尺寸 单位:M MaxSize: conf.GetInt("log.max_size"), // Maximum size unit for each log file: M
MaxBackups: conf.GetInt("log.max_backups"), // 日志文件最多保存多少个备份 MaxBackups: conf.GetInt("log.max_backups"), // The maximum number of backups that can be saved for log files
MaxAge: conf.GetInt("log.max_age"), // 文件最多保存多少天 MaxAge: conf.GetInt("log.max_age"), // Maximum number of days the file can be saved
Compress: conf.GetBool("log.compress"), // 是否压缩 Compress: conf.GetBool("log.compress"), // Compression or not
} }
var encoder zapcore.Encoder var encoder zapcore.Encoder
@@ -79,9 +78,9 @@ func initZap(conf *viper.Viper) *Logger {
}) })
} }
core := zapcore.NewCore( core := zapcore.NewCore(
encoder, // 编码器配置 encoder,
zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 打印到控制台和文件 zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // Print to console and file
level, // 日志级别 level,
) )
if conf.GetString("env") != "prod" { if conf.GetString("env") != "prod" {
return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))} return &Logger{zap.New(core, zap.Development(), zap.AddCaller(), zap.AddStacktrace(zap.ErrorLevel))}
@@ -90,18 +89,17 @@ func initZap(conf *viper.Viper) *Logger {
} }
// 自定义时间编码器
func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
//enc.AppendString(t.Format("2006-01-02 15:04:05")) //enc.AppendString(t.Format("2006-01-02 15:04:05"))
enc.AppendString(t.Format("2006-01-02 15:04:05.000000000")) enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
} }
// NewContext 给指定的context添加字段 // NewContext Adds a field to the specified context
func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) { func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) {
ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...)) ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...))
} }
// WithContext 从指定的context返回一个zap实例 // WithContext Returns a zap instance from the specified context
func (l *Logger) WithContext(ctx *gin.Context) *Logger { func (l *Logger) WithContext(ctx *gin.Context) *Logger {
if ctx == nil { if ctx == nil {
return l return l

View File

View File

@@ -26,7 +26,10 @@ var (
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
fmt.Println("begin") fmt.Println("begin")
os.Setenv("APP_CONF", "../../../config/local.yml") err := os.Setenv("APP_CONF", "../../../config/local.yml")
if err != nil {
panic(err)
}
conf := config.NewConfig() conf := config.NewConfig()
@@ -208,20 +211,3 @@ func TestUserService_UpdateProfile_UserNotFound(t *testing.T) {
assert.Error(t, err) assert.Error(t, err)
} }
func TestUserService_GenerateToken(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockUserRepo := mock_repository.NewMockUserRepository(ctrl)
userService := service.NewUserService(srv, mockUserRepo)
ctx := context.Background()
userId := "123"
result, err := userService.GenerateToken(ctx, userId)
assert.NoError(t, err)
assert.NotEmpty(t, result)
}