package jdlclient import ( "bytes" "crypto/hmac" "crypto/md5" "crypto/sha1" "crypto/sha256" "crypto/sha512" "encoding/base64" "fmt" "io/ioutil" "net/http" "strings" "sync" "time" "xiaoniaokuaiyan.com/xiaoniao/config" ) /** * @Author: qz * @Date: 2022/6/14 13:35 * @Description: */ type client struct { appSecret string accessToken string appKey string algorithm string baseUri string domain string CustomerCode string //月结号 } var jinstance *client var jonce sync.Once func createJDL() { var ( dsec = config.IniConf.Section("jdl") appkey = dsec.Key("app_key").Value() appsecret = dsec.Key("app_secret").Value() apptoken = dsec.Key("access_token").Value() baseuri = dsec.Key("base_uri").Value() code = dsec.Key("code").Value() ) //var ( // appkey = "4159281e504c405c8e463f3e25641ef1" // appsecret = "3f4088de32c8466889c63ab66f97f027" // apptoken = "6efe97697e0d46cd8f4522537ef2d10f" // baseuri = "https://api.jdl.com" //) jinstance = &client{ appSecret: appsecret, accessToken: apptoken, appKey: appkey, algorithm: "md5-salt", baseUri: baseuri, domain: "express", CustomerCode: code, } } func GetJDLClient() *client { jonce.Do(func() { createJDL() config.RegistChangeCallback(createJDL) }) return jinstance } func (c *client) DoRequest(req JdLRequest) ([]byte, error) { hc := http.Client{} timestamp := time.Now().Format("2006-01-02 15:04:05") content := strings.Join([]string{ c.appSecret, "access_token", c.accessToken, "app_key", c.appKey, "method", req.GetPath(), "param_json", req.GetBody(), "timestamp", timestamp, "v", "2.0", c.appSecret, }, "") sign, err := Sign(c.algorithm, []byte(content), c.appSecret) if err != nil { panic(err) } uri := c.baseUri + req.GetPath() httpRequest, err := http.NewRequest("POST", uri, bytes.NewReader([]byte(req.GetBody()))) if err != nil { panic(err) } query := httpRequest.URL.Query() query.Add("LOP-DN", c.domain) query.Add("app_key", c.appKey) query.Add("access_token", c.accessToken) query.Add("timestamp", timestamp) query.Add("v", "2.0") query.Add("sign", sign) query.Add("algorithm", c.algorithm) httpRequest.URL.RawQuery = query.Encode() _, offset := time.Now().Zone() httpRequest.Header.Add("lop-tz", fmt.Sprintf("%d", offset/3600)) httpRequest.Header.Add("User-Agent", "lop-http/go") httpResponse, err := hc.Do(httpRequest) if err != nil { //panic(err) return nil, err } b, err := ioutil.ReadAll(httpResponse.Body) if err != nil { //panic(b) return nil, err } //println(httpResponse.Status) //for k, v := range httpResponse.Header { // fmt.Printf("%s: %s\n", k, strings.Join(v, ", ")) //} println(string(b)) return b, nil } func Sign(algorithm string, data []byte, secret string) (string, error) { if algorithm == "md5-salt" { h := md5.New() if _, err := h.Write(data); err != nil { return "", err } return fmt.Sprintf("%x", h.Sum(nil)), nil } else if algorithm == "HMacMD5" { h := hmac.New(md5.New, []byte(secret)) if _, err := h.Write(data); err != nil { return "", err } return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } else if algorithm == "HMacSHA1" { h := hmac.New(sha1.New, []byte(secret)) if _, err := h.Write(data); err != nil { return "", err } return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } else if algorithm == "HMacSHA256" { h := hmac.New(sha256.New, []byte(secret)) if _, err := h.Write(data); err != nil { return "", err } return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } else if algorithm == "HMacSHA512" { h := hmac.New(sha512.New, []byte(secret)) if _, err := h.Write(data); err != nil { return "", err } return base64.StdEncoding.EncodeToString(h.Sum(nil)), nil } return "", fmt.Errorf("algorithm %s not supported yet", algorithm) }