Merge branch 'master' of http://192.168.5.5:10010/r/aps/WMS
| | |
| | | RuleType_Product RuleType = iota + 1 //产品上架规则 |
| | | RuleType_ProductCategory //产品类别上架规则 |
| | | ) |
| | | |
| | | type UserType int |
| | | |
| | | const ( |
| | | UserTypeSuper UserType = iota + 1 // 超级管理员 |
| | | UserTypePrimary // 主账户 |
| | | UserTypeSub // 子账户 |
| | | ) |
| | |
| | | // @Tags 位置 |
| | | // @Summary 获取位置列表 |
| | | // @Produce application/json |
| | | // @Param object body request.GetProductList true "查询参数" |
| | | // @Param object body request.GetLocationList true "查询参数" |
| | | // @Success 200 {object} util.ResponseList{data=[]models.Location} "成功" |
| | | // @Router /api-wms/v1/location/getLocationList [post] |
| | | func (slf LocationController) GetLocationList(c *gin.Context) { |
| | |
| | | if params.PageInfo.Check() { |
| | | search.SetPage(params.Page, params.PageSize) |
| | | } |
| | | list, total, err := search.SetKeyword(params.KeyWord).SetJointName(params.JointName).SetOrder("created_at desc").Find() |
| | | list, total, err := search.SetKeyword(params.KeyWord).SetType(params.Type).SetJointName(params.JointName).SetOrder("created_at desc").Find() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "查找失败") |
| | | return |
| | |
| | | "in": "body", |
| | | "required": true, |
| | | "schema": { |
| | | "$ref": "#/definitions/request.GetProductList" |
| | | "$ref": "#/definitions/request.GetLocationList" |
| | | } |
| | | } |
| | | ], |
| | |
| | | } |
| | | } |
| | | }, |
| | | "request.GetLocationList": { |
| | | "type": "object", |
| | | "properties": { |
| | | "jointName": { |
| | | "description": "拼接名称", |
| | | "type": "string" |
| | | }, |
| | | "keyWord": { |
| | | "type": "string" |
| | | }, |
| | | "page": { |
| | | "description": "页码", |
| | | "type": "integer" |
| | | }, |
| | | "pageSize": { |
| | | "description": "每页大小", |
| | | "type": "integer" |
| | | }, |
| | | "type": { |
| | | "type": "integer" |
| | | } |
| | | } |
| | | }, |
| | | "request.GetProductList": { |
| | | "type": "object", |
| | | "properties": { |
| | |
| | | "in": "body", |
| | | "required": true, |
| | | "schema": { |
| | | "$ref": "#/definitions/request.GetProductList" |
| | | "$ref": "#/definitions/request.GetLocationList" |
| | | } |
| | | } |
| | | ], |
| | |
| | | } |
| | | } |
| | | }, |
| | | "request.GetLocationList": { |
| | | "type": "object", |
| | | "properties": { |
| | | "jointName": { |
| | | "description": "拼接名称", |
| | | "type": "string" |
| | | }, |
| | | "keyWord": { |
| | | "type": "string" |
| | | }, |
| | | "page": { |
| | | "description": "页码", |
| | | "type": "integer" |
| | | }, |
| | | "pageSize": { |
| | | "description": "每页大小", |
| | | "type": "integer" |
| | | }, |
| | | "type": { |
| | | "type": "integer" |
| | | } |
| | | } |
| | | }, |
| | | "request.GetProductList": { |
| | | "type": "object", |
| | | "properties": { |
| | |
| | | wareHouseCode: |
| | | type: string |
| | | type: object |
| | | request.GetLocationList: |
| | | properties: |
| | | jointName: |
| | | description: 拼接名称 |
| | | type: string |
| | | keyWord: |
| | | type: string |
| | | page: |
| | | description: 页码 |
| | | type: integer |
| | | pageSize: |
| | | description: 每页大小 |
| | | type: integer |
| | | type: |
| | | type: integer |
| | | type: object |
| | | request.GetProductList: |
| | | properties: |
| | | categoryId: |
| | |
| | | name: object |
| | | required: true |
| | | schema: |
| | | $ref: '#/definitions/request.GetProductList' |
| | | $ref: '#/definitions/request.GetLocationList' |
| | | produces: |
| | | - application/json |
| | | responses: |
| | |
| | | basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25 |
| | | github.com/dgrijalva/jwt-go v3.2.0+incompatible |
| | | github.com/gin-gonic/gin v1.9.0 |
| | | github.com/golang-jwt/jwt/v4 v4.5.0 |
| | | github.com/google/uuid v1.3.1 |
| | | github.com/nsqio/go-nsq v1.1.0 |
| | | github.com/open-policy-agent/opa v0.57.1 |
| | |
| | | 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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= |
| | | 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/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= |
| | | github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= |
| | | github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= |
| | |
| | | package middleware |
| | | |
| | | import ( |
| | | "errors" |
| | | "fmt" |
| | | "strings" |
| | | "time" |
| | | "wms/conf" |
| | | |
| | | jwt "github.com/dgrijalva/jwt-go" |
| | | "github.com/gin-gonic/gin" |
| | | "wms/extend/util" |
| | | "strings" |
| | | "wms/pkg/contextx" |
| | | "wms/pkg/ecode" |
| | | ) |
| | | |
| | | func validateToken(tokenString string) (util.JSON, error) { |
| | | secretKey := []byte(conf.WebConf.JWTSecret) |
| | | |
| | | token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) { |
| | | // Don't forget to validate the alg is what you expect: |
| | | if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { |
| | | return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) |
| | | } |
| | | |
| | | return secretKey, nil |
| | | }) |
| | | |
| | | if err != nil { |
| | | return util.JSON{}, err |
| | | } |
| | | |
| | | if !token.Valid { |
| | | return util.JSON{}, errors.New("invalid token") |
| | | } |
| | | |
| | | return token.Claims.(jwt.MapClaims), nil |
| | | } |
| | | |
| | | // JWTMiddleware parses JWT token from cookie and stores data and expires date to the context |
| | | // JWT Token can be passed as cookie, or Authorization header |
| | | func JWTMiddleware() gin.HandlerFunc { |
| | | func JWTAuth() gin.HandlerFunc { |
| | | return func(c *gin.Context) { |
| | | tokenString, err := c.Cookie("token") |
| | | // failed to read cookie |
| | | if err != nil { |
| | | // try reading HTTP Header |
| | | authorization := c.Request.Header.Get("Authorization") |
| | | if authorization == "" { |
| | | c.Next() |
| | | return |
| | | } |
| | | sp := strings.Split(authorization, "Bearer ") |
| | | // invalid token |
| | | if len(sp) < 1 { |
| | | c.Next() |
| | | return |
| | | } |
| | | tokenString = sp[1] |
| | | ctx := new(contextx.Context).SetCtx(c) |
| | | // 我们这里jwt鉴权取头部信息 Authorization 登录时回返回token信息 这里前端需要把token存储到cookie或者本地localStorage中 不过需要跟后端协商过期时间 可以约定刷新令牌或者重新登录 |
| | | token := c.Request.Header.Get("Authorization") |
| | | if token == "" { |
| | | ctx.Fail(ecode.JWTEmpty) |
| | | c.Abort() |
| | | return |
| | | } |
| | | |
| | | tokenData, err := validateToken(tokenString) |
| | | slices := strings.Split(token, " ") |
| | | if len(slices) == 2 { |
| | | token = slices[1] |
| | | } |
| | | j := NewJWT() |
| | | // parseToken 解析token包含的信息 |
| | | claims, err := j.ParseToken(token) |
| | | if err != nil { |
| | | fmt.Println(err.Error()) |
| | | if err == TokenExpired { |
| | | c.Next() |
| | | return |
| | | } |
| | | c.Next() |
| | | return |
| | | } |
| | | |
| | | userParentId := tokenData["parentId"].(string) |
| | | if userParentId == conf.WebConf.NodeId { |
| | | c.Set("parentId", userParentId) |
| | | } else { |
| | | c.Next() |
| | | return |
| | | } |
| | | |
| | | c.Set("token_expire", tokenData["exp"]) |
| | | c.Set("claims", claims) |
| | | c.Next() |
| | | } |
| | | } |
| | | |
| | | func GenerateToken(data interface{}) (string, error) { |
| | | // token is valid for 1 hour |
| | | date := time.Now().Add(time.Hour * 12) |
| | | |
| | | token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ |
| | | "user": data, |
| | | "exp": date.Unix(), |
| | | }) |
| | | |
| | | secretKey := []byte(conf.WebConf.JWTSecret) |
| | | |
| | | tokenString, err := token.SignedString(secretKey) |
| | | |
| | | return tokenString, err |
| | | } |
New file |
| | |
| | | package middleware |
| | | |
| | | import ( |
| | | "errors" |
| | | "github.com/golang-jwt/jwt/v4" |
| | | "wms/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 创建一个token |
| | | func (j *JWT) CreateToken(claims request.CustomClaims) (string, error) { |
| | | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) |
| | | return token.SignedString(j.SigningKey) |
| | | } |
| | | |
| | | // ParseToken 解析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 |
| | | } |
| | | } |
New file |
| | |
| | | package request |
| | | |
| | | import ( |
| | | "github.com/dgrijalva/jwt-go" |
| | | "wms/constvar" |
| | | ) |
| | | |
| | | // Custom claims structure |
| | | type CustomClaims struct { |
| | | BaseClaims |
| | | BufferTime int64 |
| | | jwt.StandardClaims |
| | | } |
| | | |
| | | type BaseClaims struct { |
| | | UserId string |
| | | Username string |
| | | ParentId string |
| | | UserType constvar.UserType |
| | | } |
| | |
| | | |
| | | type GetLocationList struct { |
| | | PageInfo |
| | | Type int `json:"type"` |
| | | KeyWord string `json:"keyWord"` |
| | | JointName string `json:"jointName"` //拼接名称 |
| | | } |
| | |
| | | r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) |
| | | |
| | | urlPrefix := "/api-wms/v1" |
| | | r.Use(middleware.JWTAuth()) |
| | | |
| | | // 组织管理 |
| | | departmentController := new(controllers.DepartmentController) |