You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
go-library/service/tbk/Tbk.go

191 lines
4.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package tbk
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/bitly/go-simplejson"
"github.com/dtapps/go-library/service"
"github.com/nilorg/sdk/convert"
"io"
"io/ioutil"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
)
var (
// AppKey 应用Key
AppKey string
// AppSecret 秘密
AppSecret string
// Router 环境请求地址
Router = "https://eco.taobao.com/router/rest"
// Session 用户登录授权成功后TOP颁发给应用的授权信息。当此API的标签上注明“需要授权”则此参数必传“不需要授权”则此参数不需要传“可选授权”则此参数为可选
Session string
// Timeout ...
Timeout time.Duration
)
// Parameter 参数
type Parameter map[string]interface{}
// copyParameter 复制参数
func copyParameter(srcParams Parameter) Parameter {
newParams := make(Parameter)
for key, value := range srcParams {
newParams[key] = value
}
return newParams
}
// execute 执行API接口
func execute(param Parameter) (bytes []byte, err error) {
err = checkConfig()
if err != nil {
return
}
var req *http.Request
req, err = http.NewRequest("POST", Router, strings.NewReader(param.getRequestData()))
if err != nil {
return
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
httpClient := &http.Client{}
httpClient.Timeout = Timeout
var response *http.Response
response, err = httpClient.Do(req)
if err != nil {
return
}
if response.StatusCode != 200 {
err = fmt.Errorf("请求错误:%d", response.StatusCode)
return
}
defer response.Body.Close()
bytes, err = ioutil.ReadAll(response.Body)
return
}
// Execute 执行API接口
func Execute(method string, param Parameter) (res *simplejson.Json, err error) {
param["method"] = method
param.setRequestData()
var bodyBytes []byte
bodyBytes, err = execute(param)
if err != nil {
return
}
return bytesToResult(bodyBytes)
}
func bytesToResult(bytes []byte) (res *simplejson.Json, err error) {
res, err = simplejson.NewJson(bytes)
if err != nil {
return
}
if responseError, ok := res.CheckGet("error_response"); ok {
if subMsg, subOk := responseError.CheckGet("sub_msg"); subOk {
err = errors.New(subMsg.MustString())
} else {
err = errors.New(responseError.Get("msg").MustString())
}
res = nil
}
return
}
// 检查配置
func checkConfig() error {
if AppKey == "" {
return errors.New("AppKey 不能为空")
}
if AppSecret == "" {
return errors.New("AppSecret 不能为空")
}
if Router == "" {
return errors.New("Router 不能为空")
}
return nil
}
func (p Parameter) setRequestData() {
hh, _ := time.ParseDuration("8h")
loc := time.Now().UTC().Add(hh)
p["timestamp"] = strconv.FormatInt(loc.Unix(), 10)
p["format"] = "json"
p["app_key"] = AppKey
p["v"] = "2.0"
p["sign_method"] = "md5"
p["partner_id"] = "Nilorg"
if Session != "" {
p["session"] = Session
}
// 设置签名
p["sign"] = getSign(p)
}
// 获取请求数据
func (p Parameter) getRequestData() string {
// 公共参数
args := url.Values{}
// 请求参数
for key, val := range p {
args.Set(key, interfaceToString(val))
}
return args.Encode()
}
// 获取签名
func getSign(params Parameter) string {
// 获取Key
keys := []string{}
for k := range params {
keys = append(keys, k)
}
// 排序asc
sort.Strings(keys)
// 把所有参数名和参数值串在一起
query := bytes.NewBufferString(AppSecret)
for _, k := range keys {
query.WriteString(k)
query.WriteString(interfaceToString(params[k]))
}
query.WriteString(AppSecret)
// 使用MD5加密
h := md5.New()
io.Copy(h, query)
// 把二进制转化为大写的十六进制
return strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
}
func interfaceToString(src interface{}) string {
if src == nil {
panic(service.ErrTypeIsNil)
}
switch src.(type) {
case string:
return src.(string)
case int, int8, int32, int64:
case uint8, uint16, uint32, uint64:
case float32, float64:
return convert.ToString(src)
}
data, err := json.Marshal(src)
if err != nil {
panic(err)
}
return string(data)
}