package yunzmall import ( "context" "fmt" "github.com/gogf/gf/container/garray" "github.com/gogf/gf/crypto/gmd5" "github.com/gogf/gf/crypto/gsha1" "github.com/gogf/gf/encoding/gjson" "github.com/gogf/gf/frame/g" "github.com/gogf/gf/os/gtime" "github.com/gogf/gf/text/gregex" "github.com/gogf/gf/text/gstr" "github.com/gogf/gf/util/gconv" "github.com/gogf/gf/util/grand" "net/url" "sort" "time" ) type Client struct { AppKey string AppSecret string accessToken string Url string DB int Source int } const Url = "https://supply.yunzmall.com/supplyapi" const pkgName = "yunzmall" const CacheKey = "yunzmall:token:" func New(req *Client) *Client { if req.DB == 0 { req.DB = 10 } if req.Url == "" { req.Url = Url } return req } // post 请求 func (s *Client) post(ctx context.Context, method string, params g.Map, xToken ...interface{}) (str string, err error) { Start := gtime.TimestampMilli() Request := g.Client().ContentJson() var AppNonce = grand.S(16) var AppTimestamp = gtime.TimestampStr() Request.SetHeader("App-Nonce-Str", grand.S(16)) Request.SetHeader("App-Timestamp", gtime.TimestampStr()) if len(xToken) == 0 { var token string token, err = s.AccessToken(ctx) if err != nil { return } Request.SetHeader("x-token", token) } AppSign, err := s.sign(AppNonce, AppTimestamp, params) if err != nil { return } Request.SetHeader("App-Sign", AppSign) resp, err := Request. Timeout(time.Second*5). Post(s.Url+method, params) defer func() { _ = resp.Close() paramStr := gjson.New(params).MustToJsonString() ctx = context.WithValue(ctx, "Method", "POST") ctx = context.WithValue(ctx, "URI", method) if err != nil { g.Log().Ctx(ctx).Cat(pkgName).Cat("error").Infof("参数【%v】错误【%v】响应时间【%v ms】", paramStr, err.Error(), gtime.TimestampMilli()-Start) } else { g.Log().Ctx(ctx).Cat(pkgName).Infof("参数【%v】响应【%v】响应时间【%v ms】", paramStr, str, gtime.TimestampMilli()-Start) } }() if err != nil { return } str = resp.ReadAllString() return } func (s *Client) get(ctx context.Context, method string, params g.Map, xToken ...interface{}) (str string, err error) { Start := gtime.TimestampMilli() Request := g.Client().ContentJson() var AppNonce = grand.S(16) var AppTimestamp = gtime.TimestampStr() Request.SetHeader("App-Nonce-Str", grand.S(16)) Request.SetHeader("App-Timestamp", gtime.TimestampStr()) if len(xToken) == 0 { var token string token, err = s.AccessToken(ctx) if err != nil { return } Request.SetHeader("x-token", token) } AppSign, err := s.sign(AppNonce, AppTimestamp, params) if err != nil { return } postValues := url.Values{} for k, v := range params { postValues.Add(k, gconv.String(v)) } URL, _ := url.Parse(s.Url + method) URL.RawQuery = postValues.Encode() urlPath := URL.String() Request.SetHeader("App-Sign", AppSign) resp, err := Request. Timeout(time.Second * 5). Get(urlPath) defer func() { _ = resp.Close() paramStr := gjson.New(params).MustToJsonString() ctx = context.WithValue(ctx, "Method", "GET") ctx = context.WithValue(ctx, "URI", method) if err != nil { g.Log().Ctx(ctx).Cat(pkgName).Cat("error").Infof("参数【%v】错误【%v】响应时间【%v ms】", paramStr, err.Error(), gtime.TimestampMilli()-Start) } else { g.Log().Ctx(ctx).Cat(pkgName).Infof("参数【%v】响应【%v】响应时间【%v ms】", paramStr, str, gtime.TimestampMilli()-Start) } }() if err != nil { return } str = resp.ReadAllString() return } func (s *Client) sign(nonce string, timestamp string, param g.Map) (res string, err error) { var keys []string keys = append(keys, "App-Nonce-Str") keys = append(keys, "App-Timestamp") mewparam := gjson.New(param).Map() mewparam["App-Timestamp"] = timestamp mewparam["App-Nonce-Str"] = nonce for k := range mewparam { keys = append(keys, k) } sort.Strings(keys) var array = garray.New() for _, v := range keys { array.Append(fmt.Sprintf("%s=%s", v, gconv.String(mewparam[v]))) } array.Append(fmt.Sprintf("%s=%s", "appKey", s.AppKey)) array.Append(fmt.Sprintf("%s=%s", "appSecret", s.AppSecret)) var str = array.Join("&") str, err = gregex.ReplaceString(`\s`, "", str) if err != nil { return } str = gsha1.Encrypt(str) str = gmd5.MustEncryptString(str) res = gstr.ToUpper(str) return } type CommonRes struct { Code int `json:"code"` Msg string `json:"msg"` }