第三方api接口
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.

191 lines
5.3 KiB

  1. package topsdk
  2. import (
  3. "bytes"
  4. zhios_third_party_utils "code.fnuoos.com/go_rely_warehouse/zyos_go_third_party_api.git/utils"
  5. "fmt"
  6. "io"
  7. "io/ioutil"
  8. "log"
  9. "mime/multipart"
  10. "net"
  11. "net/http"
  12. "net/url"
  13. "strings"
  14. "time"
  15. )
  16. type TopClient struct {
  17. AppKey string
  18. AppSecret string
  19. ServerUrl string
  20. Format string
  21. SignMethod string
  22. ConnectTimeout int64
  23. ReadTimeout int64
  24. Version string
  25. Simplify bool
  26. httpClient *http.Client
  27. }
  28. type HttpTransportConfig struct {
  29. DialTimeout int64
  30. KeepAlive int64
  31. MaxIdleConns int
  32. MaxIdleConnsPerHost int
  33. IdleConnTimeout int64
  34. MaxConnsPerHost int
  35. }
  36. func NewDefaultTopClient(AppKey string, AppSecret string, ServerUrl string, connectTimeount int64, readTimeout int64) TopClient {
  37. var httpTransportConfig = &HttpTransportConfig{
  38. DialTimeout: 30000,
  39. KeepAlive: 30000,
  40. MaxIdleConns: 100,
  41. MaxIdleConnsPerHost: 50,
  42. IdleConnTimeout: 30000,
  43. }
  44. return NewTopClientWithConfig(AppKey, AppSecret, ServerUrl, connectTimeount, readTimeout, httpTransportConfig)
  45. }
  46. func NewTopClientWithConfig(AppKey string, AppSecret string, ServerUrl string, connectTimeount int64, readTimeout int64, httpTransportConfig *HttpTransportConfig) TopClient {
  47. httpClient := http.Client{
  48. Timeout: time.Duration(connectTimeount) * time.Millisecond,
  49. Transport: &http.Transport{
  50. DialContext: (&net.Dialer{
  51. Timeout: time.Duration(httpTransportConfig.DialTimeout) * time.Millisecond,
  52. KeepAlive: time.Duration(httpTransportConfig.KeepAlive) * time.Millisecond,
  53. }).DialContext,
  54. ForceAttemptHTTP2: true,
  55. MaxIdleConns: httpTransportConfig.MaxIdleConns,
  56. MaxIdleConnsPerHost: httpTransportConfig.MaxIdleConnsPerHost,
  57. IdleConnTimeout: time.Duration(httpTransportConfig.IdleConnTimeout) * time.Millisecond,
  58. TLSHandshakeTimeout: 10 * time.Second,
  59. ExpectContinueTimeout: 1 * time.Second,
  60. },
  61. }
  62. return TopClient{
  63. AppKey: AppKey,
  64. AppSecret: AppSecret,
  65. ServerUrl: ServerUrl,
  66. Format: ApiFormat,
  67. SignMethod: SignMethod,
  68. ConnectTimeout: connectTimeount,
  69. ReadTimeout: readTimeout,
  70. Version: TopVersion,
  71. Simplify: true,
  72. httpClient: &httpClient,
  73. }
  74. }
  75. func (client *TopClient) ExecuteWithSession(method string, data map[string]interface{}, fileData map[string]interface{}, session string) (string, error) {
  76. var publicParam = make(map[string]interface{})
  77. publicParam["method"] = method
  78. publicParam["app_key"] = client.AppKey
  79. publicParam["timestamp"] = time.Now().Format(DateFormat)
  80. publicParam["v"] = client.Version
  81. publicParam["sign_method"] = client.SignMethod
  82. publicParam["format"] = client.Format
  83. publicParam["simplify"] = client.Simplify
  84. publicParam["partner_id"] = SdkVersion
  85. if session != "" {
  86. publicParam["session"] = session
  87. }
  88. sign := zhios_third_party_utils.GetSign(publicParam, data, client.AppSecret)
  89. // 构建url
  90. serverUrl, _ := url.Parse(client.ServerUrl)
  91. urlValues := url.Values{}
  92. urlValues.Add("sign", sign)
  93. for k, v := range publicParam {
  94. urlValues.Add(k, fmt.Sprint(v))
  95. }
  96. serverUrl.RawQuery = urlValues.Encode()
  97. urlPath := serverUrl.String()
  98. // 构建body
  99. if fileData != nil && len(fileData) > 0 {
  100. return doPostWithFile(urlPath, data, fileData, client.httpClient)
  101. } else {
  102. return doPost(urlPath, data, client.httpClient)
  103. }
  104. }
  105. func doPost(urlPath string, data map[string]interface{}, httpClient *http.Client) (string, error) {
  106. bodyParam := url.Values{}
  107. for k, v := range data {
  108. bodyParam.Add(k, fmt.Sprint(v))
  109. }
  110. resp, err := httpClient.Post(urlPath, "application/x-www-form-urlencoded", strings.NewReader(bodyParam.Encode()))
  111. if resp != nil {
  112. defer resp.Body.Close()
  113. }
  114. if err != nil {
  115. log.Println("http.PostForm error", err)
  116. return "", err
  117. }
  118. body, err := ioutil.ReadAll(resp.Body)
  119. if err != nil {
  120. log.Println("ioutil.ReadAll", err)
  121. return "", err
  122. }
  123. return string(body), nil
  124. }
  125. func doPostWithFile(urlPath string, data map[string]interface{}, fileData map[string]interface{}, httpClient *http.Client) (string, error) {
  126. bodyBuf := &bytes.Buffer{}
  127. writer := multipart.NewWriter(bodyBuf)
  128. for k, v := range data {
  129. err := writer.WriteField(k, fmt.Sprint(v))
  130. if err != nil {
  131. return "", err
  132. }
  133. }
  134. for k, v := range fileData {
  135. value, ok := v.([]byte)
  136. if ok {
  137. fileWriter, err := writer.CreateFormFile(k, "file")
  138. if err != nil {
  139. return "", err
  140. }
  141. _, err = io.Copy(fileWriter, bytes.NewReader(value))
  142. if err != nil {
  143. return "", err
  144. }
  145. } else {
  146. value, ok := v.(zhios_third_party_utils.FileItem)
  147. if ok {
  148. fileWriter, err := writer.CreateFormFile(k, value.FileName)
  149. if err != nil {
  150. return "", err
  151. }
  152. _, err = io.Copy(fileWriter, bytes.NewReader(value.Content))
  153. if err != nil {
  154. return "", err
  155. }
  156. }
  157. }
  158. }
  159. err := writer.Close()
  160. if err != nil {
  161. return "", err
  162. }
  163. resp, err := httpClient.Post(urlPath, writer.FormDataContentType(), bodyBuf)
  164. if err != nil {
  165. log.Println("http.PostForm error", err)
  166. return "", err
  167. }
  168. defer resp.Body.Close()
  169. body, err := ioutil.ReadAll(resp.Body)
  170. if err != nil {
  171. log.Println("ioutil.ReadAll", err)
  172. return "", err
  173. }
  174. return string(body), nil
  175. }
  176. func (client *TopClient) Execute(method string, data map[string]interface{}, fileData map[string]interface{}) (string, error) {
  177. return client.ExecuteWithSession(method, data, fileData, "")
  178. }