merge develop
This commit is contained in:
commit
b1cb50a6e3
1
.gitignore
vendored
1
.gitignore
vendored
@ -17,4 +17,5 @@
|
|||||||
# vendor/
|
# vendor/
|
||||||
.idea
|
.idea
|
||||||
.vscode
|
.vscode
|
||||||
|
*_test.go
|
||||||
|
|
||||||
|
3
go.mod
3
go.mod
@ -4,6 +4,7 @@ go 1.15
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/buger/jsonparser v1.1.1
|
github.com/buger/jsonparser v1.1.1
|
||||||
|
github.com/ddliu/go-httpclient v0.6.9
|
||||||
github.com/gin-gonic/gin v1.7.2
|
github.com/gin-gonic/gin v1.7.2
|
||||||
github.com/go-redis/redis/v8 v8.3.4
|
github.com/go-redis/redis/v8 v8.3.4
|
||||||
github.com/go-redis/redis_rate/v9 v9.1.1
|
github.com/go-redis/redis_rate/v9 v9.1.1
|
||||||
@ -16,6 +17,8 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/tidwall/gjson v1.8.1
|
github.com/tidwall/gjson v1.8.1
|
||||||
go.uber.org/zap v1.17.0
|
go.uber.org/zap v1.17.0
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/yaml.v2 v2.3.0
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
gorm.io/driver/mysql v1.0.0
|
gorm.io/driver/mysql v1.0.0
|
||||||
gorm.io/gorm v1.21.12
|
gorm.io/gorm v1.21.12
|
||||||
|
6
go.sum
6
go.sum
@ -5,6 +5,8 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
|||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/ddliu/go-httpclient v0.6.9 h1:/3hsBVpcgCJwqm1dkVlnAJ9NWuYInbRc+i9FyUXX/LE=
|
||||||
|
github.com/ddliu/go-httpclient v0.6.9/go.mod h1:zM9P0OxV4OGGz1pt/ibuj0ooX2SWH9a6MvXZLbT0JMc=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
@ -142,9 +144,13 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE
|
|||||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||||
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
|
||||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
126
mail/code_tpl.html
Normal file
126
mail/code_tpl.html
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<base target="_blank" />
|
||||||
|
<style type="text/css">
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style id="cloudAttachStyle" type="text/css">
|
||||||
|
#divNeteaseBigAttach,
|
||||||
|
#divNeteaseBigAttach_bak {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style id="blockquoteStyle" type="text/css">
|
||||||
|
blockquote {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
font-size: 14px;
|
||||||
|
font-family: arial, verdana, sans-serif;
|
||||||
|
line-height: 1.666;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
overflow: auto;
|
||||||
|
white-space: normal;
|
||||||
|
word-wrap: break-word;
|
||||||
|
min-height: 100px
|
||||||
|
}
|
||||||
|
|
||||||
|
td,
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
body {
|
||||||
|
font-family: Helvetica, 'Microsoft Yahei', verdana
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
white-space: -moz-pre-wrap;
|
||||||
|
white-space: -pre-wrap;
|
||||||
|
white-space: -o-pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
width: 95%
|
||||||
|
}
|
||||||
|
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
font-family: arial, verdana, sans-serif;
|
||||||
|
line-height: 1.666
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer,
|
||||||
|
section,
|
||||||
|
aside,
|
||||||
|
article,
|
||||||
|
nav,
|
||||||
|
hgroup,
|
||||||
|
figure,
|
||||||
|
figcaption {
|
||||||
|
display: block
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin-right: 0px
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body tabindex="0" role="listitem">
|
||||||
|
<table width="700" border="0" align="center" cellspacing="0" style="width:700px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<div style="width:700px;margin:0 auto;border-bottom:1px solid #ccc;margin-bottom:30px;">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="700" height="39"
|
||||||
|
style="font:12px Tahoma, Arial, 宋体;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td width="210"></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div style="width:680px;padding:0 10px;margin:0 auto;">
|
||||||
|
<div style="line-height:1.5;font-size:14px;margin-bottom:25px;color:#4d4d4d;">
|
||||||
|
<strong style="display:block;margin-bottom:15px;">尊敬的用户:<span
|
||||||
|
style="color:#f60;font-size: 16px;"></span>您好!</strong>
|
||||||
|
<strong style="display:block;margin-bottom:15px;">
|
||||||
|
您正在进行<span style="color: red">{operate_description}</span>操作,请在验证码输入框中输入:<span
|
||||||
|
style="color:#f60;font-size: 24px">{operate_code}</span>,以完成操作。
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div style="margin-bottom:30px;">
|
||||||
|
<small style="display:block;margin-bottom:20px;font-size:12px;">
|
||||||
|
<p style="color:#747474;">
|
||||||
|
注意:此操作可能会修改您的密码、登录邮箱或绑定手机。如非本人操作,请及时登录并修改密码以保证帐户安全
|
||||||
|
<br>(开发者不会向你索取此验证码,请勿泄漏!)
|
||||||
|
</p>
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="width:700px;margin:0 auto;">
|
||||||
|
<div
|
||||||
|
style="padding:10px 10px 0;border-top:1px solid #ccc;color:#747474;margin-bottom:20px;line-height:1.3em;font-size:12px;">
|
||||||
|
<p>此为系统邮件,请勿回复<br>
|
||||||
|
请保管好您的邮箱,避免账号被他人盗用
|
||||||
|
</p>
|
||||||
|
<p>白茶清欢的个人网站</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
91
mail/mail.go
Normal file
91
mail/mail.go
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// Package mail 邮件发送配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 1:14 上午 2021/8/13
|
||||||
|
package mail
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gopkg/util"
|
||||||
|
|
||||||
|
"gopkg.in/gomail.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Mail 邮件服务实例
|
||||||
|
Mail *mail
|
||||||
|
)
|
||||||
|
|
||||||
|
type mail struct {
|
||||||
|
conf map[string]string
|
||||||
|
port int
|
||||||
|
mailDialer *gomail.Dialer
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMailMessage 获取邮件消息实例
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 1:32 上午 2021/8/13
|
||||||
|
func NewMailMessage(fromMail string, fromMailName string, pass string, host string, port int) *mail {
|
||||||
|
if Mail == nil {
|
||||||
|
Mail = &mail{}
|
||||||
|
if len(fromMailName) == 0 {
|
||||||
|
fromMailName = "系统邮件"
|
||||||
|
}
|
||||||
|
Mail.conf = map[string]string{
|
||||||
|
"user": fromMail,
|
||||||
|
"pass": pass,
|
||||||
|
"host": host,
|
||||||
|
"port": fmt.Sprintf("%v", port),
|
||||||
|
"from_mail_name": fromMailName,
|
||||||
|
}
|
||||||
|
|
||||||
|
Mail.port = port
|
||||||
|
Mail.mailDialer = gomail.NewDialer(Mail.conf["host"], port, Mail.conf["user"], Mail.conf["pass"])
|
||||||
|
}
|
||||||
|
return Mail
|
||||||
|
}
|
||||||
|
|
||||||
|
// BaseSend 基础邮件发送
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 1:14 上午 2021/8/13
|
||||||
|
func (m *mail) BaseSend(mailTo []string, subject string, body string) error {
|
||||||
|
message := gomail.NewMessage()
|
||||||
|
message.SetHeader("From", message.FormatAddress(m.conf["user"], m.conf["from_mail_name"])) //这种方式可以添加别名,即“XX官方”
|
||||||
|
//说明:如果是用网易邮箱账号发送,以下方法别名可以是中文,如果是qq企业邮箱,以下方法用中文别名,会报错,需要用上面此方法转码
|
||||||
|
//m.SetHeader("From", "FB Sample"+"<"+mailConn["user"]+">") //这种方式可以添加别名,即“FB Sample”, 也可以直接用<code>m.SetHeader("From",mailConn["user"])</code> 读者可以自行实验下效果
|
||||||
|
//m.SetHeader("From", mailConn["user"])
|
||||||
|
message.SetHeader("To", mailTo...) //发送给多个用户
|
||||||
|
message.SetHeader("Subject", subject) //设置邮件主题
|
||||||
|
message.SetBody("text/html", body) //设置邮件正文
|
||||||
|
|
||||||
|
d := gomail.NewDialer(m.conf["host"], m.port, m.conf["user"], m.conf["pass"])
|
||||||
|
|
||||||
|
return d.DialAndSend(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TplSend 使用模版发送邮件
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 1:05 下午 2021/8/14
|
||||||
|
func (m *mail) TplSend(mailTo []string, subject string, tpl string, bindData map[string]string) error {
|
||||||
|
var (
|
||||||
|
tplContent []byte
|
||||||
|
err error
|
||||||
|
)
|
||||||
|
if tplContent, err = util.ReadFileContent(tpl); nil != err {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
mailBody := string(tplContent)
|
||||||
|
for k, v := range bindData {
|
||||||
|
mailBody = strings.ReplaceAll(mailBody, "{"+k+"}", v)
|
||||||
|
}
|
||||||
|
return m.BaseSend(mailTo, subject, mailBody)
|
||||||
|
}
|
127
request/curl.go
127
request/curl.go
@ -7,6 +7,131 @@
|
|||||||
// Date : 2021-08-01 8:47 下午
|
// Date : 2021-08-01 8:47 下午
|
||||||
package request
|
package request
|
||||||
|
|
||||||
func Send(apiMethod *APIMethod) {
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
|
||||||
|
"github.com/ddliu/go-httpclient"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Send 发送HTTP请求
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 9:38 下午 2021/8/11
|
||||||
|
func Send(apiMethod *APIMethod) *APIResponse {
|
||||||
|
if apiMethod.Parameter == nil {
|
||||||
|
apiMethod.Parameter = make(map[string]interface{})
|
||||||
|
}
|
||||||
|
if apiMethod.Header == nil {
|
||||||
|
apiMethod.Header = make(map[string]string)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// request 发送请求
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2:27 下午 2021/8/12
|
||||||
|
func request(apiMethod *APIMethod, responseConfig *ResponseConfig) (*APIResponse, bool) {
|
||||||
|
apiResponse := &APIResponse{
|
||||||
|
Code: "",
|
||||||
|
Message: "",
|
||||||
|
Data: "",
|
||||||
|
Success: false,
|
||||||
|
TraceID: "",
|
||||||
|
Cost: 0,
|
||||||
|
RealCost: 0,
|
||||||
|
TotalCost: 0,
|
||||||
|
TotalRealCost: 0,
|
||||||
|
ErrorList: make([]error, 0),
|
||||||
|
StartRequestTime: time.Now().Unix(),
|
||||||
|
FinishRequestTime: 0,
|
||||||
|
}
|
||||||
|
defer func(apiResponse *APIResponse) {
|
||||||
|
apiResponse.FinishRequestTime = time.Now().Unix()
|
||||||
|
apiResponse.RealCost = apiResponse.FinishRequestTime - apiResponse.StartRequestTime
|
||||||
|
}(apiResponse)
|
||||||
|
var (
|
||||||
|
client *httpclient.HttpClient
|
||||||
|
response *httpclient.Response
|
||||||
|
err error
|
||||||
|
responseData []byte
|
||||||
|
)
|
||||||
|
client = httpclient.NewHttpClient()
|
||||||
|
inputByteData, _ := json.Marshal(apiMethod.Parameter)
|
||||||
|
requestData := bytes.NewReader(inputByteData)
|
||||||
|
if response, err = client.Do(apiMethod.Method, apiMethod.ServiceDomain+apiMethod.URI, apiMethod.Header, requestData); nil != err {
|
||||||
|
apiResponse.Success = false
|
||||||
|
apiResponse.ErrorList = append(apiResponse.ErrorList, err)
|
||||||
|
return apiResponse, false
|
||||||
|
}
|
||||||
|
if responseData, err = ioutil.ReadAll(response.Body); nil != err {
|
||||||
|
apiResponse.Success = false
|
||||||
|
apiResponse.ErrorList = append(apiResponse.ErrorList, err)
|
||||||
|
return apiResponse, false
|
||||||
|
}
|
||||||
|
orgData := string(responseData)
|
||||||
|
apiResponse.Data = gjson.Get(orgData, responseConfig.DataKey).String()
|
||||||
|
apiResponse.Code = fmt.Sprintf("%v", gjson.Get(orgData, responseConfig.CodeKey).Value())
|
||||||
|
apiResponse.Message = gjson.Get(orgData, responseConfig.MessageKey).String()
|
||||||
|
apiResponse.Cost = gjson.Get(orgData, responseConfig.CostKey).Int()
|
||||||
|
apiResponse.Success = isSuccessCode(apiResponse.Code, responseConfig.SuccessCode)
|
||||||
|
|
||||||
|
if apiResponse.Success {
|
||||||
|
return apiResponse, false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非成功, 判断是否需要重试
|
||||||
|
return apiResponse, isNeedRetry(apiMethod, ResponseErrorTypeBusinessCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// isNeedRetry 是否需要重试
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 3:01 下午 2021/8/12
|
||||||
|
func isNeedRetry(apiMethod *APIMethod, errType string) bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// isSuccessCode 是否为业务处理成功状态码
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 3:43 下午 2021/8/13
|
||||||
|
func isSuccessCode(responseCode string, successResponseCodeList []string) bool {
|
||||||
|
isSuccess := false
|
||||||
|
for _, itemCode := range successResponseCodeList {
|
||||||
|
if responseCode == itemCode {
|
||||||
|
isSuccess = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isSuccess
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildResponseData 构建响应结果
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2:57 下午 2021/8/12
|
||||||
|
func buildResponseData(response *httpclient.Response) *APIResponse {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// buildRequestHeader 构建请求header
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 9:41 下午 2021/8/11
|
||||||
|
func buildRequestHeader(apiMethod *APIMethod) map[string]string {
|
||||||
|
header := make(map[string]string)
|
||||||
|
return header
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,12 @@ package request
|
|||||||
//
|
//
|
||||||
// Date : 8:29 下午 2021/8/1
|
// Date : 8:29 下午 2021/8/1
|
||||||
type APIMethod struct {
|
type APIMethod struct {
|
||||||
ServiceDomain string `json:"service_domain"` // 调用服务的域名
|
ServiceDomain string `json:"service_domain"` // 调用服务的域名
|
||||||
URI string `json:"uri"` // 调用的URI
|
URI string `json:"uri"` // 调用的URI
|
||||||
Method string `json:"method"` // 请求方法
|
Method string `json:"method"` // 请求方法
|
||||||
ISRestfulURI bool `json:"is_restful_uri"` // 是否为restful uri
|
ISRestfulURI bool `json:"is_restful_uri"` // 是否为restful uri
|
||||||
Header map[string]string `json:"header"` // 请求header
|
Header map[string]string `json:"header"` // 请求header
|
||||||
|
Parameter map[string]interface{} `json:"parameter"` // 请求参数
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResponseConfig ...
|
// ResponseConfig ...
|
||||||
@ -27,12 +27,18 @@ type APIMethod struct {
|
|||||||
//
|
//
|
||||||
// Date : 8:32 下午 2021/8/1
|
// Date : 8:32 下午 2021/8/1
|
||||||
type ResponseConfig struct {
|
type ResponseConfig struct {
|
||||||
ISJson bool `json:"is_json"` // 响应数据是否为json
|
RetryRule int `json:"retry_rule"` // 重试规则 0 - http error 1 - business error 2 - both 0 && 1
|
||||||
CodeKey string `json:"code_key"` // 代表业务Code的Key
|
RetryCnt int `json:"retry_cnt"` // 重试次数(重试次数 1, 最多请求两次)
|
||||||
MessageKey string `json:"message_key"` // 描述业务code的key
|
RetryInterval int `json:"retry_interval"` // 重试的时间间隔, 单位ms, 为 0 立即重试, > 0 休眠指定ms后重试
|
||||||
DataKey string `json:"data_key"` // 返回数据的key
|
ISJson bool `json:"is_json"` // 响应数据是否为json
|
||||||
SuccessRule string `json:"success_rule"` // 请求成功的规则, http_code / business_code http状态码或者业务状态码, 如果是通过http code 判断是否为请求成功 code key / message key 配置无效
|
CodeKey string `json:"code_key"` // 代表业务Code的Key
|
||||||
SuccessCode []string `json:"success_code"` // 哪些状态码被认为是请求成功
|
MessageKey string `json:"message_key"` // 描述业务code的key
|
||||||
|
TraceKey string `json:"trace_key"` // 接口返回的trace追踪字段key
|
||||||
|
DataKey string `json:"data_key"` // 返回数据的key
|
||||||
|
CostKey string `json:"cost_key"` // 代表接口耗时的key
|
||||||
|
SuccessRule string `json:"success_rule"` // 请求成功的规则, http_code / business_code http状态码或者业务状态码, 如果是通过http code 判断是否为请求成功 code key / message key 配置无效
|
||||||
|
SuccessCode []string `json:"success_code"` // 哪些状态码被认为是请求成功
|
||||||
|
SuccessHttpCode []string `json:"success_http_code"` // 被认为是成功的http code
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIResponse API响应数据
|
// APIResponse API响应数据
|
||||||
@ -41,8 +47,34 @@ type ResponseConfig struct {
|
|||||||
//
|
//
|
||||||
// Date : 8:54 下午 2021/8/1
|
// Date : 8:54 下午 2021/8/1
|
||||||
type APIResponse struct {
|
type APIResponse struct {
|
||||||
Data string `json:"data"` // 响应数据
|
Code string `json:"code"` // 响应状态码
|
||||||
Cost int64 `json:"cost"` // 接口耗时
|
Message string `json:"message"` // 响应状态码的描述
|
||||||
StartRequestTime int64 `json:"start_request_time"` // 开始请求时间
|
Data string `json:"data"` // 响应数据
|
||||||
FinishRequestTime int64 `json:"finish_request_time"` // 完成请求时间
|
Success bool `json:"success"` // 请求是否成功
|
||||||
|
TraceID string `json:"trace_id"` // 日志追踪traceID
|
||||||
|
Cost int64 `json:"cost"` // 接口耗时(第三方接口返回)
|
||||||
|
RealCost int64 `json:"real_cost"` // 内部从发起请求,到拿到结果的耗时
|
||||||
|
TotalCost int64 `json:"total_cost"` // 累计请求加一起耗时
|
||||||
|
TotalRealCost int64 `json:"total_real_cost"` // 累计真实耗时
|
||||||
|
ErrorList []error `json:"error_list"` // 重试过程中累计出现过的异常
|
||||||
|
StartRequestTime int64 `json:"start_request_time"` // 开始请求时间
|
||||||
|
FinishRequestTime int64 `json:"finish_request_time"` // 完成请求时间
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ResponseErrorTypeInternal 内部异常,请求没发出去
|
||||||
|
ResponseErrorTypeInternal = "internal"
|
||||||
|
// ResponseErrorTypeHttpStatus http 状态码异常
|
||||||
|
ResponseErrorTypeHttpStatus = "http"
|
||||||
|
// ResponseErrorTypeBusinessCode 业务状态码异常
|
||||||
|
ResponseErrorTypeBusinessCode = "business"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// RetryRuleOnlyHttpError 仅 http 异常重试
|
||||||
|
RetryRuleOnlyHttpError = 0
|
||||||
|
// RetryRuleOnlyBusinessError 仅业务状态码异常重试
|
||||||
|
RetryRuleOnlyBusinessError = 1
|
||||||
|
// RetryRuleMixed 任意一种异常出现,均重试
|
||||||
|
RetryRuleMixed = 2
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user