code cleanup
This commit is contained in:
		@ -1,125 +0,0 @@
 | 
				
			|||||||
// Package httpclient 基础请求库
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author: go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Description: 基础常量定义
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// File: define.go
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Version: 1.0.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 19:56:48
 | 
					 | 
				
			||||||
package httpclient
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"git.zhangdeman.cn/zhangdeman/exception"
 | 
					 | 
				
			||||||
	"github.com/ddliu/go-httpclient"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// ContentTypeFormData form-data 请求
 | 
					 | 
				
			||||||
	ContentTypeFormData = "form-data"
 | 
					 | 
				
			||||||
	// ContentTypeFormURLEncoded x-www-form-urlencoded 请求
 | 
					 | 
				
			||||||
	ContentTypeFormURLEncoded = "application/x-www-form-urlencoded"
 | 
					 | 
				
			||||||
	// ContentTypeJSON json的请求方式
 | 
					 | 
				
			||||||
	ContentTypeJSON = "application/json"
 | 
					 | 
				
			||||||
	// ContentTypeDefault 默认的请求方式
 | 
					 | 
				
			||||||
	ContentTypeDefault = ContentTypeJSON
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// BodyTypeJson json数据
 | 
					 | 
				
			||||||
	BodyTypeJson = "json"
 | 
					 | 
				
			||||||
	// BodyTypeXML xml数据
 | 
					 | 
				
			||||||
	BodyTypeXML = "xml"
 | 
					 | 
				
			||||||
	// BodyTypeYaml yaml数据
 | 
					 | 
				
			||||||
	BodyTypeYaml = "yaml"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// DefaultConnectTimeout 默认连接超时时间, 毫秒
 | 
					 | 
				
			||||||
	DefaultConnectTimeout = 1000
 | 
					 | 
				
			||||||
	// DefaultReadTimeout 默认读取超时时间, 毫秒
 | 
					 | 
				
			||||||
	DefaultReadTimeout = 1000
 | 
					 | 
				
			||||||
	// DefaultResponseCodeField 默认code字段
 | 
					 | 
				
			||||||
	DefaultResponseCodeField = "code"
 | 
					 | 
				
			||||||
	// DefaultResponseMessageField 默认message字段
 | 
					 | 
				
			||||||
	DefaultResponseMessageField = "message"
 | 
					 | 
				
			||||||
	// DefaultResponseDataField 默认数据字段
 | 
					 | 
				
			||||||
	DefaultResponseDataField = "data"
 | 
					 | 
				
			||||||
	// DefaultFailMessage 接口响应失败
 | 
					 | 
				
			||||||
	DefaultFailMessage = "api request fail"
 | 
					 | 
				
			||||||
	// DefaultSuccessMessage 接口响应成功
 | 
					 | 
				
			||||||
	DefaultSuccessMessage = "api request success"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
var (
 | 
					 | 
				
			||||||
	// DefaultSuccessCode 默认成功状态码
 | 
					 | 
				
			||||||
	DefaultSuccessCode = []string{"0", "200"}
 | 
					 | 
				
			||||||
	// DefaultSuccessHttpCode 默认成功http状态码
 | 
					 | 
				
			||||||
	DefaultSuccessHttpCode = []string{"200"}
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// ResponseCodeFieldLocationBody 响应状态码在body
 | 
					 | 
				
			||||||
	ResponseCodeFieldLocationBody = "body"
 | 
					 | 
				
			||||||
	// ResponseCodeFieldLocationHeader 在header
 | 
					 | 
				
			||||||
	ResponseCodeFieldLocationHeader = "header"
 | 
					 | 
				
			||||||
	// ResponseCodeFieldLocationDefault 响应状态码位置默认值
 | 
					 | 
				
			||||||
	ResponseCodeFieldLocationDefault = ResponseCodeFieldLocationBody
 | 
					 | 
				
			||||||
	// ResponseBodyAsData 会用整体的body作为数据
 | 
					 | 
				
			||||||
	ResponseBodyAsData = "__response__body__"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ApiRequestConfig api请求的配置
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Description:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 20:14:18
 | 
					 | 
				
			||||||
type ApiRequestConfig struct {
 | 
					 | 
				
			||||||
	Method                    string                 `json:"method"`                       // 请求方法
 | 
					 | 
				
			||||||
	Domain                    string                 `json:"domain"`                       // 请求域名
 | 
					 | 
				
			||||||
	URI                       string                 `json:"uri"`                          // 请求的路由
 | 
					 | 
				
			||||||
	ResponseCodeField         string                 `json:"response_code_field"`          // 业务状态码字段
 | 
					 | 
				
			||||||
	ResponseCodeFieldLocation string                 `json:"response_code_field_location"` // 响应的业务状态码位置, 默认 : body . 可配置 body / header
 | 
					 | 
				
			||||||
	ResponseMessageField      string                 `json:"response_message_field"`       // 业务状态码描述的字段
 | 
					 | 
				
			||||||
	ResponseDataField         string                 `json:"response_data_field"`          // 业务数据的字段
 | 
					 | 
				
			||||||
	SuccessCodeList           []string               `json:"success_code_list"`            // 代表请求成功的code列表
 | 
					 | 
				
			||||||
	SuccessHttpCodeList       []string               `json:"success_http_code_list"`       // 代表成功的http code列表
 | 
					 | 
				
			||||||
	Parameter                 map[string]interface{} `json:"parameter"`                    // 传入的请求参数
 | 
					 | 
				
			||||||
	CommonHeader              map[string]string      `json:"common_header"`                // 全部请求都要传的header
 | 
					 | 
				
			||||||
	Body                      []byte                 `json:"-"`                            // 请求体
 | 
					 | 
				
			||||||
	FullURL                   string                 `json:"full_url"`                     // 完整请求地址
 | 
					 | 
				
			||||||
	Timeout                   Timeout                `json:"timeout"`                      // 超时配置
 | 
					 | 
				
			||||||
	ContentType               string                 `json:"content_type"`                 // 请求方法
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Timeout 超时配置
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 15:02 2022/5/2
 | 
					 | 
				
			||||||
type Timeout struct {
 | 
					 | 
				
			||||||
	Connect int `json:"connect"` // 连接超时
 | 
					 | 
				
			||||||
	Read    int `json:"read"`    // 读取超时时间
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// ApiResponse 接口响应结果
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Description:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 20:25:39
 | 
					 | 
				
			||||||
type ApiResponse struct {
 | 
					 | 
				
			||||||
	RequestConfig     *ApiRequestConfig    `json:"request_config"`      // 请求配置
 | 
					 | 
				
			||||||
	Response          *httpclient.Response `json:"response"`            // 响应体
 | 
					 | 
				
			||||||
	Exception         exception.IException `json:"-"`                   // 异常信息
 | 
					 | 
				
			||||||
	StartRequestTime  int64                `json:"start_request_time"`  // 开始请求时间, 纳秒
 | 
					 | 
				
			||||||
	FinishRequestTime int64                `json:"finish_request_time"` // 完成请求时间,纳秒
 | 
					 | 
				
			||||||
	Code              string               `json:"code"`                // 业务状态码
 | 
					 | 
				
			||||||
	Message           string               `json:"message"`             // 状态码描述
 | 
					 | 
				
			||||||
	Data              string               `json:"data"`                // 响应数据
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@ -1,27 +0,0 @@
 | 
				
			|||||||
// Package httpclient ...
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author: go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Description: 定义异常
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// File: exception.go
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Version: 1.0.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 20:40:08
 | 
					 | 
				
			||||||
package httpclient
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const (
 | 
					 | 
				
			||||||
	// ResponseCodeNotFound 响应结果获取不到状态码字段
 | 
					 | 
				
			||||||
	ResponseCodeNotFound = 404000000002
 | 
					 | 
				
			||||||
	// ResponseDataNotFound 响应结果获取不到数据字段
 | 
					 | 
				
			||||||
	ResponseDataNotFound = 404000000004
 | 
					 | 
				
			||||||
	// SendRequestError 请求发送出现异常
 | 
					 | 
				
			||||||
	SendRequestError = 400000000002
 | 
					 | 
				
			||||||
	// ReadResponseBodyError 读取响应数据体出现异常
 | 
					 | 
				
			||||||
	ReadResponseBodyError = 400000000003
 | 
					 | 
				
			||||||
	// RequestMethodNotSupport 请求方法不支持
 | 
					 | 
				
			||||||
	RequestMethodNotSupport = 405000000001
 | 
					 | 
				
			||||||
	// ResponseHttpCodeIsNotSuccess 响应的http状态码非成功
 | 
					 | 
				
			||||||
	ResponseHttpCodeIsNotSuccess = 500000000001
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
@ -1,350 +0,0 @@
 | 
				
			|||||||
// Package httpclient ...
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author: go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Description:
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// File: request.go
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Version: 1.0.0
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 21:25:03
 | 
					 | 
				
			||||||
package httpclient
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import (
 | 
					 | 
				
			||||||
	"bytes"
 | 
					 | 
				
			||||||
	"encoding/json"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"net/http"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
	"time"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"git.zhangdeman.cn/zhangdeman/exception"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/tidwall/gjson"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/ddliu/go-httpclient"
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Request 发送请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:26:02
 | 
					 | 
				
			||||||
func Request(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = strings.ToUpper(apiConfig.Method)
 | 
					 | 
				
			||||||
	switch apiConfig.Method {
 | 
					 | 
				
			||||||
	case http.MethodGet:
 | 
					 | 
				
			||||||
		return GET(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodPost:
 | 
					 | 
				
			||||||
		return POST(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodPut:
 | 
					 | 
				
			||||||
		return PUT(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodDelete:
 | 
					 | 
				
			||||||
		return DELETE(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodConnect:
 | 
					 | 
				
			||||||
		return Connect(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodOptions:
 | 
					 | 
				
			||||||
		return OPTION(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodTrace:
 | 
					 | 
				
			||||||
		return Trace(apiConfig, header, param)
 | 
					 | 
				
			||||||
	case http.MethodPatch:
 | 
					 | 
				
			||||||
		return Patch(apiConfig, header, param)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return &ApiResponse{
 | 
					 | 
				
			||||||
			RequestConfig:     apiConfig,
 | 
					 | 
				
			||||||
			Exception:         exception.New(RequestMethodNotSupport, 0, map[string]string{"method": apiConfig.Method}, apiConfig.Method+" : request method is not support"),
 | 
					 | 
				
			||||||
			Response:          nil,
 | 
					 | 
				
			||||||
			StartRequestTime:  time.Now().UnixNano(),
 | 
					 | 
				
			||||||
			FinishRequestTime: time.Now().UnixNano(),
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// GET ...
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date: 2022/05/01 21:29:09
 | 
					 | 
				
			||||||
func GET(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodGet
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// POST post请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:31:36
 | 
					 | 
				
			||||||
func POST(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodPost
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// PUT put请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:31:52
 | 
					 | 
				
			||||||
func PUT(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodPut
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// DELETE delete请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:32:08
 | 
					 | 
				
			||||||
func DELETE(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodDelete
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// OPTION option请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:32:18
 | 
					 | 
				
			||||||
func OPTION(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodOptions
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Patch patch请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:36:12
 | 
					 | 
				
			||||||
func Patch(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodPatch
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Trace trace请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:36:24
 | 
					 | 
				
			||||||
func Trace(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodTrace
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Connect connect请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 2022/05/01 21:36:39
 | 
					 | 
				
			||||||
func Connect(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) *ApiResponse {
 | 
					 | 
				
			||||||
	apiConfig.Method = http.MethodConnect
 | 
					 | 
				
			||||||
	buildRequestURLAndParam(apiConfig, header, param)
 | 
					 | 
				
			||||||
	return send(apiConfig, header)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// getHttpClient 获取httpclient实例
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 22:27 2022/5/1
 | 
					 | 
				
			||||||
func getHttpClient(apiConfig *ApiRequestConfig, header map[string]string) *httpclient.HttpClient {
 | 
					 | 
				
			||||||
	fullHeader := make(map[string]string)
 | 
					 | 
				
			||||||
	for name, val := range apiConfig.CommonHeader {
 | 
					 | 
				
			||||||
		fullHeader[name] = val
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for name, val := range header {
 | 
					 | 
				
			||||||
		fullHeader[name] = val
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.ContentType) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.ContentType = ContentTypeDefault
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	fullHeader["content-type"] = apiConfig.ContentType
 | 
					 | 
				
			||||||
	return httpclient.NewHttpClient().WithHeaders(fullHeader).
 | 
					 | 
				
			||||||
		WithOption(httpclient.OPT_CONNECTTIMEOUT_MS, apiConfig.Timeout.Connect).
 | 
					 | 
				
			||||||
		WithOption(httpclient.OPT_TIMEOUT_MS, apiConfig.Timeout.Read)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// buildRequestURLAndParam 构建完整请求URL与请求参数
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 21:55 2022/5/1
 | 
					 | 
				
			||||||
func buildRequestURLAndParam(apiConfig *ApiRequestConfig, header map[string]string, param map[string]interface{}) {
 | 
					 | 
				
			||||||
	apiConfig.Method = strings.ToUpper(apiConfig.Method)
 | 
					 | 
				
			||||||
	if apiConfig.Timeout.Connect == 0 {
 | 
					 | 
				
			||||||
		apiConfig.Timeout.Connect = DefaultConnectTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if apiConfig.Timeout.Read == 0 {
 | 
					 | 
				
			||||||
		apiConfig.Timeout.Read = DefaultConnectTimeout
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	formatParam := make(map[string]interface{})
 | 
					 | 
				
			||||||
	for paramName, paramValue := range param {
 | 
					 | 
				
			||||||
		uriTemplate := "{" + paramName + "}"
 | 
					 | 
				
			||||||
		if strings.Contains(apiConfig.URI, uriTemplate) {
 | 
					 | 
				
			||||||
			apiConfig.URI = strings.ReplaceAll(apiConfig.URI, uriTemplate, fmt.Sprintf("%v", paramValue))
 | 
					 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		formatParam[paramName] = paramValue
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	apiConfig.Parameter = formatParam
 | 
					 | 
				
			||||||
	paramPair := make([]string, 0)
 | 
					 | 
				
			||||||
	switch apiConfig.Method {
 | 
					 | 
				
			||||||
	case http.MethodPost:
 | 
					 | 
				
			||||||
		apiConfig.Body, _ = json.Marshal(formatParam)
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		for paramName, paramValue := range formatParam {
 | 
					 | 
				
			||||||
			paramPair = append(paramPair, fmt.Sprintf("%v=%v", paramName, paramValue))
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if len(paramPair) > 0 {
 | 
					 | 
				
			||||||
			apiConfig.URI = apiConfig.URI + "?" + strings.Join(paramPair, "&")
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if strings.HasSuffix(apiConfig.Domain, "/") {
 | 
					 | 
				
			||||||
		apiConfig.Domain = strings.TrimRight(apiConfig.Domain, "/")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !strings.HasPrefix(apiConfig.URI, "/") {
 | 
					 | 
				
			||||||
		apiConfig.URI = "/" + apiConfig.URI
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	apiConfig.FullURL = apiConfig.Domain + apiConfig.URI
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// send 发送请求
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Author : go_developer@163.com<白茶清欢>
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
// Date : 14:53 2022/5/2
 | 
					 | 
				
			||||||
func send(apiConfig *ApiRequestConfig, header map[string]string) *ApiResponse {
 | 
					 | 
				
			||||||
	var (
 | 
					 | 
				
			||||||
		client       *httpclient.HttpClient
 | 
					 | 
				
			||||||
		err          error
 | 
					 | 
				
			||||||
		responseByte []byte
 | 
					 | 
				
			||||||
	)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 填充默认配置
 | 
					 | 
				
			||||||
	if len(apiConfig.ResponseCodeFieldLocation) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.ResponseCodeFieldLocation = ResponseCodeFieldLocationDefault
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.ResponseCodeField) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.ResponseCodeField = DefaultResponseCodeField
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.ResponseMessageField) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.ResponseMessageField = DefaultResponseMessageField
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.ResponseDataField) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.ResponseDataField = DefaultResponseDataField
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.SuccessCodeList) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.SuccessCodeList = DefaultSuccessCode
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if len(apiConfig.SuccessHttpCodeList) == 0 {
 | 
					 | 
				
			||||||
		apiConfig.SuccessHttpCodeList = DefaultSuccessHttpCode
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	response := &ApiResponse{
 | 
					 | 
				
			||||||
		RequestConfig:     apiConfig,
 | 
					 | 
				
			||||||
		Response:          nil,
 | 
					 | 
				
			||||||
		Exception:         nil,
 | 
					 | 
				
			||||||
		StartRequestTime:  time.Now().UnixNano(),
 | 
					 | 
				
			||||||
		FinishRequestTime: 0,
 | 
					 | 
				
			||||||
		Code:              "",
 | 
					 | 
				
			||||||
		Message:           "",
 | 
					 | 
				
			||||||
		Data:              "",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	defer func() {
 | 
					 | 
				
			||||||
		response.FinishRequestTime = time.Now().UnixNano()
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	client = getHttpClient(apiConfig, header)
 | 
					 | 
				
			||||||
	if response.Response, err = client.Do(apiConfig.Method, apiConfig.FullURL, nil, bytes.NewReader(apiConfig.Body)); nil != err {
 | 
					 | 
				
			||||||
		response.Exception = exception.New(SendRequestError, 0, map[string]string{"real_reason": err.Error()}, "http request send fail : "+err.Error())
 | 
					 | 
				
			||||||
		return response
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if responseByte, err = io.ReadAll(response.Response.Body); nil != err {
 | 
					 | 
				
			||||||
		response.Exception = exception.New(ReadResponseBodyError, response.Response.StatusCode, map[string]string{"real_reason": err.Error()}, "response body read fail : "+err.Error())
 | 
					 | 
				
			||||||
		return response
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// 判断http状态码是否为成功
 | 
					 | 
				
			||||||
	isHttpSuccess := false
 | 
					 | 
				
			||||||
	responseHttpCode := fmt.Sprintf("%v", response.Response.StatusCode)
 | 
					 | 
				
			||||||
	for _, itemSuccessHttpCode := range response.RequestConfig.SuccessHttpCodeList {
 | 
					 | 
				
			||||||
		if responseHttpCode == itemSuccessHttpCode {
 | 
					 | 
				
			||||||
			isHttpSuccess = true
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// http请求失败
 | 
					 | 
				
			||||||
	if !isHttpSuccess {
 | 
					 | 
				
			||||||
		response.Exception = exception.New(ResponseHttpCodeIsNotSuccess, response.Response.StatusCode, map[string]string{
 | 
					 | 
				
			||||||
			"real_reason": responseHttpCode + " : response http code is not success",
 | 
					 | 
				
			||||||
		}, responseHttpCode+" : response http code is not success")
 | 
					 | 
				
			||||||
		return response
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// 提取响应错误码
 | 
					 | 
				
			||||||
	if response.RequestConfig.ResponseCodeFieldLocation == ResponseCodeFieldLocationHeader {
 | 
					 | 
				
			||||||
		if strings.ToLower(response.RequestConfig.ResponseCodeField) == "http_code" {
 | 
					 | 
				
			||||||
			response.Code = responseHttpCode
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			response.Code = response.Response.Header.Get(response.RequestConfig.ResponseCodeField)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		businessCode := gjson.GetBytes(responseByte, response.RequestConfig.ResponseCodeField)
 | 
					 | 
				
			||||||
		if businessCode.Exists() {
 | 
					 | 
				
			||||||
			response.Code = businessCode.String()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 判断是否提取到响应状态码
 | 
					 | 
				
			||||||
	if len(response.Code) == 0 {
 | 
					 | 
				
			||||||
		response.Exception = exception.New(ResponseCodeNotFound, response.Response.StatusCode, map[string]string{
 | 
					 | 
				
			||||||
			"real_reason": "parse response business code fail",
 | 
					 | 
				
			||||||
		}, fmt.Sprintf("business code location : %v, business code name : %v, parse business code fail", response.RequestConfig.ResponseCodeFieldLocation, response.RequestConfig.ResponseCodeField))
 | 
					 | 
				
			||||||
		return response
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// 提取响应文案
 | 
					 | 
				
			||||||
	response.Message = gjson.GetBytes(responseByte, response.RequestConfig.ResponseMessageField).String()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 判断响应状态码是否成功
 | 
					 | 
				
			||||||
	isBusinessCodeSuccess := false
 | 
					 | 
				
			||||||
	for _, itemSuccessCode := range response.RequestConfig.SuccessCodeList {
 | 
					 | 
				
			||||||
		if itemSuccessCode == response.Code {
 | 
					 | 
				
			||||||
			isBusinessCodeSuccess = true
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if len(response.Message) == 0 {
 | 
					 | 
				
			||||||
		if isBusinessCodeSuccess {
 | 
					 | 
				
			||||||
			response.Message = DefaultSuccessMessage
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			response.Message = DefaultFailMessage
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if !isBusinessCodeSuccess {
 | 
					 | 
				
			||||||
		response.Exception = exception.New(ResponseCodeNotFound, response.Response.StatusCode, map[string]string{}, response.Message)
 | 
					 | 
				
			||||||
		return response
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// 提取响应数据
 | 
					 | 
				
			||||||
	if response.RequestConfig.ResponseDataField == ResponseBodyAsData {
 | 
					 | 
				
			||||||
		response.Data = string(responseByte)
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		responseData := gjson.GetBytes(responseByte, response.RequestConfig.ResponseDataField)
 | 
					 | 
				
			||||||
		if !responseData.Exists() {
 | 
					 | 
				
			||||||
			response.Exception = exception.New(ResponseDataNotFound, response.Response.StatusCode, map[string]string{}, "response data not found, data field name : "+response.RequestConfig.ResponseDataField)
 | 
					 | 
				
			||||||
			return response
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		response.Data = responseData.String()
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return response
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user