瀏覽代碼

Replace repository with dao

chris 2 年之前
父節點
當前提交
b80f9e0ff3

+ 2 - 1
.gitignore

@@ -1,2 +1,3 @@
 /storage/
-.idea
+.idea
+*.log

+ 1 - 1
README.md

@@ -106,7 +106,7 @@ The directory structure of Nunu is as follows:
 │   │   └── user.go
 │   ├── provider
 │   │   └── provider.go
-│   ├── repository
+│   ├── dao
 │   │   └── user.go
 │   ├── server
 │   │   └── http.go

+ 1 - 1
README_zh.md

@@ -104,7 +104,7 @@ Nunu的目录结构如下:
 │   │   └── user.go
 │   ├── provider
 │   │   └── provider.go
-│   ├── repository
+│   ├── dao
 │   │   └── user.go
 │   ├── server
 │   │   └── http.go

+ 1 - 2
cmd/job/wire/wire.go

@@ -13,9 +13,8 @@ import (
 
 // wire.go 初始化模块
 func NewApp(*viper.Viper, *log.Logger) (*job.Job, func(), error) {
-	//log.Logger.Info("NewApp")
 	panic(wire.Build(
-		provider.DBSet,
+		provider.DaoSet,
 		provider.JobSet,
 	))
 }

+ 3 - 3
cmd/job/wire/wire_gen.go

@@ -7,8 +7,8 @@
 package wire
 
 import (
+	"github.com/go-nunu/nunu-layout/internal/dao"
 	"github.com/go-nunu/nunu-layout/internal/job"
-	"github.com/go-nunu/nunu-layout/pkg/db"
 	"github.com/go-nunu/nunu-layout/pkg/log"
 	"github.com/spf13/viper"
 )
@@ -17,8 +17,8 @@ import (
 
 // wire.go 初始化模块
 func NewApp(viperViper *viper.Viper, logger *log.Logger) (*job.Job, func(), error) {
-	gormDB := db.NewDB(viperViper)
-	jobJob := job.NewJob(gormDB, logger)
+	db := dao.NewDB(viperViper)
+	jobJob := job.NewJob(db, logger)
 	return jobJob, func() {
 	}, nil
 }

+ 4 - 4
cmd/migration/wire/wire.go

@@ -4,7 +4,7 @@
 package wire
 
 import (
-	"github.com/go-nunu/nunu-layout/internal/database"
+	"github.com/go-nunu/nunu-layout/internal/migration"
 	"github.com/go-nunu/nunu-layout/internal/provider"
 	"github.com/go-nunu/nunu-layout/pkg/log"
 	"github.com/google/wire"
@@ -12,10 +12,10 @@ import (
 )
 
 // wire.go 初始化模块
-func NewApp(*viper.Viper, *log.Logger) (*database.Migrate, func(), error) {
-	//log.Logger.Info("NewApp")
+func NewApp(*viper.Viper, *log.Logger) (*migration.Migrate, func(), error) {
+	//log.Info("NewApp")
 	panic(wire.Build(
-		provider.DBSet,
+		provider.DaoSet,
 		provider.MigrateSet,
 	))
 }

+ 5 - 5
cmd/migration/wire/wire_gen.go

@@ -7,8 +7,8 @@
 package wire
 
 import (
-	"github.com/go-nunu/nunu-layout/internal/database"
-	"github.com/go-nunu/nunu-layout/pkg/db"
+	"github.com/go-nunu/nunu-layout/internal/dao"
+	"github.com/go-nunu/nunu-layout/internal/migration"
 	"github.com/go-nunu/nunu-layout/pkg/log"
 	"github.com/spf13/viper"
 )
@@ -16,9 +16,9 @@ import (
 // Injectors from wire.go:
 
 // wire.go 初始化模块
-func NewApp(viperViper *viper.Viper, logger *log.Logger) (*database.Migrate, func(), error) {
-	gormDB := db.NewDB(viperViper)
-	migrate := database.NewMigrate(gormDB, logger)
+func NewApp(viperViper *viper.Viper, logger *log.Logger) (*migration.Migrate, func(), error) {
+	db := dao.NewDB(viperViper)
+	migrate := migration.NewMigrate(db, logger)
 	return migrate, func() {
 	}, nil
 }

+ 1 - 2
cmd/server/wire/wire.go

@@ -14,9 +14,8 @@ import (
 // wire.go 初始化模块
 func NewApp(*viper.Viper, *log.Logger) (*gin.Engine, func(), error) {
 	panic(wire.Build(
-		provider.DBSet,
 		provider.ServerSet,
-		provider.RepositorySet,
+		provider.DaoSet,
 		provider.ServiceSet,
 		provider.HandlerSet,
 		provider.SonyflakeSet,

+ 12 - 8
cmd/server/wire/wire_gen.go

@@ -8,14 +8,13 @@ package wire
 
 import (
 	"github.com/gin-gonic/gin"
+	"github.com/go-nunu/nunu-layout/internal/dao"
 	"github.com/go-nunu/nunu-layout/internal/handler"
 	"github.com/go-nunu/nunu-layout/internal/middleware"
-	"github.com/go-nunu/nunu-layout/internal/repository"
 	"github.com/go-nunu/nunu-layout/internal/server"
 	"github.com/go-nunu/nunu-layout/internal/service"
-	"github.com/go-nunu/nunu-layout/pkg/db"
+	"github.com/go-nunu/nunu-layout/pkg/helper/sonyflake"
 	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/sonyflake"
 	"github.com/spf13/viper"
 )
 
@@ -25,11 +24,16 @@ import (
 func NewApp(viperViper *viper.Viper, logger *log.Logger) (*gin.Engine, func(), error) {
 	jwt := middleware.NewJwt(viperViper)
 	sonyflakeSonyflake := sonyflake.NewSonyflake()
-	gormDB := db.NewDB(viperViper)
-	userRepository := repository.NewUserRepository(gormDB)
-	userService := service.NewUserService(userRepository)
-	userHandler := handler.NewUserHandler(logger, sonyflakeSonyflake, userService)
-	engine := server.NewServerHTTP(logger, jwt, userHandler)
+	handlerHandler := handler.NewHandler(logger, sonyflakeSonyflake)
+	serviceService := service.NewService(logger)
+	db := dao.NewDB(viperViper)
+	client := dao.NewRedis(viperViper)
+	daoDao := dao.NewDao(db, client, logger)
+	userDao := dao.NewUserDao(daoDao)
+	userService := service.NewUserService(serviceService, userDao)
+	userHandler := handler.NewUserHandler(handlerHandler, userService)
+	engine, cleanup := server.NewServerHTTP(logger, jwt, userHandler)
 	return engine, func() {
+		cleanup()
 	}, nil
 }

+ 2 - 2
config/local.yml

@@ -9,10 +9,10 @@ security:
     key: 1234
 data:
   mysql:
-    dns: root:123456@tcp(127.0.0.1:3306)/gin-db?charset=utf8mb4&parseTime=True&loc=Local
+    user: root:123456@tcp(127.0.0.1:3380)/user?charset=utf8mb4&parseTime=True&loc=Local
   redis:
     addr: 127.0.0.1:6350
-    password: "123456"
+    password: ""
     db: 0
     read_timeout: 0.2s
     write_timeout: 0.2s

+ 1 - 1
deploy/Dockerfile → deploy/build/Dockerfile

@@ -3,7 +3,7 @@ RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk
 
 ARG APP_RELATIVE_PATH
 
-COPY . /data/app
+COPY .. /data/app
 WORKDIR /data/app
 
 RUN rm -rf /data/app/bin/

+ 25 - 0
deploy/docker-composer/docker-composer.yml

@@ -0,0 +1,25 @@
+version: '3'
+
+services:
+  user-db:
+    image: mysql:8.0.31-debian
+    hostname: user-db
+    container_name: user-db
+    ports:
+      - 3380:3306
+    environment:
+      - MYSQL_ROOT_PASSWORD=123456
+      - MYSQL_ROOT_HOST=%
+      - MYSQL_DATABASE=user
+    volumes:
+      - ./data/mysql/user:/var/lib/mysql
+      - ./conf/mysql/conf.d:/etc/mysql/conf.d
+  cache-redis:
+    image: redis:6-alpine
+    hostname: cache-redis
+    volumes:
+      - ./data/redis/cache/:/data
+      - ./conf/redis/cache/redis.conf:/etc/redis/redis.conf
+    ports:
+      - 6350:6379
+    command: ["redis-server","/etc/redis/redis.conf"]

+ 51 - 0
internal/dao/dao.go

@@ -0,0 +1,51 @@
+package dao
+
+import (
+	"context"
+	"fmt"
+	"github.com/go-nunu/nunu-layout/pkg/log"
+	"github.com/go-redis/redis/v8"
+	"github.com/spf13/viper"
+	"gorm.io/driver/mysql"
+	"gorm.io/gorm"
+	"time"
+)
+
+type Dao struct {
+	db     *gorm.DB
+	rdb    *redis.Client
+	logger *log.Logger
+}
+
+func NewDao(db *gorm.DB, rdb *redis.Client, logger *log.Logger) *Dao {
+	return &Dao{
+		db:     db,
+		rdb:    rdb,
+		logger: logger,
+	}
+}
+
+func NewDB(conf *viper.Viper) *gorm.DB {
+	db, err := gorm.Open(mysql.Open(conf.GetString("data.mysql.user")), &gorm.Config{})
+	if err != nil {
+		panic(err)
+	}
+	return db
+}
+func NewRedis(conf *viper.Viper) *redis.Client {
+	rdb := redis.NewClient(&redis.Options{
+		Addr:     conf.GetString("data.redis.addr"),
+		Password: conf.GetString("data.redis.password"),
+		DB:       conf.GetInt("data.redis.db"),
+	})
+
+	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+	defer cancel()
+
+	_, err := rdb.Ping(ctx).Result()
+	if err != nil {
+		panic(fmt.Sprintf("redis error: %s", err.Error()))
+	}
+
+	return rdb
+}

+ 30 - 0
internal/dao/user.go

@@ -0,0 +1,30 @@
+package dao
+
+import (
+	"github.com/go-nunu/nunu-layout/internal/model"
+)
+
+type UserDao struct {
+	*Dao
+}
+
+func NewUserDao(dao *Dao) *UserDao {
+	return &UserDao{
+		Dao: dao,
+	}
+}
+
+func (r *UserDao) FirstById(id int64) (*model.User, error) {
+	var user model.User
+	if err := r.db.Where("id = ?", id).First(&user).Error; err != nil {
+		return nil, err
+	}
+	return &user, nil
+}
+
+func (r *UserDao) CreateUser(user *model.User) (*model.User, error) {
+	if err := r.db.Create(user).Error; err != nil {
+		return nil, err
+	}
+	return user, nil
+}

+ 16 - 0
internal/handler/handler.go

@@ -0,0 +1,16 @@
+package handler
+
+import (
+	"github.com/go-nunu/nunu-layout/pkg/log"
+	"github.com/sony/sonyflake"
+)
+
+type Handler struct {
+	logger *log.Logger
+}
+
+func NewHandler(logger *log.Logger, sf *sonyflake.Sonyflake) *Handler {
+	return &Handler{
+		logger: logger,
+	}
+}

+ 6 - 8
internal/handler/user.go

@@ -4,22 +4,20 @@ import (
 	"github.com/gin-gonic/gin"
 	"github.com/go-nunu/nunu-layout/internal/model"
 	"github.com/go-nunu/nunu-layout/internal/service"
-	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/resp"
-	"github.com/sony/sonyflake"
+	"github.com/go-nunu/nunu-layout/pkg/helper/resp"
 	"go.uber.org/zap"
 	"net/http"
 )
 
 type UserHandler struct {
+	*Handler
 	userService *service.UserService
-	log         *log.Logger
 }
 
-func NewUserHandler(log *log.Logger, sf *sonyflake.Sonyflake, userService *service.UserService) *UserHandler {
+func NewUserHandler(handler *Handler, userService *service.UserService) *UserHandler {
 	return &UserHandler{
+		Handler:     handler,
 		userService: userService,
-		log:         log,
 	}
 }
 
@@ -38,7 +36,7 @@ func (c *UserHandler) CreateUser(ctx *gin.Context) {
 		Username: params.Username,
 		Email:    params.Email,
 	})
-	c.log.Logger.Info("CreateUser", zap.Any("user", user))
+	c.logger.Info("CreateUser", zap.Any("user", user))
 	if err != nil {
 		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
 		return
@@ -56,7 +54,7 @@ func (c *UserHandler) GetUserById(ctx *gin.Context) {
 	}
 
 	user, err := c.userService.GetUserById(params.Id)
-	c.log.Logger.Info("GetUserByID", zap.Any("user", user))
+	c.logger.Info("GetUserByID", zap.Any("user", user))
 	if err != nil {
 		resp.HandleError(ctx, http.StatusInternalServerError, 1, err.Error(), nil)
 		return

+ 8 - 8
internal/middleware/jwt.go

@@ -3,8 +3,8 @@ package middleware
 import (
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"github.com/go-nunu/nunu-layout/pkg/helper/resp"
 	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/resp"
 	"github.com/golang-jwt/jwt/v5"
 	"github.com/spf13/viper"
 	"go.uber.org/zap"
@@ -52,7 +52,7 @@ func (j *JWT) ParseToken(tokenString string) (*MyCustomClaims, error) {
 
 func NoAuth(log *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
-		log.WithGinContext(ctx).Info("建立请求")
+		log.WithContext(ctx).Info("建立请求")
 		ctx.Next()
 	}
 }
@@ -62,7 +62,7 @@ func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		tokenString := ctx.Request.Header.Get("Authorization")
 		if tokenString == "" {
-			log.WithGinContext(ctx).Warn("请求未携带token,无权限访问", zap.Any("data", map[string]interface{}{
+			log.WithContext(ctx).Warn("请求未携带token,无权限访问", zap.Any("data", map[string]interface{}{
 				"url":    ctx.Request.URL,
 				"params": ctx.Params,
 			}))
@@ -74,7 +74,7 @@ func StrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 		// parseToken 解析token包含的信息
 		claims, err := j.ParseToken(tokenString)
 		if err != nil {
-			log.WithGinContext(ctx).Error("token error", zap.Any("data", map[string]interface{}{
+			log.WithContext(ctx).Error("token error", zap.Any("data", map[string]interface{}{
 				"url":    ctx.Request.URL,
 				"params": ctx.Params,
 			}))
@@ -100,7 +100,7 @@ func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 			tokenString = ctx.Query("accessToken")
 		}
 		if tokenString == "" {
-			log.WithGinContext(ctx).Info("建立请求")
+			log.WithContext(ctx).Info("建立请求")
 			ctx.Next()
 			return
 		}
@@ -108,7 +108,7 @@ func NoStrictAuth(j *JWT, log *log.Logger) gin.HandlerFunc {
 		// parseToken 解析token包含的信息
 		claims, err := j.ParseToken(tokenString)
 		if err != nil {
-			log.WithGinContext(ctx).Info("建立请求")
+			log.WithContext(ctx).Info("建立请求")
 			ctx.Next()
 			return
 		}
@@ -125,8 +125,8 @@ func recoveryLoggerFunc(ctx *gin.Context, logger *log.Logger) {
 		return
 	}
 	userInfo := ctx.MustGet("claims").(*MyCustomClaims)
-	logger.NewGinContext(ctx, zap.Int64("UserId", userInfo.UserId))
-	logger.WithGinContext(ctx).Info("建立请求")
+	logger.NewContext(ctx, zap.Int64("UserId", userInfo.UserId))
+	logger.WithContext(ctx).Info("建立请求")
 
 	// 统计
 }

+ 8 - 8
internal/middleware/log.go

@@ -6,9 +6,9 @@ import (
 	"encoding/json"
 	"fmt"
 	"github.com/gin-gonic/gin"
+	"github.com/go-nunu/nunu-layout/pkg/helper/md5"
+	"github.com/go-nunu/nunu-layout/pkg/helper/uuid"
 	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/md5"
-	"github.com/go-nunu/nunu-layout/pkg/uuid"
 	"go.uber.org/zap"
 	"io"
 	"strconv"
@@ -27,15 +27,15 @@ func RequestLogMiddleware(log *log.Logger) gin.HandlerFunc {
 	return func(ctx *gin.Context) {
 		// 每次请求都初始化一次配置
 		trace := md5.Md5(uuid.GenUUID())
-		log.NewGinContext(ctx, zap.String("trace", trace))
-		log.NewGinContext(ctx, zap.String("request_method", ctx.Request.Method))
+		log.NewContext(ctx, zap.String("trace", trace))
+		log.NewContext(ctx, zap.String("request_method", ctx.Request.Method))
 		headers, _ := json.Marshal(ctx.Request.Header)
-		log.NewGinContext(ctx, zap.String("request_headers", string(headers)))
-		log.NewGinContext(ctx, zap.String("request_url", ctx.Request.URL.String()))
+		log.NewContext(ctx, zap.String("request_headers", string(headers)))
+		log.NewContext(ctx, zap.String("request_url", ctx.Request.URL.String()))
 		if ctx.Request.Body != nil {
 			bodyBytes, _ := ctx.GetRawData()
 			ctx.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) // 关键点
-			log.NewGinContext(ctx, zap.String("request_params", string(bodyBytes)))
+			log.NewContext(ctx, zap.String("request_params", string(bodyBytes)))
 		}
 		ctx.Next()
 	}
@@ -54,7 +54,7 @@ func ResponseLogMiddleware(log *log.Logger) gin.HandlerFunc {
 		if strings.Contains(ctx.Request.URL.Path, "storage") {
 			return
 		}
-		log.WithGinContext(ctx).Info("响应返回", zap.Any("response_body", blw.body.String()), zap.Any("time", fmt.Sprintf("%sms", strconv.Itoa(duration))))
+		log.WithContext(ctx).Info("响应返回", zap.Any("response_body", blw.body.String()), zap.Any("time", fmt.Sprintf("%sms", strconv.Itoa(duration))))
 		statusCode := ctx.Writer.Status()
 		fmt.Println(statusCode)
 		//if statusCode >= 400 {

+ 2 - 2
internal/middleware/sign.go

@@ -2,9 +2,9 @@ package middleware
 
 import (
 	"github.com/gin-gonic/gin"
+	"github.com/go-nunu/nunu-layout/pkg/helper/md5"
+	"github.com/go-nunu/nunu-layout/pkg/helper/resp"
 	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/md5"
-	"github.com/go-nunu/nunu-layout/pkg/resp"
 	"github.com/spf13/viper"
 	"net/http"
 	"sort"

+ 2 - 2
internal/database/migration.go → internal/migration/migration.go

@@ -1,4 +1,4 @@
-package database
+package migration
 
 import (
 	"github.com/go-nunu/nunu-layout/internal/model"
@@ -19,5 +19,5 @@ func NewMigrate(db *gorm.DB, log *log.Logger) *Migrate {
 }
 func (m *Migrate) Run() {
 	m.db.AutoMigrate(&model.User{})
-	m.log.Logger.Info("AutoMigrate end")
+	m.log.Info("AutoMigrate end")
 }

+ 21 - 8
internal/provider/provider.go

@@ -1,27 +1,40 @@
 package provider
 
 import (
-	"github.com/go-nunu/nunu-layout/internal/database"
+	"github.com/go-nunu/nunu-layout/internal/dao"
 	"github.com/go-nunu/nunu-layout/internal/handler"
 	"github.com/go-nunu/nunu-layout/internal/job"
 	"github.com/go-nunu/nunu-layout/internal/middleware"
-	"github.com/go-nunu/nunu-layout/internal/repository"
+	"github.com/go-nunu/nunu-layout/internal/migration"
 	"github.com/go-nunu/nunu-layout/internal/server"
 	"github.com/go-nunu/nunu-layout/internal/service"
-	"github.com/go-nunu/nunu-layout/pkg/db"
-	"github.com/go-nunu/nunu-layout/pkg/sonyflake"
+	"github.com/go-nunu/nunu-layout/pkg/helper/sonyflake"
 	"github.com/google/wire"
 )
 
 var ServerSet = wire.NewSet(server.NewServerHTTP)
-var DBSet = wire.NewSet(db.NewDB)
+
 var SonyflakeSet = wire.NewSet(sonyflake.NewSonyflake)
-var RepositorySet = wire.NewSet(repository.NewUserRepository)
-var ServiceSet = wire.NewSet(service.NewUserService)
-var MigrateSet = wire.NewSet(database.NewMigrate)
+
+var MigrateSet = wire.NewSet(migration.NewMigrate)
+
 var JobSet = wire.NewSet(job.NewJob)
+
 var JwtSet = wire.NewSet(middleware.NewJwt)
 
+var DaoSet = wire.NewSet(
+	dao.NewDB,
+	dao.NewRedis,
+	dao.NewDao,
+	dao.NewUserDao,
+)
+
+var ServiceSet = wire.NewSet(
+	service.NewService,
+	service.NewUserService,
+)
+
 var HandlerSet = wire.NewSet(
+	handler.NewHandler,
 	handler.NewUserHandler,
 )

+ 0 - 28
internal/repository/user.go

@@ -1,28 +0,0 @@
-package repository
-
-import (
-	"github.com/go-nunu/nunu-layout/internal/model"
-	"gorm.io/gorm"
-)
-
-type UserRepository struct {
-	db *gorm.DB
-}
-
-func NewUserRepository(db *gorm.DB) *UserRepository {
-	return &UserRepository{db: db}
-}
-
-func (r *UserRepository) FirstById(id int64) (*model.User, error) {
-	var user model.User
-	if err := r.db.Where("id = ?", id).First(&user).Error; err != nil {
-		return nil, err
-	}
-	return &user, nil
-}
-func (r *UserRepository) CreateUser(user *model.User) (*model.User, error) {
-	if err := r.db.Create(user).Error; err != nil {
-		return nil, err
-	}
-	return user, nil
-}

+ 6 - 3
internal/server/http.go

@@ -1,18 +1,19 @@
 package server
 
 import (
+	"fmt"
 	"github.com/gin-gonic/gin"
 	"github.com/go-nunu/nunu-layout/internal/handler"
 	"github.com/go-nunu/nunu-layout/internal/middleware"
+	"github.com/go-nunu/nunu-layout/pkg/helper/resp"
 	"github.com/go-nunu/nunu-layout/pkg/log"
-	"github.com/go-nunu/nunu-layout/pkg/resp"
 )
 
 func NewServerHTTP(
 	log *log.Logger,
 	jwt *middleware.JWT,
 	userHandler *handler.UserHandler,
-) *gin.Engine {
+) (*gin.Engine, func()) {
 	gin.SetMode(gin.ReleaseMode)
 	r := gin.Default()
 	r.Use(
@@ -44,5 +45,7 @@ func NewServerHTTP(
 		noStrictAuthRouter.POST("/user", userHandler.CreateUser)
 	}
 
-	return r
+	return r, func() {
+		fmt.Println(6666)
+	}
 }

+ 13 - 0
internal/service/service.go

@@ -0,0 +1,13 @@
+package service
+
+import "github.com/go-nunu/nunu-layout/pkg/log"
+
+type Service struct {
+	logger *log.Logger
+}
+
+func NewService(logger *log.Logger) *Service {
+	return &Service{
+		logger: logger,
+	}
+}

+ 8 - 6
internal/service/user.go

@@ -1,23 +1,25 @@
 package service
 
 import (
+	"github.com/go-nunu/nunu-layout/internal/dao"
 	"github.com/go-nunu/nunu-layout/internal/model"
-	"github.com/go-nunu/nunu-layout/internal/repository"
 )
 
 type UserService struct {
-	userRepository *repository.UserRepository
+	*Service
+	userDao *dao.UserDao
 }
 
-func NewUserService(userRepository *repository.UserRepository) *UserService {
+func NewUserService(service *Service, userDao *dao.UserDao) *UserService {
 	return &UserService{
-		userRepository: userRepository,
+		Service: service,
+		userDao: userDao,
 	}
 }
 
 func (s *UserService) GetUserById(id int64) (*model.User, error) {
-	return s.userRepository.FirstById(id)
+	return s.userDao.FirstById(id)
 }
 func (s *UserService) CreateUser(user *model.User) (*model.User, error) {
-	return s.userRepository.CreateUser(user)
+	return s.userDao.CreateUser(user)
 }

+ 0 - 32
internal/service/user_test.go

@@ -1,32 +0,0 @@
-package service
-
-import (
-	"fmt"
-	"github.com/go-nunu/nunu-layout/internal/repository"
-	"github.com/go-nunu/nunu-layout/pkg/config"
-	"github.com/go-nunu/nunu-layout/pkg/db"
-	"github.com/stretchr/testify/assert"
-	"gorm.io/gorm"
-	"os"
-	"testing"
-)
-
-var userService *UserService
-
-func TestMain(m *testing.M) {
-	fmt.Println("begin")
-
-	os.Setenv("APP_CONF", "../../config/local.yml")
-	userRepository := repository.NewUserRepository(db.NewDB(config.NewConfig()))
-	userService = NewUserService(userRepository)
-
-	code := m.Run()
-	fmt.Println("test end")
-
-	os.Exit(code)
-
-}
-func TestGetUserByEmail(t *testing.T) {
-	_, err := userService.GetUserById(0)
-	assert.Equal(t, err, gorm.ErrRecordNotFound, "they should be equal")
-}

+ 0 - 15
pkg/db/db.go

@@ -1,15 +0,0 @@
-package db
-
-import (
-	"github.com/spf13/viper"
-	"gorm.io/driver/mysql"
-	"gorm.io/gorm"
-)
-
-func NewDB(conf *viper.Viper) *gorm.DB {
-	db, err := gorm.Open(mysql.Open(conf.GetString("data.mysql.dns")), &gorm.Config{})
-	if err != nil {
-		panic(err)
-	}
-	return db
-}

+ 0 - 0
pkg/md5/md5.go → pkg/helper/md5/md5.go


+ 0 - 0
pkg/resp/resp.go → pkg/helper/resp/resp.go


+ 0 - 0
pkg/sonyflake/sonyflake.go → pkg/helper/sonyflake/sonyflake.go


+ 0 - 0
pkg/uuid/uuid.go → pkg/helper/uuid/uuid.go


+ 9 - 5
pkg/log/log.go

@@ -17,6 +17,10 @@ type Logger struct {
 }
 
 func NewLog(conf *viper.Viper) *Logger {
+	return initZap(conf)
+}
+
+func initZap(conf *viper.Viper) *Logger {
 	// 日志地址 "out.log" 自定义
 	lp := conf.GetString("log.log_file_name")
 	// 日志级别 DEBUG,ERROR, INFO
@@ -89,13 +93,13 @@ func timeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
 	//enc.AppendString(t.Format("2006-01-02 15:04:05.000000000"))
 }
 
-// NewGinContext 给指定的context添加字段
-func (l *Logger) NewGinContext(ctx *gin.Context, fields ...zapcore.Field) {
-	ctx.Set(LOGGER_KEY, l.WithGinContext(ctx).With(fields...))
+// NewContext 给指定的context添加字段
+func (l *Logger) NewContext(ctx *gin.Context, fields ...zapcore.Field) {
+	ctx.Set(LOGGER_KEY, l.WithContext(ctx).With(fields...))
 }
 
-// WithGinContext 从指定的context返回一个zap实例
-func (l *Logger) WithGinContext(ctx *gin.Context) *Logger {
+// WithContext 从指定的context返回一个zap实例
+func (l *Logger) WithContext(ctx *gin.Context) *Logger {
 	if ctx == nil {
 		return l
 	}

+ 0 - 28
pkg/log/log_test.go

@@ -1,28 +0,0 @@
-package log
-
-import (
-	"flag"
-	"fmt"
-	"github.com/go-nunu/nunu-layout/pkg/config"
-	"go.uber.org/zap"
-	"os"
-	"testing"
-)
-
-var logTest *Logger
-
-func TestMain(m *testing.M) {
-	fmt.Println("begin")
-	flag.Set("conf", "../../config/local.yml")
-	//os.Setenv("APP_CONF", "../../config/local.yml")
-	logTest = NewLog(config.NewConfig())
-
-	code := m.Run()
-	fmt.Println("test end")
-
-	os.Exit(code)
-
-}
-func TestLog(t *testing.T) {
-	logTest.Info("test log", zap.String("data", "test data"))
-}

+ 0 - 1
pkg/log/storage/logs/server.log

@@ -1 +0,0 @@
-2023-06-02 23:14:20	info	/Users/chris/Projects/stu/gin-starter/pkg/log/log_test.go:27	test log	{"data": "test data"}

+ 0 - 26
pkg/rdb/redis.go

@@ -1,26 +0,0 @@
-package rdb
-
-import (
-	"context"
-	"github.com/go-redis/redis/v8"
-	"github.com/spf13/viper"
-	"time"
-)
-
-func NewRedis(conf *viper.Viper) error {
-	rdb := redis.NewClient(&redis.Options{
-		Addr:     conf.GetString("data.redis.addr"),
-		Password: conf.GetString("data.redis.password"),
-		DB:       conf.GetInt("data.redis.db"),
-	})
-
-	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
-	defer cancel()
-
-	_, err := rdb.Ping(ctx).Result()
-	if err != nil {
-		return err
-	}
-
-	return nil
-}

+ 0 - 0
script/deploy.sh


+ 97 - 0
test/server/handler/storage/logs/server.log

@@ -0,0 +1,97 @@
+2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:33	start
+2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "0bdb3695c4ca3381d3cbbadf5b0904a2", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
+2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463376085304737894}
+2023-06-03 00:27:49	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "0bdb3695c4ca3381d3cbbadf5b0904a2", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
+2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:33	start
+2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "f0bba6b5830095ae2f7e56e9d7c6897e", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
+2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463376133757337702}
+2023-06-03 00:28:18	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "f0bba6b5830095ae2f7e56e9d7c6897e", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
+2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "5d1b363586f1d709bf1c4c616dbf5a42", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}"}
+2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:28	GetUserByID	{"sonyflake": 463377317238931558}
+2023-06-03 00:40:03	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "5d1b363586f1d709bf1c4c616dbf5a42", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"actionType\":1,\"phone\":\"18502100065\"}", "response_body": "{\"code\":1,\"message\":\"record not found\",\"data\":{}}", "time": "2ms"}
+2023-06-03 00:48:11	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:48:12	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "7d6f948b1edb1b283b859addb92022b9", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
+2023-06-03 00:48:12	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:47	CreateUser	{"user": {"ID":1,"CreatedAt":"2023-06-03T00:48:12.007+08:00","UpdatedAt":"2023-06-03T00:48:12.007+08:00","DeletedAt":null,"Username":"test","Email":"5303221@gmail.com"}}
+2023-06-03 00:48:21	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "7d6f948b1edb1b283b859addb92022b9", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "response_body": "{\"code\":0,\"message\":\"success\",\"data\":{\"ID\":1,\"CreatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"UpdatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"DeletedAt\":null,\"Username\":\"test\",\"Email\":\"5303221@gmail.com\"}}", "time": "9827ms"}
+2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "fde7e0f0d6c2d72558de89ba9270c04b", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=aaa"}
+2023-06-03 00:48:51	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "fde7e0f0d6c2d72558de89ba9270c04b", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=aaa", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "12e4b2be61b6e0954a53a1a7d6e63ad5", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:49:13	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "12e4b2be61b6e0954a53a1a7d6e63ad5", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "1a5cccc20a9097ddb3d2e98b0fa38634", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:49:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "1a5cccc20a9097ddb3d2e98b0fa38634", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "9d13d05958c821ef4b14c855fea94854", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:50:09	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "9d13d05958c821ef4b14c855fea94854", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "ed2ccae0fa4accdc317ee0f6bb036312", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:50:44	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "ed2ccae0fa4accdc317ee0f6bb036312", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "a6dc94353e52f6ca91b7c50df42e9750", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:50:53	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "a6dc94353e52f6ca91b7c50df42e9750", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "332e61758a39c529cfcdd36de4e7a47c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:51:31	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "332e61758a39c529cfcdd36de4e7a47c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-03 00:51:36	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:51:36	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "a09398a82736c1127647996a007a2658", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:57:46	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:57:46	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "996290c5fe5fd7700a6f4298612a4c8a", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user"}
+2023-06-03 00:58:34	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "996290c5fe5fd7700a6f4298612a4c8a", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "47328ms"}
+2023-06-03 00:58:38	info	/Users/chris/Projects/stu/gin-starter/test/server/handler/user_test.go:44	start
+2023-06-03 00:58:38	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/jwt.go:55	建立请求	{"trace": "57945bf50e811ef287e0cc7c92d665ea", "request_method": "GET", "request_headers": "{}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-03 00:58:43	info	/Users/chris/Projects/stu/gin-starter/internal/handler/user.go:60	GetUserByID	{"user": {"ID":1,"CreatedAt":"2023-06-03T00:48:12.007+08:00","UpdatedAt":"2023-06-03T00:48:12.007+08:00","DeletedAt":null,"Username":"test","Email":"5303221@gmail.com"}}
+2023-06-03 00:58:43	info	/Users/chris/Projects/stu/gin-starter/internal/middleware/log.go:57	响应返回	{"trace": "57945bf50e811ef287e0cc7c92d665ea", "request_method": "GET", "request_headers": "{}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":0,\"message\":\"success\",\"data\":{\"ID\":1,\"CreatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"UpdatedAt\":\"2023-06-03T00:48:12.007+08:00\",\"DeletedAt\":null,\"Username\":\"test\",\"Email\":\"5303221@gmail.com\"}}", "time": "5315ms"}
+2023-06-05 15:52:00	info	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:47	start
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com"}
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:57	响应返回	{"trace": "856fe8165f39ab3d7734fca386f74b1c", "request_method": "GET", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"],\"Content-Type\":[\"application/json\"]}", "request_url": "/user?email=5303221@gmail.com", "response_body": "{\"code\":1,\"message\":\"missing form body\",\"data\":{}}", "time": "0ms"}
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:47	start
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:55	建立请求	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}"}
+2023-06-05 15:52:04	error	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:77	token error	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "data": {"params":null,"url":{"Scheme":"","Opaque":"","User":null,"Host":"","Path":"/user","RawPath":"","OmitHost":false,"ForceQuery":false,"RawQuery":"","Fragment":"","RawFragment":""}}}
+github.com/go-nunu/nunu-layout/internal/middleware.StrictAuth.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:77
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/go-nunu/nunu-layout/internal/middleware.NoAuth.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:56
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/go-nunu/nunu-layout/internal/middleware.ResponseLogMiddleware.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:48
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/go-nunu/nunu-layout/internal/middleware.NoAuth.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/jwt.go:56
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/go-nunu/nunu-layout/internal/middleware.CORSMiddleware.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/cors.go:20
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/go-nunu/nunu-layout/internal/middleware.RequestLogMiddleware.func1
+	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:40
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/gin-gonic/gin.CustomRecoveryWithWriter.func1
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/recovery.go:102
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/gin-gonic/gin.LoggerWithConfig.func1
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/logger.go:240
+github.com/gin-gonic/gin.(*Context).Next
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/context.go:174
+github.com/gin-gonic/gin.(*Engine).handleHTTPRequest
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:620
+github.com/gin-gonic/gin.(*Engine).ServeHTTP
+	/Users/chris/Go/pkg/mod/github.com/gin-gonic/gin@v1.9.1/gin.go:576
+github.com/go-nunu/nunu-layout/test/server/handler.NewRequest
+	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:58
+github.com/go-nunu/nunu-layout/test/server/handler.TestCreateUser
+	/Users/chris/Projects/stu/nunu-layout/test/server/handler/user_test.go:84
+testing.tRunner
+	/usr/local/go/src/testing/testing.go:1576
+2023-06-05 15:52:04	info	/Users/chris/Projects/stu/nunu-layout/internal/middleware/log.go:57	响应返回	{"trace": "66ab47224d8602f41e275df08e55582f", "request_method": "POST", "request_headers": "{\"Authorization\":[\"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySW5mbyI6eyJ1c2VyU2lkIjoiOHpsdGxQRzhXSCIsIm5pY2tuYW1lIjoi55CD55CDIiwidXNlcklkIjowfSwiZXhwIjoxNjg3NzcwMzYzLCJqdGkiOiI4emx0bFBHOFdIIiwiaXNzIjoiaHR0cHM6Ly90ZWh1Yi5jb20vYXBpIiwibmJmIjoxNjcyMjE3NzYzLCJzdWIiOiI4emx0bFBHOFdIIn0.G0sSUzj3GBANqj6dU7rSMsr44SARgYwH1ERwKUCaxsM\"]}", "request_url": "/user", "request_params": "{\"email\":\"5303221@gmail.com\",\"username\":\"test\"}", "response_body": "{\"code\":1,\"message\":\"token signature is invalid: signature is invalid\",\"data\":{}}", "time": "0ms"}

+ 51 - 0
test/server/service/user_test.go

@@ -0,0 +1,51 @@
+package service
+
+import (
+	"fmt"
+	"github.com/go-nunu/nunu-layout/internal/dao"
+	"github.com/go-nunu/nunu-layout/internal/model"
+	"github.com/go-nunu/nunu-layout/internal/service"
+	"github.com/go-nunu/nunu-layout/pkg/config"
+	"github.com/go-nunu/nunu-layout/pkg/log"
+	"github.com/stretchr/testify/assert"
+	"gorm.io/gorm"
+	"os"
+	"testing"
+)
+
+var userService *service.UserService
+
+func TestMain(m *testing.M) {
+	fmt.Println("begin")
+
+	os.Setenv("APP_CONF", "../../../config/local.yml")
+
+	conf := config.NewConfig()
+
+	logger := log.NewLog(conf)
+	db := dao.NewDB(conf)
+	rdb := dao.NewRedis(conf)
+
+	srv := service.NewService(logger)
+	repo := dao.NewDao(db, rdb, logger)
+	userDao := dao.NewUserDao(repo)
+	userService = service.NewUserService(srv, userDao)
+
+	code := m.Run()
+	fmt.Println("test end")
+
+	os.Exit(code)
+
+}
+func TestGetUserByEmail(t *testing.T) {
+	_, err := userService.GetUserById(0)
+	assert.Equal(t, err, gorm.ErrRecordNotFound, "they should be equal")
+}
+
+func TestCreateUser(t *testing.T) {
+	_, err := userService.CreateUser(&model.User{
+		Username: "test",
+		Email:    "nunu@mail.com",
+	})
+	assert.NotEqual(t, err, nil, "they should be equal")
+}