| | |
| | | |
| | | type ( |
| | | webConf struct { |
| | | Host string // 本机ip地址 |
| | | Port string // 端口号 |
| | | APPort string // 本机作为的Grpc服务端的端口号 |
| | | AlHost string // 算法服务ip地址 |
| | | AlPort string // 算法服务端口号 |
| | | NodeId string // 主账户用户名 |
| | | OssType string // 对象存储类型 |
| | | JWTSecret string |
| | | Host string // 本机ip地址 |
| | | Port string // 端口号 |
| | | APPort string // 本机作为的Grpc服务端的端口号 |
| | | AlHost string // 算法服务ip地址 |
| | | AlPort string // 算法服务端口号 |
| | | NodeId string // 主账户用户名 |
| | | OssType string // 对象存储类型 |
| | | JWTKey string |
| | | } |
| | | |
| | | nsqConf struct { |
| | |
| | | web: |
| | | port: 8008 |
| | | host: 192.168.20.119 |
| | | jwtKey: 12345 |
| | | service: |
| | | aps: 192.168.20.120:9091 |
| | | db: |
| | |
| | | "outsourcing/request" |
| | | "outsourcing/service" |
| | | "outsourcing/service/outsourcing" |
| | | "outsourcing/utils/jwt" |
| | | ) |
| | | |
| | | type OrderController struct{} |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | return |
| | | } |
| | | list, total, err := models.NewOutsourcingOrderSearch().SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetOrder("id desc").Find() |
| | | |
| | | companyId := jwt.GetCompanyID(c) |
| | | if companyId == 0 { |
| | | util.ResponseFormat(c, code.InternalError, "内部错误") |
| | | return |
| | | } |
| | | |
| | | list, total, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(companyId).SetPage(params.Page, params.PageSize).SetKeyword(params.Keyword).SetOrder("id desc").Find() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.InternalError, "查询错误") |
| | | return |
| | |
| | | // @Success 200 {object} util.ResponseList{data=request.OutsourcingOrderOverview} "成功" |
| | | // @Router /api-outsourcing/v1/order/overview [get] |
| | | func (slf *OrderController) OrderOverview(c *gin.Context) { |
| | | result, err := models.NewOutsourcingOrderSearch().CountGroupByStatus() |
| | | result, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).CountGroupByStatus() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.InternalError, "查询错误") |
| | | return |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数缺失") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderId).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | list, total, err := models.NewOutsourcingOrderProductSearch().SetPage(params.Page, params.PageSize).SetOutsourcingOrderID(params.OutsourcingOrderId).SetOrder("id desc").Find() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.InternalError, "查询错误") |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "物料申请不能为空") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.ApplyList[0].OutsourcingOrderNumber).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | var apply []*models.OutsourcingMaterialApply |
| | | err := structx.AssignTo(params.ApplyList, &apply) |
| | | err = structx.AssignTo(params.ApplyList, &apply) |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "数据转换失败") |
| | | return |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.Number).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | find, err := models.NewOutsourcingMaterialApplySearch().SetOutsourcingOrderNumber(params.Number).FindNotTotal() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "查询失败") |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetNumber(params.OutsourcingOrderNumber).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | //限定状态参数 |
| | | if params.Status == constvar.OutsourcingOrderStatusCreate || //取消确认 |
| | | params.Status == constvar.OutsourcingOrderStatusWaitProduce || //确认接受 |
| | |
| | | } |
| | | if params.OutsourcingOrderID == 0 { |
| | | util.ResponseFormat(c, code.RequestParamError, "参数缺失") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数缺失") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | if len(params.DeliveryList) == 0 { |
| | | util.ResponseFormat(c, code.RequestParamError, "发货列表不能为空") |
| | | return |
| | |
| | | WaybillNumber: params.WaybillNumber, |
| | | } |
| | | |
| | | err := models.WithTransaction(func(db *gorm.DB) error { |
| | | err := models.NewOutsourcingOrderDeliverySearch().SetOrm(db).Create(delivery) |
| | | err = models.WithTransaction(func(db *gorm.DB) error { |
| | | err = models.NewOutsourcingOrderDeliverySearch().SetOrm(db).Create(delivery) |
| | | if err != nil { |
| | | return err |
| | | } |
| | |
| | | util.ResponseFormat(c, code.RequestParamError, "参数解析失败,数据类型错误") |
| | | return |
| | | } |
| | | |
| | | _, err := models.NewOutsourcingOrderSearch().SetEnterpriseID(jwt.GetCompanyID(c)).SetID(params.OutsourcingOrderID).First() |
| | | if err != nil { |
| | | util.ResponseFormat(c, code.RequestParamError, "订单不存在") |
| | | return |
| | | } |
| | | |
| | | list, err := models.NewOutsourcingOrderDeliveryDetailsSearch(). |
| | | SetOutsourcingOrderID(params.OutsourcingOrderID). |
| | | SetPreload(true). |
| | |
| | | package middleware |
| | | |
| | | import ( |
| | | "errors" |
| | | "fmt" |
| | | "outsourcing/conf" |
| | | "strings" |
| | | "time" |
| | | |
| | | jwt "github.com/dgrijalva/jwt-go" |
| | | "github.com/gin-gonic/gin" |
| | | "outsourcing/extend/util" |
| | | "outsourcing/conf" |
| | | "outsourcing/pkg/contextx" |
| | | "outsourcing/pkg/ecode" |
| | | "outsourcing/utils/jwt" |
| | | "strings" |
| | | ) |
| | | |
| | | 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] |
| | | } |
| | | |
| | | tokenData, err := validateToken(tokenString) |
| | | if err != nil { |
| | | fmt.Println(err.Error()) |
| | | c.Next() |
| | | 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 |
| | | } |
| | | |
| | | userParentId := tokenData["parentId"].(string) |
| | | if userParentId == conf.WebConf.NodeId { |
| | | c.Set("parentId", userParentId) |
| | | } else { |
| | | c.Next() |
| | | slices := strings.Split(token, " ") |
| | | if len(slices) == 2 { |
| | | token = slices[1] |
| | | } |
| | | j := jwt.NewOutsideJWT(conf.WebConf.JWTKey) |
| | | // parseToken 解析token包含的信息 |
| | | claims, err := j.ParseToken(token) |
| | | if err != nil { |
| | | if err == jwt.TokenExpired { |
| | | ctx.Fail(ecode.JWTExpire) |
| | | c.Abort() |
| | | return |
| | | } |
| | | ctx.Fail(ecode.JWTParseErr) |
| | | c.Abort() |
| | | return |
| | | } |
| | | |
| | | c.Set("token_expire", tokenData["exp"]) |
| | | if claims.CompanyId == 0 { |
| | | ctx.Fail(ecode.JWTExpire) |
| | | c.Abort() |
| | | return |
| | | } |
| | | 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 |
| | | } |
| | |
| | | return slf |
| | | } |
| | | |
| | | func (slf *OutsourcingOrderSearch) SetEnterpriseID(id uint) *OutsourcingOrderSearch { |
| | | slf.EnterpriseID = id |
| | | return slf |
| | | } |
| | | |
| | | func (slf *OutsourcingOrderSearch) SetIDs(ids []uint) *OutsourcingOrderSearch { |
| | | slf.IDs = ids |
| | | return slf |
| | |
| | | db = db.Where("id = ?", slf.ID) |
| | | } |
| | | |
| | | if slf.EnterpriseID != 0 { |
| | | db = db.Where("enterprise_id = ?", slf.EnterpriseID) |
| | | } |
| | | |
| | | if len(slf.IDs) != 0 { |
| | | db = db.Where("id in ?", slf.IDs) |
| | | } |
| | |
| | | urlPrefix := "/api-outsourcing/v1" |
| | | |
| | | outsourcingApi := new(controllers.OrderController) |
| | | outsourcingGroup := r.Group(urlPrefix + "/order") |
| | | outsourcingGroup := r.Group(urlPrefix + "/order").Use(middleware.JWTAuth()) |
| | | { |
| | | outsourcingGroup.GET("list", outsourcingApi.OutsourcingOrderList) // 委外订单列表 |
| | | outsourcingGroup.GET("overview", outsourcingApi.OrderOverview) // 委外订单统计 |
New file |
| | |
| | | package jwt |
| | | |
| | | import ( |
| | | "github.com/dgrijalva/jwt-go" |
| | | "github.com/gin-gonic/gin" |
| | | "outsourcing/conf" |
| | | "outsourcing/pkg/logx" |
| | | "strings" |
| | | ) |
| | | |
| | | type OutsideUserClaims struct { |
| | | UserId string |
| | | Username string |
| | | ParentId string |
| | | CompanyId uint |
| | | CompanyName string |
| | | BufferTime int64 |
| | | jwt.StandardClaims |
| | | } |
| | | |
| | | func GetClaims(c *gin.Context) (*OutsideUserClaims, error) { |
| | | token := c.Request.Header.Get("Authorization") |
| | | logx.Infof("GetClaims token:%v", token) |
| | | slices := strings.Split(token, " ") |
| | | if len(slices) == 2 { |
| | | token = slices[1] |
| | | } |
| | | j := NewOutsideJWT(conf.WebConf.JWTKey) |
| | | claims, err := j.ParseToken(token) |
| | | if err != nil { |
| | | logx.Error("从Gin的Context中获取从jwt解析信息失败, 请检查请求头是否存在x-token且claims是否为规定结构") |
| | | } |
| | | return claims, err |
| | | } |
| | | |
| | | // GetCompanyID 从Gin的Context中获取从jwt解析出来的公司ID |
| | | func GetCompanyID(c *gin.Context) uint { |
| | | if claims, exists := c.Get("claims"); !exists { |
| | | if cl, err := GetClaims(c); err != nil { |
| | | return 0 |
| | | } else { |
| | | return cl.CompanyId |
| | | } |
| | | } else { |
| | | waitUse := claims.(*OutsideUserClaims) |
| | | return waitUse.CompanyId |
| | | } |
| | | } |
| | | |
| | | // GetUserInfo 从Gin的Context中获取从jwt解析出来的用户信息 |
| | | func GetUserInfo(c *gin.Context) *OutsideUserClaims { |
| | | if claims, exists := c.Get("claims"); !exists { |
| | | if cl, err := GetClaims(c); err != nil { |
| | | return nil |
| | | } else { |
| | | return cl |
| | | } |
| | | } else { |
| | | waitUse := claims.(*OutsideUserClaims) |
| | | return waitUse |
| | | } |
| | | } |
New file |
| | |
| | | package jwt |
| | | |
| | | import ( |
| | | "errors" |
| | | "github.com/dgrijalva/jwt-go" |
| | | ) |
| | | |
| | | 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:") |
| | | ) |
| | | |
| | | type OutSideJWT struct { |
| | | SigningKey []byte |
| | | } |
| | | |
| | | func NewOutsideJWT(signKey string) *OutSideJWT { |
| | | return &OutSideJWT{ |
| | | []byte(signKey), |
| | | } |
| | | } |
| | | |
| | | // CreateToken 创建一个token |
| | | func (j *OutSideJWT) CreateToken(claims OutsideUserClaims) (string, error) { |
| | | token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) |
| | | return token.SignedString(j.SigningKey) |
| | | } |
| | | |
| | | // ParseToken 解析token |
| | | func (j *OutSideJWT) ParseToken(tokenString string) (*OutsideUserClaims, error) { |
| | | token, err := jwt.ParseWithClaims(tokenString, &OutsideUserClaims{}, 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.(*OutsideUserClaims); ok && token.Valid { |
| | | return claims, nil |
| | | } |
| | | return nil, TokenInvalid |
| | | |
| | | } else { |
| | | return nil, TokenInvalid |
| | | } |
| | | } |