✨ 初始化项目
This commit is contained in:
146
internal/core/client.go
Normal file
146
internal/core/client.go
Normal file
@@ -0,0 +1,146 @@
|
||||
/**
|
||||
* @Author: Echo
|
||||
* @Email:1711788888@qq.com
|
||||
* @Date: 2021/8/27 11:31 上午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"git.echol.cn/loser/http"
|
||||
|
||||
"git.echol.cn/loser/tencent-im/internal/enum"
|
||||
"git.echol.cn/loser/tencent-im/internal/sign"
|
||||
"git.echol.cn/loser/tencent-im/internal/types"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBaseUrl = "https://console.tim.qq.com"
|
||||
defaultVersion = "v4"
|
||||
defaultContentType = "json"
|
||||
defaultExpiration = 3600
|
||||
)
|
||||
|
||||
var invalidResponse = NewError(enum.InvalidResponseCode, "invalid response")
|
||||
|
||||
type Client interface {
|
||||
// Get GET请求
|
||||
Get(serviceName string, command string, data interface{}, resp interface{}) error
|
||||
// Post POST请求
|
||||
Post(serviceName string, command string, data interface{}, resp interface{}) error
|
||||
// Put PUT请求
|
||||
Put(serviceName string, command string, data interface{}, resp interface{}) error
|
||||
// Patch PATCH请求
|
||||
Patch(serviceName string, command string, data interface{}, resp interface{}) error
|
||||
// Delete DELETE请求
|
||||
Delete(serviceName string, command string, data interface{}, resp interface{}) error
|
||||
}
|
||||
|
||||
type client struct {
|
||||
client *http.Client
|
||||
opt *Options
|
||||
userSig string
|
||||
userSigExpireAt int64
|
||||
}
|
||||
|
||||
type Options struct {
|
||||
AppId int // 应用SDKAppID,可在即时通信 IM 控制台 的应用卡片中获取。
|
||||
AppSecret string // 密钥信息,可在即时通信 IM 控制台 的应用详情页面中获取,具体操作请参见 获取密钥
|
||||
UserId string // 用户ID
|
||||
Expiration int // UserSig过期时间
|
||||
}
|
||||
|
||||
func NewClient(opt *Options) Client {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
c := new(client)
|
||||
c.opt = opt
|
||||
c.client = http.NewClient()
|
||||
c.client.SetContentType(http.ContentTypeJson)
|
||||
c.client.SetBaseUrl(defaultBaseUrl)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// Get GET请求
|
||||
func (c *client) Get(serviceName string, command string, data interface{}, resp interface{}) error {
|
||||
return c.request(http.MethodGet, serviceName, command, data, resp)
|
||||
}
|
||||
|
||||
// Post POST请求
|
||||
func (c *client) Post(serviceName string, command string, data interface{}, resp interface{}) error {
|
||||
return c.request(http.MethodPost, serviceName, command, data, resp)
|
||||
}
|
||||
|
||||
// Put PUT请求
|
||||
func (c *client) Put(serviceName string, command string, data interface{}, resp interface{}) error {
|
||||
return c.request(http.MethodPut, serviceName, command, data, resp)
|
||||
}
|
||||
|
||||
// Patch PATCH请求
|
||||
func (c *client) Patch(serviceName string, command string, data interface{}, resp interface{}) error {
|
||||
return c.request(http.MethodPatch, serviceName, command, data, resp)
|
||||
}
|
||||
|
||||
// Delete DELETE请求
|
||||
func (c *client) Delete(serviceName string, command string, data interface{}, resp interface{}) error {
|
||||
return c.request(http.MethodDelete, serviceName, command, data, resp)
|
||||
}
|
||||
|
||||
// request Request请求
|
||||
func (c *client) request(method, serviceName, command string, data, resp interface{}) error {
|
||||
res, err := c.client.Request(method, c.buildUrl(serviceName, command), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = res.Scan(resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if r, ok := resp.(types.ActionBaseRespInterface); ok {
|
||||
if r.GetActionStatus() == enum.FailActionStatus {
|
||||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||||
}
|
||||
|
||||
if r.GetErrorCode() != enum.SuccessCode {
|
||||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||||
}
|
||||
} else if r, ok := resp.(types.BaseRespInterface); ok {
|
||||
if r.GetErrorCode() != enum.SuccessCode {
|
||||
return NewError(r.GetErrorCode(), r.GetErrorInfo())
|
||||
}
|
||||
} else {
|
||||
return invalidResponse
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildUrl 构建一个请求URL
|
||||
func (c *client) buildUrl(serviceName string, command string) string {
|
||||
format := "/%s/%s/%s?sdkappid=%d&identifier=%s&usersig=%s&random=%d&contenttype=%s"
|
||||
random := rand.Int31()
|
||||
userSig := c.getUserSig()
|
||||
return fmt.Sprintf(format, defaultVersion, serviceName, command, c.opt.AppId, c.opt.UserId, userSig, random, defaultContentType)
|
||||
}
|
||||
|
||||
// getUserSig 获取签名
|
||||
func (c *client) getUserSig() string {
|
||||
now, expiration := time.Now(), c.opt.Expiration
|
||||
|
||||
if expiration <= 0 {
|
||||
expiration = defaultExpiration
|
||||
}
|
||||
|
||||
if c.userSig == "" || c.userSigExpireAt <= now.Unix() {
|
||||
c.userSig, _ = sign.GenUserSig(c.opt.AppId, c.opt.AppSecret, c.opt.UserId, expiration)
|
||||
c.userSigExpireAt = now.Add(time.Duration(expiration) * time.Second).Unix()
|
||||
}
|
||||
|
||||
return c.userSig
|
||||
}
|
38
internal/core/error.go
Normal file
38
internal/core/error.go
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @Author: Echo
|
||||
* @Email:1711788888@qq.com
|
||||
* @Date: 2021/8/27 1:12 下午
|
||||
* @Desc: TODO
|
||||
*/
|
||||
|
||||
package core
|
||||
|
||||
type Error interface {
|
||||
error
|
||||
Code() int
|
||||
Message() string
|
||||
}
|
||||
|
||||
type respError struct {
|
||||
code int
|
||||
message string
|
||||
}
|
||||
|
||||
func NewError(code int, message string) Error {
|
||||
return &respError{
|
||||
code: code,
|
||||
message: message,
|
||||
}
|
||||
}
|
||||
|
||||
func (e *respError) Error() string {
|
||||
return e.message
|
||||
}
|
||||
|
||||
func (e *respError) Code() int {
|
||||
return e.code
|
||||
}
|
||||
|
||||
func (e *respError) Message() string {
|
||||
return e.message
|
||||
}
|
Reference in New Issue
Block a user