base.go 2.7 KB
package schl

import (
	"context"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"github.com/gogf/gf/container/garray"
	"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/util/gconv"
	"github.com/gogf/gf/util/grand"
	"regexp"
	"sort"
	"strings"
)

var server *Config

type Config struct {
	ApiUrl    string
	AppKey    string
	AppSecret string
	ImgUrl    string
}

const pkgName = "schl"

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

func (c *Config) Post(ctx context.Context, api string, bodyMap g.Map) (result string, err error) {

	Start := gtime.TimestampMilli()
	pubilcParams := new(PubilcParams)
	pubilcParams.AppID = c.AppKey
	pubilcParams.Timestamp = gtime.TimestampStr()
	pubilcParams.Nonce = grand.S(16, false)
	secret := c.AppSecret
	sign := c.Sign(ctx, *pubilcParams, bodyMap, secret)

	defer func() {
		ctx = context.WithValue(ctx, "URI", api)
		if err != nil {
			g.Log().Ctx(ctx).Cat("error").Async(true).
				Infof("参数【%v】错误【%v】响应时间:【%v ms】", gjson.New(bodyMap).MustToJsonString(), err.Error(), gtime.TimestampMilli()-Start)
		} else {
			g.Log().Ctx(ctx).Cat(pkgName).Async(true).
				Infof("参数【%v】响应【%v】响应时间:【%v ms】", gjson.New(bodyMap).MustToJsonString(), result, gtime.TimestampMilli()-Start)
		}
	}()

	pubilcParams.Signature = sign

	pubilcParamsMap := gconv.Map(pubilcParams)
	for k, v := range pubilcParamsMap {
		bodyMap[k] = v
	}
	response, err := g.Client().Ctx(ctx).
		Post(c.ApiUrl+api, bodyMap)
	defer func() {
		_ = response.Close()
	}()
	if nil != err {
		return
	}
	result, _ = gregex.ReplaceString(`\s`, "", response.ReadAllString())
	return
}

func (c *Config) Sign(ctx context.Context, pubilcParams PubilcParams, params g.Map, secret string) (sign string) {

	allMaps := make(map[string]string)
	var arr = garray.New().Append("appId", "timestamp", "nonce")
	for k, v := range gconv.MapStrStr(pubilcParams) {
		if arr.Contains(k) {
			allMaps[k] = v
		}
	}
	allMaps["secret"] = secret

	for k, v := range params {
		re3, _ := regexp.Compile(`\s`)
		allMaps[k] = re3.ReplaceAllString(gconv.String(v), "")
	}

	keys := make([]string, 0)
	for k := range allMaps {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	paramsString := ""
	for k, v := range keys {
		if k > 0 {
			paramsString += "&"
		}
		paramsString += v + "=" + allMaps[v]
	}

	paramsString += "&key=" + secret

	hmacSha256String := hmacSha256(paramsString, secret)

	sign = strings.ToUpper(hmacSha256String)
	return
}

func hmacSha256(data string, secret string) string {
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(data))
	return hex.EncodeToString(h.Sum(nil))
}