package txcloudapi import ( "crypto/hmac" "crypto/sha1" "encoding/base64" "fmt" "net/http" "time" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) const ( source = "market" StatusErr = -1 //单号或代码错误 StatusNull = 0 //暂无轨迹 StatusAccept = 1 //快递收件 StatusDelivering = 2 //在途中 StatusFinished = 3 //已签收 StatusProblem = 4 //问题件 (派件不成功或要求择日派送) StatusException = 5 //疑难件(收件人拒绝签收,地址有误或不能送达派送区域,收费等原因无法正常派送) StatusFailed = 6 //退件签收 ) type API struct { secretID string secretKey string client *http.Client config *platformapi.APIConfig } func New(secretID, secretKey string, config ...*platformapi.APIConfig) *API { curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } return &API{ secretID: secretID, secretKey: secretKey, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, } } func calcAuthorization(source string, secretId string, secretKey string) (auth string, datetime string, err error) { timeLocation, _ := time.LoadLocation("Etc/GMT") datetime = time.Now().In(timeLocation).Format("Mon, 02 Jan 2006 15:04:05 GMT") signStr := fmt.Sprintf("x-date: %s\nx-source: %s", datetime, source) // hmac-sha1 mac := hmac.New(sha1.New, []byte(secretKey)) mac.Write([]byte(signStr)) sign := base64.StdEncoding.EncodeToString(mac.Sum(nil)) auth = fmt.Sprintf("hmac id=\"%s\", algorithm=\"hmac-sha1\", headers=\"x-date x-source\", signature=\"%s\"", secretId, sign) return auth, datetime, nil } func (a *API) AccessAPI(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { // 签名 auth, datetime, _ := calcAuthorization(source, a.secretID, a.secretKey) err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(url, "", params), nil) request.Header.Set("X-Source", source) request.Header.Set("X-Date", datetime) request.Header.Set("Authorization", auth) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") return request }, a.config, func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { if jsonResult1 == nil { return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") } if err == nil { if jsonResult1["code"].(string) != "OK" { errLevel = platformapi.ErrLevelGeneralFail err = utils.NewErrorCode(jsonResult1["msg"].(string), jsonResult1["code"].(string)) } retVal = jsonResult1 } return errLevel, err }) return retVal, err } func (a *API) AccessAPI2(url string, params map[string]interface{}) (retVal map[string]interface{}, err error) { // 签名 auth, datetime, _ := calcAuthorization(source, a.secretID, a.secretKey) err = platformapi.AccessPlatformAPIWithRetry(a.client, func() *http.Request { request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(url, "", params), nil) request.Header.Set("X-Source", source) request.Header.Set("X-Date", datetime) request.Header.Set("Authorization", auth) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") return request }, a.config, func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) { if jsonResult1 == nil { return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil") } if err == nil { if !jsonResult1["Result"].(map[string]interface{})["success"].(bool) { errLevel = platformapi.ErrLevelGeneralFail err = utils.NewErrorCode(jsonResult1["Result"].(map[string]interface{})["errMsg"].(string), "false") } retVal = jsonResult1 } return errLevel, err }) return retVal, err } type GetWaybillDetailInfoResult struct { Code string `json:"code"` No string `json:"no"` Type string `json:"type"` List []struct { Content string `json:"content"` Time string `json:"time"` } `json:"list"` State string `json:"state"` Msg string `json:"msg"` Name string `json:"name"` Site string `json:"site"` Phone string `json:"phone"` Logo string `json:"logo"` Courier string `json:"courier"` CourierPhone string `json:"courierPhone"` UpdateTime string `json:"updateTime"` TakeTime string `json:"takeTime"` } func (a *API) GetWaybillDetailInfo(vendorWaybillID, comType string) (getWaybillDetailInfoResult *GetWaybillDetailInfoResult, err error) { params := map[string]interface{}{ "num": vendorWaybillID, } if comType != "" { params["com"] = comType } result, err := a.AccessAPI("https://service-5hof02so-1300683954.gz.apigw.tencentcs.com/release/kuaidi", params) if err == nil { utils.Map2StructByJson(result, &getWaybillDetailInfoResult, false) } return getWaybillDetailInfoResult, err } type AddressDistinguishResult struct { AddressDetail string `json:"addressDetail"` City string `json:"city"` CityCode int `json:"cityCode"` District string `json:"district"` DistrictCode int `json:"districtCode"` DivisionZip string `json:"divisionZip"` MobileNO string `json:"mobileNO"` PersonalName string `json:"personalName"` Province string `json:"province"` ProvinceCode int `json:"provinceCode"` Lng float64 `json:"lng"` Lat float64 `json:"lat"` } func (a *API) AddressDistinguish(address string) (addressDistinguishResult *AddressDistinguishResult, err error) { params := map[string]interface{}{ "address": address, } result, err := a.AccessAPI2("https://service-7daeqy5n-1301652365.bj.apigw.tencentcs.com/release/address_parse", params) if err == nil { utils.Map2StructByJson(result["Result"].(map[string]interface{})["data"], &addressDistinguishResult, false) } return addressDistinguishResult, err }