From 3b474a056ea35196ce5d2a5f297eafa11295a95d Mon Sep 17 00:00:00 2001
From: liujiandao <274878379@qq.com>
Date: 星期三, 22 十一月 2023 14:23:13 +0800
Subject: [PATCH] 添加登录功能
---
request/jwt.go | 20 +
go.mod | 3
pkg/ecode/code.go | 21 +
pkg/contextx/contextx.go | 97 ++++++++
constvar/const.go | 9
pkg/logx/json.go | 91 +++++++
pkg/logx/service.go | 49 ++++
go.sum | 13
middleware/utils.go | 60 +++++
pkg/logx/console.go | 89 +++++++
middleware/jwt.go | 39 +++
pkg/logx/index.go | 158 +++++++++++++
initialize/router.go | 8
pkg/ecode/msg.go | 24 ++
14 files changed, 669 insertions(+), 12 deletions(-)
diff --git a/constvar/const.go b/constvar/const.go
new file mode 100644
index 0000000..384dbfa
--- /dev/null
+++ b/constvar/const.go
@@ -0,0 +1,9 @@
+package constvar
+
+type UserType int
+
+const (
+ UserTypeSuper UserType = iota + 1 // 瓒呯骇绠$悊鍛�
+ UserTypePrimary // 涓昏处鎴�
+ UserTypeSub // 瀛愯处鎴�
+)
diff --git a/go.mod b/go.mod
index ba23ae5..879a5a1 100644
--- a/go.mod
+++ b/go.mod
@@ -3,11 +3,13 @@
go 1.18
require (
+ github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fsnotify/fsnotify v1.6.0
github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
github.com/gin-gonic/gin v1.9.1
github.com/glebarez/sqlite v1.8.0
github.com/go-sql-driver/mysql v1.7.1
+ github.com/golang-jwt/jwt/v4 v4.5.0
github.com/h2non/filetype v1.1.3
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
github.com/redis/go-redis/v9 v9.0.5
@@ -23,6 +25,7 @@
golang.org/x/sync v0.3.0
google.golang.org/grpc v1.55.0
google.golang.org/protobuf v1.30.0
+ gopkg.in/natefinch/lumberjack.v2 v2.2.1
gorm.io/driver/mysql v1.5.1
gorm.io/driver/postgres v1.5.2
gorm.io/driver/sqlserver v1.5.1
diff --git a/go.sum b/go.sum
index 5995390..92c4d46 100644
--- a/go.sum
+++ b/go.sum
@@ -45,7 +45,6 @@
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
-github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
@@ -73,6 +72,8 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko=
@@ -140,10 +141,10 @@
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
@@ -226,16 +227,10 @@
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
-github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
-github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
-github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgtype v1.9.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgx/v4 v4.14.0/go.mod h1:jT3ibf/A0ZVCp89rtCIN0zCJxcE74ypROmHEZYsG/j8=
github.com/jackc/pgx/v5 v5.3.1 h1:Fcr8QJ1ZeLi5zsPZqQeUZhNhxfkkKBOgJuYkJHoBOtU=
github.com/jackc/pgx/v5 v5.3.1/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8=
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
@@ -769,6 +764,8 @@
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
+gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU=
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/initialize/router.go b/initialize/router.go
index 4b390f7..584dbf3 100644
--- a/initialize/router.go
+++ b/initialize/router.go
@@ -2,6 +2,7 @@
import (
"net/http"
+ "srm/middleware"
"srm/router/purchase"
"github.com/gin-gonic/gin"
@@ -25,16 +26,15 @@
global.GVA_LOG.Info("register swagger handler")
// 鏂逛究缁熶竴娣诲姞璺敱缁勫墠缂� 澶氭湇鍔″櫒涓婄嚎浣跨敤
- PublicGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
+ PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
{
// 鍋ュ悍鐩戞祴
- PublicGroup.GET("/health", func(c *gin.Context) {
+ PrivateGroup.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, "ok")
})
//systemRouter.InitInitRouter(PublicGroup) // 鑷姩鍒濆鍖栫浉鍏�
}
-
- PrivateGroup := Router.Group(global.GVA_CONFIG.System.RouterPrefix)
+ PrivateGroup.Use(middleware.JWTAuth())
{
systemRouter.InitSystemRouter(PrivateGroup) // system鐩稿叧璺敱
//exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup) // 鏂囦欢涓婁紶涓嬭浇鍔熻兘璺敱
diff --git a/middleware/jwt.go b/middleware/jwt.go
new file mode 100644
index 0000000..42ce6e0
--- /dev/null
+++ b/middleware/jwt.go
@@ -0,0 +1,39 @@
+package middleware
+
+import (
+ "github.com/gin-gonic/gin"
+ "srm/pkg/contextx"
+ "srm/pkg/ecode"
+ "strings"
+)
+
+func JWTAuth() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ ctx := new(contextx.Context).SetCtx(c)
+ // 鎴戜滑杩欓噷jwt閴存潈鍙栧ご閮ㄤ俊鎭� Authorization 鐧诲綍鏃跺洖杩斿洖token淇℃伅 杩欓噷鍓嶇闇�瑕佹妸token瀛樺偍鍒癱ookie鎴栬�呮湰鍦發ocalStorage涓� 涓嶈繃闇�瑕佽窡鍚庣鍗忓晢杩囨湡鏃堕棿 鍙互绾﹀畾鍒锋柊浠ょ墝鎴栬�呴噸鏂扮櫥褰�
+ token := c.Request.Header.Get("Authorization")
+ if token == "" {
+ ctx.Fail(ecode.JWTEmpty)
+ c.Abort()
+ return
+ }
+ slices := strings.Split(token, " ")
+ if len(slices) == 2 {
+ token = slices[1]
+ }
+ j := NewJWT()
+ // parseToken 瑙f瀽token鍖呭惈鐨勪俊鎭�
+ claims, err := j.ParseToken(token)
+ if err != nil {
+ if err == TokenExpired {
+ c.Next()
+ return
+ }
+ c.Next()
+ return
+ }
+
+ c.Set("claims", claims)
+ c.Next()
+ }
+}
diff --git a/middleware/utils.go b/middleware/utils.go
new file mode 100644
index 0000000..190a77a
--- /dev/null
+++ b/middleware/utils.go
@@ -0,0 +1,60 @@
+package middleware
+
+import (
+ "errors"
+ "github.com/golang-jwt/jwt/v4"
+ "srm/request"
+)
+
+type JWT struct {
+ SigningKey []byte
+}
+
+var (
+ TokenExpired = errors.New("Token is expired")
+ TokenNotValidYet = errors.New("Token not active yet")
+ TokenMalformed = errors.New("That's not even a token")
+ TokenInvalid = errors.New("Couldn't handle this token:")
+)
+
+func NewJWT() *JWT {
+ return &JWT{
+ []byte("327a9457-899a-481e-8b30-58cc97e5b808"),
+ }
+}
+
+// CreateToken 鍒涘缓涓�涓猼oken
+func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) {
+ token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
+ return token.SignedString(j.SigningKey)
+}
+
+// ParseToken 瑙f瀽token
+func (j *JWT) ParseToken(tokenString string) (*request.CustomClaims, error) {
+ token, err := jwt.ParseWithClaims(tokenString, &request.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
+ return j.SigningKey, nil
+ })
+ if err != nil {
+ if ve, ok := err.(*jwt.ValidationError); ok {
+ if ve.Errors&jwt.ValidationErrorMalformed != 0 {
+ return nil, TokenMalformed
+ } else if ve.Errors&jwt.ValidationErrorExpired != 0 {
+ // Token is expired
+ return nil, TokenExpired
+ } else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
+ return nil, TokenNotValidYet
+ } else {
+ return nil, TokenInvalid
+ }
+ }
+ }
+ if token != nil {
+ if claims, ok := token.Claims.(*request.CustomClaims); ok && token.Valid {
+ return claims, nil
+ }
+ return nil, TokenInvalid
+
+ } else {
+ return nil, TokenInvalid
+ }
+}
diff --git a/pkg/contextx/contextx.go b/pkg/contextx/contextx.go
new file mode 100644
index 0000000..958df06
--- /dev/null
+++ b/pkg/contextx/contextx.go
@@ -0,0 +1,97 @@
+package contextx
+
+import (
+ "github.com/gin-gonic/gin"
+ "net/http"
+ "srm/pkg/ecode"
+ "srm/pkg/logx"
+)
+
+type (
+ Context struct {
+ ctx *gin.Context
+ paramsMap map[string]interface{}
+ }
+
+ Response struct {
+ Code int `json:"code"`
+ Data interface{} `json:"data"`
+ Msg string `json:"msg"`
+ }
+)
+
+func NewContext(ctx *gin.Context, params interface{}) (r *Context, isAllow bool) {
+ r = &Context{
+ ctx: ctx,
+ }
+ if r.ctx.Request.Method == "OPTIONS" {
+ r.ctx.String(http.StatusOK, "")
+ return
+ }
+
+ defer func() {
+ query := r.ctx.Request.URL.RawQuery
+ if query != "" {
+ query = "?" + query
+ }
+ urlPath := r.ctx.Request.URL.Path
+ logx.Infof("%s | %s %s | uid: %s | %+v", ctx.ClientIP(), r.ctx.Request.Method, urlPath+query, r.GetUserId(), params)
+ }()
+
+ // validate params
+ if params != nil {
+ if err := r.ctx.ShouldBind(params); err != nil {
+ r.Fail(ecode.ParamsErr)
+ return
+ }
+ }
+ isAllow = true
+ return
+}
+
+func (slf *Context) GetRequestPath() (r string) {
+ r = slf.ctx.Request.URL.Path
+ return
+}
+
+func (slf *Context) GetUserId() (r string) {
+ v := slf.paramsMap["userId"]
+ switch v.(type) {
+ case string:
+ r = v.(string)
+ }
+ return
+}
+
+func (slf *Context) Result(code int, data interface{}, msg string) {
+ slf.ctx.JSON(http.StatusOK, Response{
+ Code: code,
+ Data: data,
+ Msg: msg,
+ })
+}
+
+func (slf *Context) Ok() {
+ slf.Result(ecode.OK, map[string]interface{}{}, "")
+}
+
+func (slf *Context) OkWithDetailed(data interface{}) {
+ slf.Result(ecode.OK, data, "")
+}
+
+func (slf *Context) Fail(errCode int) {
+ slf.Result(errCode, map[string]interface{}{}, ecode.GetMsg(errCode))
+}
+
+func (slf *Context) FailWithDetailed(errCode int, data interface{}) {
+ slf.Result(errCode, data, ecode.GetMsg(errCode))
+}
+
+func (slf *Context) GetCtx() *gin.Context {
+ return slf.ctx
+}
+
+func (slf *Context) SetCtx(c *gin.Context) *Context {
+ slf.ctx = c
+ return slf
+}
diff --git a/pkg/ecode/code.go b/pkg/ecode/code.go
new file mode 100644
index 0000000..aa74251
--- /dev/null
+++ b/pkg/ecode/code.go
@@ -0,0 +1,21 @@
+package ecode
+
+const (
+ OK = 200
+
+ UnknownErr = 2001 // 鏈煡閿欒
+ DBErr = 2002 // db閿欒
+ RedisErr = 2003 // redis閿欒
+ ParamsErr = 2004 // 璇锋眰鍙傛暟閿欒
+ UserNotExist = 2005 // 鐢ㄦ埛涓嶅瓨鍦�
+ PasswordErr = 2006 // 瀵嗙爜閿欒
+ UserForbidden = 2007 // 鐢ㄦ埛琚鐢�
+ CaptchaGenerateFailed = 2008 // 楠岃瘉鐮佺敓鎴愬け璐�
+ CaptchaErr = 2009 // 楠岃瘉鐮侀敊璇�
+ CreateTokenErr = 2010 // 鍒涘缓token澶辫触
+ JWTInBlackList = 2011 // JWT鍦ㄧ櫧鍚嶅崟
+ JWTDisabled = 2012 // JWT澶辨晥
+ JWTEmpty = 2013 // JWT涓虹┖
+ JWTExpire = 2014 // JWT杩囨湡
+ JWTParseErr = 2015 // JWT瑙f瀽澶辫触
+)
diff --git a/pkg/ecode/msg.go b/pkg/ecode/msg.go
new file mode 100644
index 0000000..9b5ebe5
--- /dev/null
+++ b/pkg/ecode/msg.go
@@ -0,0 +1,24 @@
+package ecode
+
+var MsgFlags = map[int]string{
+ UnknownErr: "鏈煡閿欒",
+ DBErr: "db閿欒",
+ RedisErr: "redis閿欒",
+ ParamsErr: "璇锋眰鍙傛暟閿欒",
+ UserNotExist: "鐢ㄦ埛涓嶅瓨鍦�",
+ PasswordErr: "瀵嗙爜閿欒",
+ UserForbidden: "鐢ㄦ埛琚鐢�",
+ CaptchaGenerateFailed: "楠岃瘉鐮佺敓鎴愬け璐�",
+ CaptchaErr: "楠岃瘉鐮侀敊璇�",
+ CreateTokenErr: "鍒涘缓token澶辫触",
+ JWTInBlackList: "JWT鍦ㄧ櫧鍚嶅崟",
+ JWTDisabled: "JWT澶辨晥",
+ JWTEmpty: "JWT涓虹┖",
+ JWTExpire: "JWT杩囨湡",
+ JWTParseErr: "JWT瑙f瀽澶辫触",
+}
+
+func GetMsg(errCode int) (errMsg string) {
+ errMsg, _ = MsgFlags[errCode]
+ return
+}
diff --git a/pkg/logx/console.go b/pkg/logx/console.go
new file mode 100644
index 0000000..fe1d18a
--- /dev/null
+++ b/pkg/logx/console.go
@@ -0,0 +1,89 @@
+package logx
+
+import (
+ "fmt"
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+ "time"
+)
+
+type ConsoleLog struct {
+ val string
+}
+
+func NewConsoleLog() Encoder {
+ return new(ConsoleLog)
+}
+
+// Config 鑷畾涔夐厤缃�.
+func (slf *ConsoleLog) Config() zapcore.Encoder {
+ var (
+ cfg = zap.NewProductionEncoderConfig()
+ )
+
+ // 鏃堕棿鏍煎紡鑷畾涔�
+ cfg.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString("[" + t.Format("2006-01-02 15:04:05") + "]")
+ }
+ // 鎵撳嵃璺緞鑷畾涔�
+ cfg.EncodeCaller = func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
+ encoder.AppendString("[" + getFilePath(caller) + "]")
+ }
+ // 绾у埆鏄剧ず鑷畾涔�
+ cfg.EncodeLevel = func(level zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) {
+ encoder.AppendString("[" + level.String() + "]")
+ }
+ return zapcore.NewConsoleEncoder(cfg)
+}
+
+// WithKey 娣诲姞鍗曚釜閿�.
+func (slf *ConsoleLog) WithKey(key string) Encoder {
+ slf.val = slf.val + "[" + key + "] "
+ return slf
+}
+
+// WithField 娣诲姞瀛楁.
+func (slf *ConsoleLog) WithField(key, val string) Encoder {
+ slf.val = slf.val + fmt.Sprintf("[%s:%s] ", key, val)
+ return slf
+}
+
+func (slf *ConsoleLog) Debug(msg string) {
+ _logger.Debug(slf.val + msg)
+}
+
+func (slf *ConsoleLog) Debugf(format string, v ...interface{}) {
+ _logger.Debug(fmt.Sprintf(slf.val+format, v...))
+}
+
+func (slf *ConsoleLog) Info(msg string) {
+ _logger.Info(slf.val + msg)
+}
+
+func (slf *ConsoleLog) Infof(format string, v ...interface{}) {
+ _logger.Info(fmt.Sprintf(slf.val+format, v...))
+}
+
+func (slf *ConsoleLog) Warn(msg string) {
+ _logger.Warn(slf.val + msg)
+}
+
+func (slf *ConsoleLog) Warnf(format string, v ...interface{}) {
+ _logger.Warn(fmt.Sprintf(slf.val+format, v...))
+}
+
+func (slf *ConsoleLog) Error(msg string) {
+ _logger.Error(slf.val + msg)
+}
+
+func (slf *ConsoleLog) Errorf(format string, v ...interface{}) {
+ _logger.Error(fmt.Sprintf(slf.val+format, v...))
+}
+
+func (slf *ConsoleLog) Fatal(msg string) {
+ _logger.Fatal(slf.val + msg)
+}
+
+func (slf *ConsoleLog) Fatalf(format string, v ...interface{}) {
+ _logger.Fatal(fmt.Sprintf(slf.val+format, v...))
+}
diff --git a/pkg/logx/index.go b/pkg/logx/index.go
new file mode 100644
index 0000000..42e4213
--- /dev/null
+++ b/pkg/logx/index.go
@@ -0,0 +1,158 @@
+package logx
+
+import (
+ "go.uber.org/zap"
+ "go.uber.org/zap/buffer"
+ "go.uber.org/zap/zapcore"
+ "gopkg.in/natefinch/lumberjack.v2"
+ "os"
+ "path"
+ "strings"
+)
+
+type (
+ Conf struct {
+ Path string // 鏃ュ織璺緞
+ Encoder string // 缂栫爜鍣ㄩ�夋嫨
+ }
+ logItem struct {
+ FileName string
+ Level zap.LevelEnablerFunc
+ }
+ Encoder interface {
+ Config() zapcore.Encoder
+ WithKey(key string) Encoder
+ WithField(key, val string) Encoder
+ Debug(msg string)
+ Debugf(format string, v ...interface{})
+ Info(msg string)
+ Infof(format string, v ...interface{})
+ Warn(msg string)
+ Warnf(format string, v ...interface{})
+ Error(msg string)
+ Errorf(format string, v ...interface{})
+ Fatal(msg string)
+ Fatalf(format string, v ...interface{})
+ }
+)
+
+var (
+ maxSize = 200 // 姣忎釜鏃ュ織鏂囦欢鏈�澶у昂瀵�200M
+ maxBackups = 20 // 鏃ュ織鏂囦欢鏈�澶氫繚瀛�20涓浠�
+ maxAge = 30 // 淇濈暀鏈�澶уぉ鏁�
+ _logger *zap.Logger
+ _pool = buffer.NewPool()
+ c Conf
+
+ ConsoleEncoder = "console" // 鎺у埗鍙拌緭鍑�
+ JsonEncoder = "json" // json杈撳嚭
+)
+
+// Init 鍒濆鍖栨棩蹇�.
+func Init(conf Conf) {
+ c = conf
+ prefix, suffix := getFileSuffixPrefix(c.Path)
+
+ infoPath := path.Join(prefix + ".info" + suffix)
+ errPath := path.Join(prefix + ".err" + suffix)
+ items := []logItem{
+ {
+ FileName: infoPath,
+ Level: func(level zapcore.Level) bool {
+ return level <= zap.InfoLevel
+ },
+ },
+ {
+ FileName: errPath,
+ Level: func(level zapcore.Level) bool {
+ return level > zap.InfoLevel
+ },
+ },
+ }
+
+ NewLogger(items)
+}
+
+// NewLogger 鏃ュ織.
+func NewLogger(items []logItem) {
+ var (
+ cfg zapcore.Encoder
+ cores []zapcore.Core
+ )
+ switch c.Encoder {
+ case JsonEncoder:
+ cfg = NewJsonLog().Config()
+ case ConsoleEncoder:
+ cfg = NewConsoleLog().Config()
+ default:
+ cfg = NewConsoleLog().Config()
+ }
+
+ for _, v := range items {
+ hook := lumberjack.Logger{
+ Filename: v.FileName,
+ MaxSize: maxSize, // 姣忎釜鏃ュ織鏂囦欢淇濆瓨鐨勬渶澶у昂瀵� 鍗曚綅锛歁
+ MaxBackups: maxBackups, // 鏃ュ織鏂囦欢鏈�澶氫繚瀛樺灏戜釜澶囦唤
+ MaxAge: maxAge, // 鏂囦欢鏈�澶氫繚瀛樺灏戝ぉ
+ Compress: true, // 鏄惁鍘嬬缉
+ LocalTime: true, // 澶囦唤鏂囦欢鍚嶆湰鍦�/UTC鏃堕棿
+ }
+ core := zapcore.NewCore(
+ cfg, // 缂栫爜鍣ㄩ厤缃�;
+ zapcore.NewMultiWriteSyncer(zapcore.AddSync(os.Stdout), zapcore.AddSync(&hook)), // 鎵撳嵃鍒版帶鍒跺彴鍜屾枃浠�
+ v.Level, // 鏃ュ織绾у埆
+ )
+ cores = append(cores, core)
+ }
+
+ // 寮�鍚紑鍙戞ā寮忥紝鍫嗘爤璺熻釜
+ caller := zap.AddCaller()
+ // 寮�鍙戞ā寮�
+ development := zap.Development()
+ // 浜屾灏佽
+ skip := zap.AddCallerSkip(1)
+ // 鏋勯�犳棩蹇�
+ _logger = zap.New(zapcore.NewTee(cores...), caller, development, skip)
+ return
+}
+
+// GetEncoder 鑾峰彇鑷畾涔夌紪鐮佸櫒.
+func GetEncoder() Encoder {
+ switch c.Encoder {
+ case JsonEncoder:
+ return NewJsonLog()
+ case ConsoleEncoder:
+ return NewConsoleLog()
+ default:
+ return NewConsoleLog()
+ }
+}
+
+// GetLogger 鑾峰彇鏃ュ織璁板綍鍣�.
+func GetLogger() *zap.Logger {
+ return _logger
+}
+
+// getFileSuffixPrefix 鏂囦欢璺緞鍒囧壊
+func getFileSuffixPrefix(fileName string) (prefix, suffix string) {
+ paths, _ := path.Split(fileName)
+ base := path.Base(fileName)
+ suffix = path.Ext(fileName)
+ prefix = strings.TrimSuffix(base, suffix)
+ prefix = path.Join(paths, prefix)
+ return
+}
+
+// getFilePath 鑷畾涔夎幏鍙栨枃浠惰矾寰�.
+func getFilePath(ec zapcore.EntryCaller) string {
+ if !ec.Defined {
+ return "undefined"
+ }
+ buf := _pool.Get()
+ buf.AppendString(ec.Function)
+ buf.AppendByte(':')
+ buf.AppendInt(int64(ec.Line))
+ caller := buf.String()
+ buf.Free()
+ return caller
+}
diff --git a/pkg/logx/json.go b/pkg/logx/json.go
new file mode 100644
index 0000000..1d7d361
--- /dev/null
+++ b/pkg/logx/json.go
@@ -0,0 +1,91 @@
+package logx
+
+import (
+ "fmt"
+ "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+ "time"
+)
+
+type JsonLog struct {
+ fields []zap.Field
+ val string
+}
+
+// NewJsonLog 鑷畾涔夋坊鍔爈og field.
+func NewJsonLog() Encoder {
+ return &JsonLog{fields: make([]zap.Field, 0)}
+}
+
+// Config 鑷畾涔夐厤缃�.
+func (slf *JsonLog) Config() zapcore.Encoder {
+ var (
+ cfg = zap.NewProductionEncoderConfig()
+ )
+
+ // 鏃堕棿鏍煎紡鑷畾涔�
+ cfg.EncodeTime = func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
+ enc.AppendString(t.Format("2006-01-02 15:04:05"))
+ }
+ // 鎵撳嵃璺緞鑷畾涔�
+ cfg.EncodeCaller = func(caller zapcore.EntryCaller, encoder zapcore.PrimitiveArrayEncoder) {
+ encoder.AppendString(getFilePath(caller))
+ }
+ // 绾у埆鏄剧ず鑷畾涔�
+ cfg.EncodeLevel = func(level zapcore.Level, encoder zapcore.PrimitiveArrayEncoder) {
+ encoder.AppendString(level.String())
+ }
+ return zapcore.NewJSONEncoder(cfg)
+}
+
+// WithKey 娣诲姞鍗曚釜閿�.
+func (slf *JsonLog) WithKey(key string) Encoder {
+ slf.val = slf.val + key + " "
+ return slf
+}
+
+// WithField 娣诲姞瀛楁.
+func (slf *JsonLog) WithField(key, val string) Encoder {
+ slf.fields = append(slf.fields, zap.String(key, val))
+ return slf
+}
+
+func (slf *JsonLog) Debug(msg string) {
+ _logger.Debug(slf.val+msg, slf.fields...)
+}
+
+func (slf *JsonLog) Debugf(format string, v ...interface{}) {
+ _logger.Debug(fmt.Sprintf(slf.val+format, v...), slf.fields...)
+}
+
+func (slf *JsonLog) Info(msg string) {
+ _logger.Info(slf.val+msg, slf.fields...)
+}
+
+func (slf *JsonLog) Infof(format string, v ...interface{}) {
+ _logger.Info(fmt.Sprintf(slf.val+format, v...), slf.fields...)
+}
+
+func (slf *JsonLog) Warn(msg string) {
+ _logger.Warn(slf.val+msg, slf.fields...)
+}
+
+func (slf *JsonLog) Warnf(format string, v ...interface{}) {
+ _logger.Warn(fmt.Sprintf(slf.val+format, v...), slf.fields...)
+}
+
+func (slf *JsonLog) Error(msg string) {
+ _logger.Error(slf.val+msg, slf.fields...)
+}
+
+func (slf *JsonLog) Errorf(format string, v ...interface{}) {
+ _logger.Error(fmt.Sprintf(slf.val+format, v...), slf.fields...)
+}
+
+func (slf *JsonLog) Fatal(msg string) {
+ _logger.Fatal(slf.val+msg, slf.fields...)
+}
+
+func (slf *JsonLog) Fatalf(format string, v ...interface{}) {
+ _logger.Fatal(fmt.Sprintf(slf.val+format, v...), slf.fields...)
+}
diff --git a/pkg/logx/service.go b/pkg/logx/service.go
new file mode 100644
index 0000000..4416eee
--- /dev/null
+++ b/pkg/logx/service.go
@@ -0,0 +1,49 @@
+package logx
+
+import (
+ "fmt"
+)
+
+func Sync() {
+ _ = _logger.Sync()
+}
+
+func Debug(msg string) {
+ _logger.Debug(msg)
+}
+
+func Debugf(format string, v ...interface{}) {
+ _logger.Debug(fmt.Sprintf(format, v...))
+}
+
+func Info(msg string) {
+ _logger.Info(msg)
+}
+
+func Infof(format string, v ...interface{}) {
+ _logger.Info(fmt.Sprintf(format, v...))
+}
+
+func Warn(msg string) {
+ _logger.Warn(msg)
+}
+
+func Warnf(format string, v ...interface{}) {
+ _logger.Warn(fmt.Sprintf(format, v...))
+}
+
+func Error(msg string) {
+ _logger.Error(msg)
+}
+
+func Errorf(format string, v ...interface{}) {
+ _logger.Error(fmt.Sprintf(format, v...))
+}
+
+func Fatal(msg string) {
+ _logger.Fatal(msg)
+}
+
+func Fatalf(format string, v ...interface{}) {
+ _logger.Fatal(fmt.Sprintf(format, v...))
+}
diff --git a/request/jwt.go b/request/jwt.go
new file mode 100644
index 0000000..0e3b5a4
--- /dev/null
+++ b/request/jwt.go
@@ -0,0 +1,20 @@
+package request
+
+import (
+ "github.com/dgrijalva/jwt-go"
+ "srm/constvar"
+)
+
+// Custom claims structure
+type CustomClaims struct {
+ BaseClaims
+ BufferTime int64
+ jwt.StandardClaims
+}
+
+type BaseClaims struct {
+ UserId string
+ Username string
+ ParentId string
+ UserType constvar.UserType
+}
--
Gitblit v1.8.0