This commit is contained in:
Ashang
2022-04-04 16:01:36 +08:00
commit 20c576b9bc
72 changed files with 4680 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
package constant
var Errno = map[int]string{
400: "系统错误",
401: "签名认证错误",
10001: "钱包地址已存在,请勿重复添加",
10002: "支付交易已存在,请勿重复创建",
10003: "无可用钱包地址,无法发起支付",
10004: "支付金额有误, 无法满足最小支付单位",
10005: "无可用金额通道",
10006: "汇率计算错误",
10007: "订单区块已处理",
10008: "订单不存在",
10009: "无法解析请求参数",
}
var (
SystemErr = Err(400)
SignatureErr = Err(401)
WalletAddressAlreadyExists = Err(10001)
OrderAlreadyExists = Err(10002)
NotAvailableWalletAddress = Err(10003)
PayAmountErr = Err(10004)
NotAvailableAmountErr = Err(10005)
RateAmountErr = Err(10006)
OrderBlockAlreadyProcess = Err(10007)
OrderNotExists = Err(10008)
ParamsMarshalErr = Err(10009)
)
type RspError struct {
Code int
Msg string
}
func (re *RspError) Error() string {
return re.Msg
}
func Err(code int) (err error) {
err = &RspError{
Code: code,
Msg: Errno[code],
}
return err
}
func (re *RspError) Render() (code int, msg string) {
return re.Code, re.Msg
}
+73
View File
@@ -0,0 +1,73 @@
package http
import (
"github.com/assimon/luuu/util/constant"
"github.com/assimon/luuu/util/page"
"github.com/labstack/echo/v4"
"net/http"
)
type Resp struct{}
type Response struct {
StatusCode int `json:"status_code"`
Message string `json:"message"`
Data interface{} `json:"data"`
RequestID string `json:"request_id"`
}
func (r *Resp) View(e echo.Context, code int, html string) error {
return e.HTML(code, html)
}
// SucView 成功返回
func (r *Resp) SucView(e echo.Context, html string) error {
return r.View(e, http.StatusOK, html)
}
func (r *Resp) Json(e echo.Context, code int, data interface{}) error {
return e.JSON(code, data)
}
// SucJson 成功返回json
func (r *Resp) SucJson(e echo.Context, data interface{}, message ...string) error {
rp := new(Response)
rp.StatusCode = http.StatusOK
if len(message) == 0 {
rp.Message = "success"
} else {
for _, m := range message {
rp.Message += "," + m
}
}
rp.Data = data
rp.RequestID = e.Request().Header.Get(echo.HeaderXRequestID)
return r.Json(e, http.StatusOK, rp)
}
// SucJsonPage 分页封装返回json
func (r *Resp) SucJsonPage(e echo.Context, data interface{}, pagination page.Pagination, message ...string) error {
type PageData struct {
List interface{} `json:"list"`
Pagination page.Pagination `json:"pagination"`
}
pageDate := PageData{
List: data,
Pagination: pagination,
}
return r.SucJson(e, pageDate, message...)
}
// FailJson 失败json
func (r *Resp) FailJson(e echo.Context, err error) error {
rr := new(Response)
switch err.(type) {
case *constant.RspError:
rr.StatusCode, rr.Message = err.(*constant.RspError).Render()
default:
rr.StatusCode = 400
rr.Message = err.Error()
}
rr.RequestID = e.Request().Header.Get(echo.HeaderXRequestID)
return r.Json(e, http.StatusOK, &rr)
}
+18
View File
@@ -0,0 +1,18 @@
package http_client
import (
"github.com/go-resty/resty/v2"
"time"
)
// GetHttpClient 获取请求客户端
func GetHttpClient(proxys ...string) *resty.Client {
client := resty.New()
// 如果有代理
if len(proxys) > 0 {
proxy := proxys[0]
client.SetProxy(proxy)
}
client.SetTimeout(time.Second * 5)
return client
}
+5
View File
@@ -0,0 +1,5 @@
package json
import jsoniter "github.com/json-iterator/go"
var Cjson = jsoniter.ConfigCompatibleWithStandardLibrary
+42
View File
@@ -0,0 +1,42 @@
package log
import (
"fmt"
"github.com/assimon/luuu/config"
"github.com/natefinch/lumberjack"
"github.com/spf13/viper"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
"time"
)
var Sugar *zap.SugaredLogger
func Init() {
writeSyncer := getLogWriter()
encoder := getEncoder()
core := zapcore.NewCore(encoder, writeSyncer, zapcore.DebugLevel)
logger := zap.New(core, zap.AddCaller())
Sugar = logger.Sugar()
}
func getEncoder() zapcore.Encoder {
encoderConfig := zap.NewProductionEncoderConfig()
encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder
encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder
return zapcore.NewJSONEncoder(encoderConfig)
}
func getLogWriter() zapcore.WriteSyncer {
file := fmt.Sprintf("%s/log_%s.log",
config.LogSavePath,
time.Now().Format("20060102"))
lumberJackLogger := &lumberjack.Logger{
Filename: file,
MaxSize: viper.GetInt("log_max_size"),
MaxBackups: viper.GetInt("max_backups"),
MaxAge: viper.GetInt("log_max_age"),
Compress: false,
}
return zapcore.AddSync(lumberJackLogger)
}
+25
View File
@@ -0,0 +1,25 @@
package page
import "math"
const (
DefaultPageSize = 10
MaxPageSize = 100
DefaultPage = 1
)
type Pagination struct {
CurrentPage int `json:"current_page"` // 当前页码
PerPage int `json:"per_page"` // 当前页行数
TotalPage int `json:"total_page"` // 总页码
Total int64 `json:"total"` // 总行数
}
func GetPagination(page, pageSize int, total int64) Pagination {
return Pagination{
Total: total,
CurrentPage: page,
PerPage: pageSize,
TotalPage: int(math.Ceil(float64(total) / float64(pageSize))),
}
}
+117
View File
@@ -0,0 +1,117 @@
package sign
import (
"errors"
"github.com/assimon/luuu/util/json"
"github.com/gookit/goutil/strutil"
"reflect"
"sort"
"strconv"
)
// Get 获取签名
func Get(data interface{}, bizKey string) (string, error) {
var err error
signStr := ""
switch v := reflect.ValueOf(data); v.Kind() {
case reflect.Map:
signStr, err = MapToParams(data.(map[string]interface{}))
if err != nil {
return "", err
}
case reflect.Struct:
signStr, err = Struct2map(v.Interface())
if err != nil {
return "", err
}
default:
return "", errors.New("type err")
}
sign := strutil.Md5(signStr + bizKey)
return sign, nil
}
func Struct2map(content interface{}) (string, error) {
var params map[string]interface{}
marshal, err := json.Cjson.Marshal(content)
if err != nil {
return "", err
}
if err = json.Cjson.Unmarshal(marshal, &params); err != nil {
return "", err
}
paramsUrl, err := MapToParams(params)
return paramsUrl, err
}
func MapToParams(params map[string]interface{}) (string, error) {
var tempArr []string
temString := ""
for k, v := range params {
if k == "signature" {
continue
}
if v == nil {
continue
}
fv := ""
switch v.(type) {
case float64:
ft := v.(float64)
fv = strconv.FormatFloat(ft, 'f', -1, 64)
case float32:
ft := v.(float32)
fv = strconv.FormatFloat(float64(ft), 'f', -1, 64)
case int:
it := v.(int)
fv = strconv.Itoa(it)
case uint:
it := v.(uint)
fv = strconv.Itoa(int(it))
case int8:
it := v.(int8)
fv = strconv.Itoa(int(it))
case uint8:
it := v.(uint8)
fv = strconv.Itoa(int(it))
case int16:
it := v.(int16)
fv = strconv.Itoa(int(it))
case uint16:
it := v.(uint16)
fv = strconv.Itoa(int(it))
case int32:
it := v.(int32)
fv = strconv.Itoa(int(it))
case uint32:
it := v.(uint32)
fv = strconv.Itoa(int(it))
case int64:
it := v.(int64)
fv = strconv.FormatInt(it, 10)
case uint64:
it := v.(uint64)
fv = strconv.FormatUint(it, 10)
case string:
fv = v.(string)
case []byte:
fv = string(v.([]byte))
default:
return "", errors.New("signature marshal error")
}
// 空值不参与签名
if fv == "" {
continue
}
tempArr = append(tempArr, k+"="+fv)
}
sort.Strings(tempArr)
for n, v := range tempArr {
if n+1 < len(tempArr) {
temString = temString + v + "&"
} else {
temString = temString + v
}
}
return temString, nil
}