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.
694 lines
14 KiB
694 lines
14 KiB
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/gzip"
|
|
"encoding/json"
|
|
"fmt"
|
|
"github.com/shopspring/decimal"
|
|
"io"
|
|
"io/ioutil"
|
|
"matchmaking-system/internal/pkg/flags"
|
|
"matchmaking-system/internal/pkg/logging/applogger"
|
|
"math/rand"
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
)
|
|
|
|
// HttpGet
|
|
//
|
|
// @Description:
|
|
// @param url
|
|
// @return string
|
|
// @return error
|
|
func HttpGet(url string) (string, error) {
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
defer resp.Body.Close()
|
|
result, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
|
|
return string(result), err
|
|
}
|
|
|
|
// HttpGetDoKey
|
|
//
|
|
// @Description:
|
|
// @param url
|
|
// @return string
|
|
// @return error
|
|
func HttpGetDoKey(url string) (string, error) {
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
req.Header.Add("X-RapidAPI-Key", flags.SetNull)
|
|
req.Header.Add("X-RapidAPI-Host", flags.SetNull)
|
|
|
|
res, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
body, err := io.ReadAll(res.Body)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
|
|
return string(body), nil
|
|
}
|
|
|
|
// HttpGetApi
|
|
//
|
|
// @Description:
|
|
// @param url
|
|
// @return map[string]interface{}
|
|
// @return error
|
|
func HttpGetApi(url string) (map[string]interface{}, error) {
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
var status map[string]interface{}
|
|
if err := json.NewDecoder(resp.Body).Decode(&status); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return status, err
|
|
}
|
|
|
|
// HttpGetDoKeyMap
|
|
//
|
|
// @Description:
|
|
// @param url
|
|
// @return map[string]interface{}
|
|
// @return error
|
|
func HttpGetDoKeyMap(url string) (map[string]interface{}, error) {
|
|
req, err := http.NewRequest("GET", url, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req.Header.Add("X-RapidAPI-Key", flags.SetNull)
|
|
req.Header.Add("X-RapidAPI-Host", flags.SetNull)
|
|
|
|
res, err := http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
var status map[string]interface{}
|
|
if err := json.NewDecoder(res.Body).Decode(&status); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return status, nil
|
|
}
|
|
|
|
// HttpPost
|
|
//
|
|
// @Description:
|
|
// @param url
|
|
// @param body
|
|
// @return string
|
|
// @return error
|
|
func HttpPost(url string, body string) (string, error) {
|
|
resp, err := http.Post(url, "application/json", strings.NewReader(body))
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
defer resp.Body.Close()
|
|
result, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return flags.SetNull, err
|
|
}
|
|
|
|
return string(result), err
|
|
}
|
|
|
|
// ReplaceStr
|
|
//
|
|
// @Description: 字符串替换空字符串
|
|
// @param value
|
|
// @return string
|
|
func ReplaceStr(value string) string {
|
|
return strings.Replace(value, " ", flags.SetNull, 1)
|
|
}
|
|
|
|
// ReplaceStrByValue
|
|
//
|
|
// @Description: 字符串替换 value替换为"-"
|
|
// @param str
|
|
// @param value
|
|
// @return string
|
|
func ReplaceStrByValue(str, value string) string {
|
|
return strings.Replace(str, value, "-", 1)
|
|
}
|
|
|
|
// IntegerInit
|
|
//
|
|
// @Description:
|
|
// @param value
|
|
// @return int
|
|
func IntegerInit(value string) int {
|
|
in, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
return in
|
|
}
|
|
|
|
// TimeMaoSendToString
|
|
//
|
|
// @Description: int64 - string
|
|
// @param i
|
|
// @return string
|
|
func TimeMaoSendToString(i int64) string {
|
|
t := time.Unix(0, i*int64(time.Microsecond))
|
|
|
|
return t.Format(flags.TimeLayout)
|
|
}
|
|
|
|
// TimeDateToMaoSend
|
|
//
|
|
// @Description: time - int64
|
|
// @param t
|
|
// @return int64
|
|
func TimeDateToMaoSend(t time.Time) int64 {
|
|
now := time.Now()
|
|
fmt.Println(now)
|
|
return now.UnixMicro()
|
|
}
|
|
|
|
// TimeStringToTime
|
|
//
|
|
// @Description: string - time
|
|
// @param t
|
|
// @return time.Time
|
|
func TimeStringToTime(t string) time.Time {
|
|
loc, err := time.LoadLocation("Local")
|
|
if err != nil {
|
|
return time.Time{}
|
|
}
|
|
theTime, err := time.ParseInLocation(flags.LayoutTime, t, loc)
|
|
if err != nil {
|
|
return time.Time{}
|
|
}
|
|
|
|
return theTime
|
|
}
|
|
|
|
// TimeStringToIn64
|
|
//
|
|
// @Description: string - int64
|
|
// @param t
|
|
// @return int64
|
|
func TimeStringToIn64(t string) int64 {
|
|
loc, err := time.LoadLocation("Local")
|
|
if err != nil {
|
|
return int64(0)
|
|
}
|
|
theTime, err := time.ParseInLocation(flags.LayoutTime, t, loc)
|
|
if err != nil {
|
|
return int64(0)
|
|
}
|
|
|
|
return theTime.UnixMicro()
|
|
}
|
|
|
|
// DealPrice
|
|
//
|
|
// @Description:
|
|
// @param types
|
|
// @param limitPrice
|
|
// @param marketPrice
|
|
// @return decimal.Decimal
|
|
func DealPrice(types int, limitPrice, marketPrice string) decimal.Decimal {
|
|
switch types {
|
|
case 1:
|
|
return decimal.RequireFromString(limitPrice)
|
|
case 2:
|
|
return decimal.RequireFromString(marketPrice)
|
|
default:
|
|
return decimal.Zero
|
|
}
|
|
}
|
|
|
|
// GZipDecompress
|
|
//
|
|
// @Description:
|
|
// @param input
|
|
// @return string
|
|
// @return error
|
|
func GZipDecompress(input []byte) (string, error) {
|
|
buf := bytes.NewBuffer(input)
|
|
reader, gzipErr := gzip.NewReader(buf)
|
|
if gzipErr != nil {
|
|
return flags.SetNull, gzipErr
|
|
}
|
|
defer reader.Close()
|
|
|
|
result, readErr := ioutil.ReadAll(reader)
|
|
if readErr != nil {
|
|
return flags.SetNull, readErr
|
|
}
|
|
|
|
return string(result), nil
|
|
}
|
|
|
|
// Difference
|
|
//
|
|
// @Description: [生成指定范围的随机小数.注:很不智能,需要限制min和max前面的数字必须相同例如min:0.0001 max:0.0005]
|
|
// @return decimal.Decimal
|
|
func Difference() decimal.Decimal {
|
|
rad := RandFloat64(flags.MinDifference, flags.MaxDifference)
|
|
|
|
return decimal.NewFromFloat(rad)
|
|
}
|
|
|
|
// RandFloat64
|
|
//
|
|
// @Description:
|
|
// @param min
|
|
// @param max
|
|
// @return float64
|
|
func RandFloat64(min, max float64) float64 {
|
|
my_min := strconv.FormatFloat(min, 'f', -1, 64)
|
|
my_max := strconv.FormatFloat(max, 'f', -1, 64)
|
|
|
|
if len(my_min) != len(my_max) {
|
|
return 0
|
|
} else {
|
|
prefix := flags.SetNull
|
|
suffix := flags.SetNull
|
|
suffix1 := flags.SetNull
|
|
sw := 0
|
|
for i := 0; i < len(my_min); i++ {
|
|
str1 := string(my_min[i])
|
|
str2 := string(my_max[i])
|
|
if sw == 0 {
|
|
if my_min[i] == my_max[i] {
|
|
prefix = prefix + str1
|
|
} else {
|
|
sw = 1
|
|
suffix = suffix + str1
|
|
suffix1 = suffix1 + str2
|
|
}
|
|
} else {
|
|
suffix = suffix + str1
|
|
suffix1 = suffix1 + str2
|
|
}
|
|
}
|
|
//前缀字符串转整数
|
|
prefix1, err := strconv.ParseInt(suffix, 10, 64)
|
|
if err != nil {
|
|
applogger.Error("prefix1 ParseInt err: %v", err)
|
|
return min
|
|
}
|
|
prefix2, err := strconv.ParseInt(suffix1, 10, 64)
|
|
if err != nil {
|
|
applogger.Error("prefix2 ParseInt err: %v", err)
|
|
return min
|
|
}
|
|
//生成随机整数
|
|
sjz := RandInt64(prefix1, prefix2)
|
|
//随机整数转字符串
|
|
sjz_str := strconv.FormatInt(sjz, 10)
|
|
//前缀拼接随机字符串
|
|
all_str := prefix + sjz_str
|
|
//全字符串转浮点数
|
|
result, _ := strconv.ParseFloat(all_str, 64)
|
|
|
|
return result
|
|
}
|
|
}
|
|
|
|
// RandInt64
|
|
//
|
|
// @Description:
|
|
// @param min
|
|
// @param max
|
|
// @return int64
|
|
func RandInt64(min, max int64) int64 {
|
|
if min >= max || min == 0 || max == 0 {
|
|
return max
|
|
}
|
|
rand.Seed(time.Now().UnixNano())
|
|
|
|
return rand.Int63n(max-min) + min
|
|
}
|
|
|
|
// RandInt
|
|
//
|
|
// @Description: 随机[1,2]整数
|
|
// @return decimal.Decimal
|
|
func RandInt() decimal.Decimal {
|
|
rand.Seed(time.Now().UnixNano())
|
|
randomInt := rand.Intn(2) + 1
|
|
|
|
return decimal.RequireFromString(strconv.Itoa(randomInt))
|
|
}
|
|
|
|
// CheckTime
|
|
//
|
|
// @Description: 判断当前时间是否在区间内["09:00"~"09:05"]
|
|
// @param start
|
|
// @param end
|
|
// @return bool
|
|
func CheckTime(start, end string) bool {
|
|
current, _ := time.Parse("15:04", time.Now().Format("15:04"))
|
|
startTime, _ := time.Parse("15:04", start)
|
|
endTime, _ := time.Parse("15:04", end)
|
|
|
|
if current.After(startTime) && current.Before(endTime) || current.Equal(startTime) || current.Equal(endTime) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
// CheckInPlateTime
|
|
//
|
|
// @Description: 判定股票市场是否盘中
|
|
// @param openTime
|
|
// @param closeTime
|
|
// @return bool
|
|
func CheckInPlateTime(timeValue flags.TimeValue) bool {
|
|
var checkBool bool
|
|
dateTime, _ := time.Parse(flags.LayoutOne, time.Now().Format(flags.LayoutOne))
|
|
// 判定上午盘
|
|
checkAmTime := dateTime.Equal(timeValue.AmOpenTime) || dateTime.Equal(timeValue.AmCloseTime)
|
|
if timeValue.AmOpenTime.Before(timeValue.AmCloseTime) {
|
|
// 同一天
|
|
if dateTime.After(timeValue.AmOpenTime) && dateTime.Before(timeValue.AmCloseTime) || checkAmTime {
|
|
checkBool = true
|
|
}
|
|
} else {
|
|
// 跨天
|
|
if dateTime.After(timeValue.AmOpenTime) || dateTime.Before(timeValue.AmCloseTime) || checkAmTime {
|
|
checkBool = true
|
|
}
|
|
}
|
|
// 判定下午盘
|
|
checkPmTime := dateTime.Equal(timeValue.PmOpenTime) || dateTime.Equal(timeValue.PmCloseTime)
|
|
if timeValue.PmOpenTime.Before(timeValue.PmCloseTime) {
|
|
// 同一天
|
|
if dateTime.After(timeValue.PmOpenTime) && dateTime.Before(timeValue.PmCloseTime) || checkPmTime {
|
|
checkBool = true
|
|
}
|
|
} else {
|
|
// 跨天
|
|
if dateTime.After(timeValue.PmOpenTime) || dateTime.Before(timeValue.PmCloseTime) || checkPmTime {
|
|
checkBool = true
|
|
}
|
|
}
|
|
|
|
return checkBool
|
|
}
|
|
|
|
// CheckTimeUTC
|
|
//
|
|
// @Description: 判断时间是否在区间内
|
|
// @param start
|
|
// @param end
|
|
// @return bool
|
|
func CheckTimeUTC(start, end string) bool {
|
|
current, _ := time.Parse(flags.LayoutTime, time.Now().Format(flags.LayoutTime))
|
|
startTime, _ := time.Parse(flags.LayoutTime, start)
|
|
endTime, _ := time.Parse(flags.LayoutTime, end)
|
|
|
|
if current.After(startTime) && current.Before(endTime) || current.Equal(startTime) || current.Equal(endTime) {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
// GetTime
|
|
//
|
|
// @Description: 获取时间格式["09:00"]
|
|
// @return string
|
|
func GetTime() string {
|
|
// 获取当前时间
|
|
currentTime := time.Now()
|
|
|
|
// 获取当前时间的小时和分钟
|
|
hour := currentTime.Hour()
|
|
minute := currentTime.Minute()
|
|
|
|
// 打印小时和分钟
|
|
return fmt.Sprintf("%02d:%02d", hour, minute)
|
|
}
|
|
|
|
// GetAddTime
|
|
//
|
|
// @Description: 新增时间
|
|
// @param st
|
|
// @param t
|
|
// @return string
|
|
func GetAddTime(st string, t string) string {
|
|
startTime, _ := time.Parse("15:04", st)
|
|
|
|
duration, _ := time.ParseDuration(t)
|
|
|
|
endTime := startTime.Add(duration)
|
|
|
|
return endTime.Format("15:04")
|
|
}
|
|
|
|
// StrReplace
|
|
//
|
|
// @Description: 替换空字符串
|
|
// @param str
|
|
// @return string
|
|
func StrReplace(str string) string {
|
|
return strings.Replace(string(str), " ", flags.SetNull, -1)
|
|
}
|
|
|
|
// IsNumber
|
|
//
|
|
// @Description: 正则判定是否为整数或者小数
|
|
// @param input
|
|
// @return bool
|
|
func IsNumber(input string) bool {
|
|
numberRegex := regexp.MustCompile(`^(-)?[0-9]+(\.[0-9]+)?$`)
|
|
|
|
return numberRegex.MatchString(input)
|
|
}
|
|
|
|
// IsNumberInt
|
|
//
|
|
// @Description: 正则判定是否正整数
|
|
// @param input
|
|
// @return bool
|
|
func IsNumberInt(input string) bool {
|
|
numberRegex := regexp.MustCompile(`^[1-9]\d*$`)
|
|
|
|
return numberRegex.MatchString(input)
|
|
}
|
|
|
|
// DecimalsPrice
|
|
//
|
|
// @Description: 处理小数
|
|
// @param price
|
|
// @return string
|
|
func DecimalsPrice(price string) string {
|
|
if len(price) == 0 {
|
|
return flags.SetNull
|
|
}
|
|
num, err := strconv.ParseFloat(price, 64)
|
|
if err != nil {
|
|
applogger.Error("DecimalsPrice err:%", err)
|
|
return flags.SetNull
|
|
}
|
|
|
|
return strconv.FormatFloat(num, 'f', -1, 64)
|
|
}
|
|
|
|
// DecimlsStrInt
|
|
//
|
|
// @Description: 定义下单判定比例
|
|
// @return decimal.Decimal
|
|
func DecimalsStrInt() decimal.Decimal {
|
|
return decimal.RequireFromString(flags.OrderCheck)
|
|
}
|
|
|
|
// TimeAddDay
|
|
//
|
|
// @Description: 时间+天+时分秒
|
|
// @param day
|
|
// @return time.Time
|
|
func TimeAddDay(day string) (time.Time, error) {
|
|
dayInt, err := strconv.Atoi(day)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
// 获取当前时间
|
|
currentTime := time.Now()
|
|
// 创建一个表示指定天数的 Duration (24小时 * 天数)
|
|
duration := time.Duration(dayInt) * 24 * time.Hour
|
|
// 把 Duration 添加到当前时间上
|
|
return currentTime.Add(duration), nil
|
|
}
|
|
|
|
// TimeAddDayZero
|
|
//
|
|
// @Description: 时间+天
|
|
// @param day
|
|
// @return time.Time
|
|
// @return error
|
|
func TimeAddDayZero(dayInt int) time.Time {
|
|
// 获取当前时间
|
|
currentTime := time.Now()
|
|
// 创建一个表示指定天数的 Duration (24小时 * 天数)
|
|
duration := time.Duration(dayInt) * 24 * time.Hour
|
|
// 把 Duration 添加到当前时间上
|
|
timeFormat := currentTime.Add(duration).Format(flags.LayoutZero)
|
|
// string-time
|
|
parsedTime, err := time.Parse(flags.LayoutZero, timeFormat)
|
|
if err != nil {
|
|
return time.Time{}
|
|
}
|
|
|
|
return parsedTime
|
|
}
|
|
|
|
// TimeAddDaySend
|
|
//
|
|
// @Description: 时间+天
|
|
// @param day
|
|
// @return time.Time
|
|
// @return error
|
|
func TimeAddDaySend(day string) (time.Time, error) {
|
|
dayInt, err := strconv.Atoi(day)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
dayS := dayInt - 1
|
|
|
|
// 当前时间
|
|
currentTime := time.Now()
|
|
// 创建一个表示指定天数的 Duration (24小时 * 天数)
|
|
duration := time.Duration(dayS) * 24 * time.Hour
|
|
// time-string
|
|
timeFormat := currentTime.Add(duration).Format(flags.LayoutZero)
|
|
// string-time
|
|
parsedTime, err := time.Parse(flags.LayoutZero, timeFormat)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
|
|
return parsedTime, nil
|
|
}
|
|
|
|
// TimeStopTime
|
|
//
|
|
// @Description: 处理期权到期时间
|
|
// @param day
|
|
// @return time.Time
|
|
// @return error
|
|
func TimeStopTime(day string) (time.Time, error) {
|
|
dayStr := fmt.Sprintf("%v 00:00:00", day)
|
|
parsedTime, err := time.Parse(flags.LayoutZero, dayStr)
|
|
if err != nil {
|
|
return time.Time{}, err
|
|
}
|
|
|
|
return parsedTime, nil
|
|
}
|
|
|
|
// TimeYYYMMDD
|
|
//
|
|
// @Description: 期权到期时间和当前时间判定是否相同-相同不容许下单
|
|
// @param day
|
|
// @return time.Time
|
|
// @return error
|
|
func TimeYYYMMDD(day string) bool {
|
|
timeNow := time.Now().Format(flags.TimeFormat)
|
|
if timeNow == day {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// TimeComparison
|
|
//
|
|
// @Description: 时间校对(时间到期平仓)
|
|
// @param stopTime
|
|
// @return bool
|
|
func TimeComparison(stopTime time.Time) bool {
|
|
time1 := time.Now()
|
|
time2 := stopTime.Add(time.Hour * 17)
|
|
|
|
// 判断 time1 是否在 time2 之前
|
|
if time1.Before(time2) {
|
|
return false
|
|
}
|
|
|
|
// 判断两个时间是否相同
|
|
if time1.Equal(time2) {
|
|
return true
|
|
}
|
|
|
|
// 判断 time1 是否在 time2 之后
|
|
if time1.After(time2) {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// MapToString
|
|
//
|
|
// @Description: map[string]string 转 string
|
|
// @param m
|
|
// @return string
|
|
// @return error
|
|
func MapToString(m map[string]string) (string, error) {
|
|
jsonBytes, err := json.Marshal(m)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
buffer := bytes.NewBuffer(jsonBytes)
|
|
return buffer.String(), nil
|
|
}
|
|
|
|
// StringToInt
|
|
//
|
|
// @Description: String -> To
|
|
// @param str
|
|
// @return int
|
|
func StringToInt(str string) int {
|
|
checkInt, err := strconv.Atoi(str)
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
return checkInt
|
|
}
|
|
|
|
// ExtractSubstringBeforeFirstDigit
|
|
//
|
|
// @Description: takes a string and returns the substring before the first digit.
|
|
// @param s
|
|
// @return string
|
|
func ExtractSubstringBeforeFirstDigit(s string) string {
|
|
for i, c := range s {
|
|
if unicode.IsDigit(c) {
|
|
return s[:i]
|
|
}
|
|
}
|
|
return s // 如果没有找到数字,返回原字符串
|
|
}
|
|
|