tm.go 3.5 KB
package tm

import (
	"context"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/gtime"
	"github.com/gogf/gf/util/gconv"
	"github.com/gogf/gf/util/grand"
	"net/url"
	"reflect"
	"sort"
	"strings"
	"time"
)

type Config struct {
	AppKey    string
	AppSecret string
	BizUid    string
}

var server *Config

const PkgName = "tm"

const (
	apiUrl           string = "http://linkedmall.aliyuncs.com/"
	regionId         string = "cn-hangzhou"
	bizId            string = "LMALL201912050002"
	signatureVersion string = "1.0"
	signatureMethod  string = "HMAC-SHA1"
	version          string = "2018-01-16"
	format           string = "JSON"
	typeAnony        string = "ANONY"
	typeEp           string = "EP"
)

func New(req *Config) {
	server = req
	return
}

func specialUrlEncode(req string) (res string) {
	req = url.QueryEscape(req)
	req = strings.Replace(req, "+", "%20", -1)
	req = strings.Replace(req, "*", "%2A", -1)
	req = strings.Replace(req, "*7E", "~", -1)
	res = req
	return
}

func sign(param map[string]string) {
	var keys []string

	mewparam := param
	for k := range mewparam {
		keys = append(keys, k)
	}

	sort.Strings(keys)

	var signStr string

	u := url.Values{}
	for _, v := range keys {
		u.Set(v, mewparam[v])
	}
	signStr += specialUrlEncode(u.Encode())
	signStr = "POST&" + specialUrlEncode("/") + "&" + signStr

	param["Signature"] = hmacsha1Base64(signStr)

	return
}

func hmacsha1Base64(str string) string {
	appSecret := []byte(server.AppSecret + "&")
	mac := hmac.New(sha1.New, appSecret)
	mac.Write([]byte(str))
	return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

func post(ctx context.Context, method string, params map[string]string) (str string, err error) {
	Start := gtime.TimestampMilli()
	curtime := time.Now().UTC()
	params["Action"] = method
	params["AccessKeyId"] = server.AppKey
	params["BizId"] = bizId
	params["RegionId"] = regionId
	params["SignatureMethod"] = signatureMethod
	params["SignatureVersion"] = signatureVersion
	params["Version"] = version
	params["Format"] = format
	params["SignatureNonce"] = grand.S(32)
	params["Timestamp"] = curtime.Format("2006-01-02T15:04:05Z")

	sign(params)

	Request := g.Client()
	Request.SetHeader("Content-Type", "application/x-www-form-urlencoded")
	Request.Timeout(3 * time.Second)
	resp, err := Request.Post(apiUrl, params)
	defer func() {
		_ = resp.Close()
		paramStr := gjson.New(params).MustToJsonString()
		ctx = context.WithValue(ctx, "Method", "POST")
		ctx = context.WithValue(ctx, "URI", apiUrl+params["Action"])
		if err != nil {
			g.Log().Ctx(ctx).Infof("参数【%v】错误【%v】响应时间【%v】", paramStr, err.Error(), gtime.TimestampMilli()-Start)
		} else {
			g.Log().Ctx(ctx).Cat(PkgName).Infof("参数【%v】响应【%v】响应时间【%v】", paramStr, str, gtime.TimestampMilli()-Start)
		}
	}()
	str = resp.ReadAllString()
	return

}

func convert(pre string, req []map[string]interface{}) (res map[string]string) {
	res = make(map[string]string)
	for k, v := range req {
		for key, val := range v {
			if reflect.TypeOf(val).String() == "[]string" {
				for key2, val2 := range gconv.Strings(val) {
					res[pre+"."+gconv.String(k+1)+"."+key+"."+gconv.String(key2+1)] = gconv.String(val2)
				}
			} else {
				res[pre+"."+gconv.String(k+1)+"."+key] = gconv.String(val)
			}
		}
	}
	return
}

type CommonRes struct {
	Code      string `json:"Code"`
	Message   string `json:"Message"`
	RequestId string `json:"RequestId"`
}