feat:完善项目
This commit is contained in:
51
utils/array.go
Normal file
51
utils/array.go
Normal file
@ -0,0 +1,51 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func InArray(search, needle interface{}) bool {
|
||||
val := reflect.ValueOf(needle)
|
||||
|
||||
kind := val.Kind()
|
||||
|
||||
if kind == reflect.Slice || kind == reflect.Array {
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
if val.Index(i).Interface() == search {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ArrayFlip(src interface{}) interface{} {
|
||||
val := reflect.ValueOf(src)
|
||||
|
||||
kind := val.Kind()
|
||||
|
||||
out := make(map[interface{}]interface{}, 0)
|
||||
|
||||
if kind == reflect.Slice || kind == reflect.Array || kind == reflect.Map {
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
fmt.Printf("val.Field():%v\n", val.Index(i).MapKeys())
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func ArrayStrings(src interface{}) []string {
|
||||
out := make([]string, 0)
|
||||
|
||||
val := reflect.ValueOf(src)
|
||||
|
||||
kind := val.Kind()
|
||||
|
||||
if kind == reflect.Slice || kind == reflect.Array {
|
||||
for i := 0; i < val.Len(); i++ {
|
||||
out = append(out, fmt.Sprintf("%v", val.Index(i).Interface()))
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
31
utils/array_test.go
Normal file
31
utils/array_test.go
Normal file
@ -0,0 +1,31 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
a = 0x00001
|
||||
b = 0x00010
|
||||
c = 0x00100
|
||||
)
|
||||
|
||||
func TestArrayFlip(t *testing.T) {
|
||||
//flip := []uint64{1, 2, 3, 4}
|
||||
//out := ArrayFlip(flip)
|
||||
//t.Logf("out:%v\n", out)
|
||||
|
||||
d := a & b & c
|
||||
t.Log(d)
|
||||
|
||||
}
|
||||
|
||||
func TestArrayStrings(t *testing.T) {
|
||||
a := []uint64{1, 2, 3, 4, 5}
|
||||
t.Log(a)
|
||||
t.Log(reflect.TypeOf(a).String())
|
||||
b := ArrayStrings(a)
|
||||
t.Log(b)
|
||||
t.Log(reflect.TypeOf(b).String())
|
||||
}
|
9
utils/bit_calc.go
Normal file
9
utils/bit_calc.go
Normal file
@ -0,0 +1,9 @@
|
||||
package utils
|
||||
|
||||
// Exchange 位置交换
|
||||
func Exchange(a, b int) (int, int) {
|
||||
a = a ^ b
|
||||
b = a ^ b
|
||||
a = a ^ b
|
||||
return a, b
|
||||
}
|
83
utils/bit_calc_test.go
Normal file
83
utils/bit_calc_test.go
Normal file
@ -0,0 +1,83 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func converToBianry(n int) string {
|
||||
result := ""
|
||||
for ; n > 0; n /= 2 {
|
||||
lsb := n % 2
|
||||
result = strconv.Itoa(lsb) + result
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// 1,2,4
|
||||
func TestExchange(t *testing.T) {
|
||||
for i := 0; i < 10; i++ {
|
||||
//t.Log(1 << uint(i))
|
||||
}
|
||||
|
||||
//t.Log(0b00000000100)
|
||||
a := 1
|
||||
b := 1 << 1
|
||||
c := 1 << 2
|
||||
t.Log(a)
|
||||
t.Log(b)
|
||||
t.Log(c)
|
||||
|
||||
d := a | b | c
|
||||
t.Log(d)
|
||||
|
||||
t.Log(d & a)
|
||||
t.Log(d & b)
|
||||
t.Log(d & c)
|
||||
}
|
||||
|
||||
func TestAnyToByte(t *testing.T) {
|
||||
src := []int{1}
|
||||
|
||||
mark := 0
|
||||
|
||||
for i := 0; i < len(src); i++ {
|
||||
mark = mark | src[i]
|
||||
}
|
||||
t.Log(mark)
|
||||
}
|
||||
|
||||
func TestFromJSONFile(t *testing.T) {
|
||||
file := "FWBAT-GX-A13-V310.bin"
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
content, err := ioutil.ReadAll(f)
|
||||
|
||||
if err != nil {
|
||||
t.Log(err)
|
||||
return
|
||||
}
|
||||
t.Log(content)
|
||||
t.Log(len(content))
|
||||
|
||||
inputReader := bufio.NewReader(f)
|
||||
s, _, _ := inputReader.ReadLine()
|
||||
|
||||
t.Log(s)
|
||||
t.Log(len(s))
|
||||
//t.Log(bufio.NewReader(f))
|
||||
//for {
|
||||
// inputString, readerError := inputReader.ReadString('\n') //我们将inputReader里面的字符串按行进行读取。
|
||||
// if readerError == io.EOF {
|
||||
// return
|
||||
// }
|
||||
// t.Log(inputString)
|
||||
//}
|
||||
}
|
13
utils/catch.go
Normal file
13
utils/catch.go
Normal file
@ -0,0 +1,13 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
func TryCatch(f func()) {
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
err = fmt.Errorf("internal error: %v", err)
|
||||
fmt.Printf("TryCatch Error:%v\n", err)
|
||||
}
|
||||
}()
|
||||
f()
|
||||
}
|
89
utils/convert.go
Normal file
89
utils/convert.go
Normal file
@ -0,0 +1,89 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// types 数据结构类型
|
||||
types = []string{"string", "int64", "int", "uint", "uint64", "byte"}
|
||||
)
|
||||
|
||||
// ConvertTypes 需转换的类型
|
||||
type ConvertTypes struct {
|
||||
String, Int64, Int, Uint, Uint64, Byte bool
|
||||
}
|
||||
|
||||
// TypeConvert type mutual convert
|
||||
// result -- interface.(type)
|
||||
func (c *ConvertTypes) TypeConvert(from interface{}) interface{} {
|
||||
|
||||
fType := reflect.TypeOf(from)
|
||||
|
||||
val := func(r reflect.Type) interface{} {
|
||||
|
||||
return nil
|
||||
|
||||
}(fType)
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
// MapToStruct map to struct
|
||||
// key is struct filedName
|
||||
func MapToStruct(m map[string]interface{}, s interface{}) {
|
||||
for k, v := range m {
|
||||
|
||||
tRef := reflect.TypeOf(s).Elem()
|
||||
|
||||
fieldNum := tRef.NumField()
|
||||
|
||||
for i := 0; i < fieldNum; i++ {
|
||||
// 匹配结构字段名称
|
||||
if strings.ToLower(k) != strings.ToLower(tRef.Field(i).Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
vRef := reflect.ValueOf(s).Elem().FieldByName(tRef.Field(i).Name)
|
||||
|
||||
if !vRef.CanSet() {
|
||||
continue
|
||||
}
|
||||
|
||||
switch vRef.Type().String() {
|
||||
case "string":
|
||||
vRef.SetString(v.(string))
|
||||
break
|
||||
case "int64":
|
||||
vRef.SetInt(v.(int64))
|
||||
break
|
||||
case "int":
|
||||
switch reflect.TypeOf(v).String() {
|
||||
case "float64":
|
||||
vRef.SetInt(int64(v.(float64)))
|
||||
break
|
||||
case "int":
|
||||
vRef.SetInt(int64(v.(int)))
|
||||
break
|
||||
}
|
||||
break
|
||||
case "bool":
|
||||
vRef.SetBool(v.(bool))
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// StructToMap struct to map
|
||||
func StructToMap(s interface{}, m map[string]interface{}) {
|
||||
tRef := reflect.TypeOf(s).Elem()
|
||||
vRef := reflect.ValueOf(s).Elem()
|
||||
|
||||
fieldNum := tRef.NumField()
|
||||
|
||||
for index := 0; index < fieldNum; index++ {
|
||||
m[tRef.Field(index).Name] = vRef.FieldByName(tRef.Field(index).Name).Interface()
|
||||
}
|
||||
}
|
52
utils/encrypt.go
Normal file
52
utils/encrypt.go
Normal file
@ -0,0 +1,52 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/sha1"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// Md5String
|
||||
func Md5String(s string, salt ...string) string {
|
||||
h := md5.New()
|
||||
if len(salt) > 0 {
|
||||
s += strings.Join(salt, "")
|
||||
}
|
||||
h.Write([]byte(s))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Sha1String
|
||||
func Sha1String(s string) string {
|
||||
h := sha1.New()
|
||||
h.Write([]byte(s))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Sha256String
|
||||
func Sha256String(s string) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(s))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
// Sha512String
|
||||
func Sha512String(s string) string {
|
||||
h := sha512.New()
|
||||
h.Write([]byte(s))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
|
||||
func HashString(s []byte) string {
|
||||
hash, _ := bcrypt.GenerateFromPassword(s, bcrypt.DefaultCost)
|
||||
return string(hash)
|
||||
}
|
||||
|
||||
func HashCompare(src, compare []byte) bool {
|
||||
return bcrypt.CompareHashAndPassword(src, compare) == nil
|
||||
}
|
7
utils/encrypt_test.go
Normal file
7
utils/encrypt_test.go
Normal file
@ -0,0 +1,7 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestSha256String(t *testing.T) {
|
||||
t.Log(Md5String("9f735e0df9a1ddc702bf0a1a7b83033f9f7153a00c29de82cedadc9957289b05"))
|
||||
}
|
61
utils/file.go
Normal file
61
utils/file.go
Normal file
@ -0,0 +1,61 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
func Open(name string) (f *os.File, err error) {
|
||||
_, err = os.Stat(name)
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
return os.OpenFile(name, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0666)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, fmt.Errorf("file %s already exists", name)
|
||||
}
|
||||
|
||||
func PathExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
func IsDir(path string) bool {
|
||||
s, err := os.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return s.IsDir()
|
||||
}
|
||||
|
||||
func Mkdir(path string) error {
|
||||
return os.Mkdir(path, os.ModePerm)
|
||||
}
|
||||
|
||||
func MkdirAll(path string) error {
|
||||
return os.MkdirAll(path, os.ModePerm)
|
||||
}
|
||||
|
||||
func PrepareOutput(path string) error {
|
||||
fi, err := os.Stat(path)
|
||||
|
||||
if err != nil {
|
||||
if os.IsExist(err) && !fi.IsDir() {
|
||||
return err
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
err = os.MkdirAll(path, 0777)
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
83
utils/json.go
Normal file
83
utils/json.go
Normal file
@ -0,0 +1,83 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// AnyToJSON ToJson
|
||||
func AnyToJSON(any interface{}) string {
|
||||
bytes, _ := json.Marshal(any)
|
||||
return string(bytes)
|
||||
}
|
||||
|
||||
// AnyToByte ToByte
|
||||
func AnyToByte(any interface{}) []byte {
|
||||
bytes, _ := json.Marshal(any)
|
||||
return bytes
|
||||
}
|
||||
|
||||
// FromJSON get value from JSON string
|
||||
func FromJSON(data string, v interface{}) error {
|
||||
if data == "" {
|
||||
return errors.New("data nil")
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(data), v); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromJSONToMap get mapvalue from JSON string
|
||||
func FromJSONToMap(data string) map[string]interface{} {
|
||||
var jsonBody map[string]interface{}
|
||||
//解析 body
|
||||
if len(data) > 0 {
|
||||
FromJSON(data, &jsonBody)
|
||||
} else {
|
||||
jsonBody = make(map[string]interface{}, 0)
|
||||
}
|
||||
return jsonBody
|
||||
}
|
||||
|
||||
// FromJSONBytes get value from JSON bytes
|
||||
func FromJSONBytes(data []byte, v interface{}) error {
|
||||
if len(data) <= 0 {
|
||||
return errors.New("data nil")
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, v); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FromJSONReader get value from JSON Reader
|
||||
func FromJSONReader(data io.Reader, v interface{}) error {
|
||||
if data == nil {
|
||||
return errors.New("jsonFile nail")
|
||||
}
|
||||
|
||||
jsonDecoder := json.NewDecoder(data)
|
||||
return jsonDecoder.Decode(v)
|
||||
}
|
||||
|
||||
// FromJSONFile get value from JSON file
|
||||
func FromJSONFile(jsonFile string, v interface{}) error {
|
||||
if len(jsonFile) <= 0 {
|
||||
return errors.New("jsonFile nail")
|
||||
}
|
||||
|
||||
file, err := os.Open(jsonFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
jsonDecoder := json.NewDecoder(bufio.NewReader(file))
|
||||
return jsonDecoder.Decode(v)
|
||||
}
|
45
utils/jwt.go
Normal file
45
utils/jwt.go
Normal file
@ -0,0 +1,45 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
const jwtKey = "abc123ABC"
|
||||
|
||||
// JWTEncrypt 加密
|
||||
func JWTEncrypt(effectTimes int, param ...map[string]interface{}) string {
|
||||
token := jwt.New(jwt.SigningMethodHS256)
|
||||
claims := make(jwt.MapClaims, 0)
|
||||
claims["exp"] = fmt.Sprintf("%d", time.Now().Add(time.Second*time.Duration(effectTimes)).Unix())
|
||||
claims["iat"] = fmt.Sprintf("%d", time.Now().Unix())
|
||||
|
||||
if len(param) > 0 {
|
||||
for _, val := range param {
|
||||
for k, v := range val {
|
||||
claims[k] = v
|
||||
}
|
||||
}
|
||||
}
|
||||
token.Claims = claims
|
||||
tokenString, _ := token.SignedString([]byte(jwtKey))
|
||||
return tokenString
|
||||
}
|
||||
|
||||
// JWTDecrypt 解密
|
||||
func JWTDecrypt(tokenString string) jwt.MapClaims {
|
||||
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(jwtKey), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return claims
|
||||
}
|
42
utils/rand.go
Normal file
42
utils/rand.go
Normal file
@ -0,0 +1,42 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
uuid "github.com/satori/go.uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
)
|
||||
|
||||
func GetUUID() string {
|
||||
return uuid.NewV4().String()
|
||||
}
|
||||
|
||||
func GetRandomCode(length int) string {
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
code := make([]string, 0)
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
code = append(code, fmt.Sprintf("%d", rand.Intn(10)))
|
||||
}
|
||||
return strings.Join(code, "")
|
||||
}
|
||||
|
||||
func GetRandomString(length int) string {
|
||||
bytes := []byte(str)
|
||||
|
||||
result := make([]byte, 0)
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
for i := 0; i < length; i++ {
|
||||
result = append(result, bytes[r.Intn(len(bytes))])
|
||||
}
|
||||
return string(result)
|
||||
}
|
14
utils/reflect.go
Normal file
14
utils/reflect.go
Normal file
@ -0,0 +1,14 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
)
|
||||
|
||||
func DeepCopy(dst, src interface{}) error {
|
||||
var buf bytes.Buffer
|
||||
if err := gob.NewEncoder(&buf).Encode(src); err != nil {
|
||||
return err
|
||||
}
|
||||
return gob.NewDecoder(bytes.NewBuffer(buf.Bytes())).Decode(dst)
|
||||
}
|
34
utils/regexp.go
Normal file
34
utils/regexp.go
Normal file
@ -0,0 +1,34 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
)
|
||||
|
||||
func ValidateMobile(mobile string) bool {
|
||||
reg := regexp.MustCompile("^1[3|4|5|6|7|8|9][0-9]\\d{8}$")
|
||||
return reg.MatchString(mobile)
|
||||
}
|
||||
|
||||
func ValidateEmail(email string) bool {
|
||||
reg := regexp.MustCompile("^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$")
|
||||
return reg.MatchString(email)
|
||||
}
|
||||
|
||||
func ValidateUrl(url string) {
|
||||
//reg := regexp.MustCompile("^([hH][tT]{2}[pP]:|||[hH][tT]{2}[pP][sS]:|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$")
|
||||
}
|
||||
|
||||
func ValidateCompile(obj, compile string) bool {
|
||||
reg := regexp.MustCompile(compile)
|
||||
return reg.MatchString(obj)
|
||||
}
|
||||
|
||||
func ReplaceAllCompile(obj, compile, replace string) string {
|
||||
reg := regexp.MustCompile(compile)
|
||||
return reg.ReplaceAllString(obj, replace)
|
||||
}
|
||||
|
||||
func MatchString(pattern string, s string) bool {
|
||||
status, _ := regexp.MatchString(pattern, s)
|
||||
return status
|
||||
}
|
47
utils/regexp_test.go
Normal file
47
utils/regexp_test.go
Normal file
@ -0,0 +1,47 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestReplaceCompile(t *testing.T) {
|
||||
src := "12312321321"
|
||||
|
||||
t.Log(src)
|
||||
|
||||
compile := "[/]+"
|
||||
src = ReplaceAllCompile(src, compile, "/")
|
||||
t.Log(src)
|
||||
|
||||
compile = "(^[\\w])([\\w/]*)([\\w])$"
|
||||
//compile = "(^[\\w])"
|
||||
|
||||
//compile = "^[\\w]" +
|
||||
// "([\\w*])" +
|
||||
// "[\\w]$"
|
||||
status := ValidateCompile(src, compile)
|
||||
t.Log(status)
|
||||
|
||||
//compile := "user.+\\z"
|
||||
//src = ReplaceAllCompile(src, compile, "user")
|
||||
//t.Log(src)
|
||||
|
||||
//compile = "^\\w{0,50}$"
|
||||
//status = ValidateCompile(src, compile)
|
||||
//t.Log(status)
|
||||
//
|
||||
////支持中文、大小写字母、日文、数字、短划线、下划线、斜杠和小数点,必须以中文、英文或数字开头,不超过 30 个字符
|
||||
//compile = "(^[a-zA-Z0-9\u4e00-\u9fa5])([a-zA-Z0-9_\u4e00-\u9fa5-_/.]*){0,30}$"
|
||||
//status = ValidateCompile(src, compile)
|
||||
//t.Logf("文本检测:%v\n", status)
|
||||
}
|
||||
|
||||
func TestValidateCompile(t *testing.T) {
|
||||
src := "2134"
|
||||
|
||||
t.Log(src)
|
||||
|
||||
compile := "^[\\w-.:]{4,32}$"
|
||||
status := ValidateCompile(src, compile)
|
||||
t.Log(status)
|
||||
}
|
55
utils/snowflake.go
Normal file
55
utils/snowflake.go
Normal file
@ -0,0 +1,55 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
workerBits uint8 = 10
|
||||
numberBits uint8 = 12
|
||||
workerMax int64 = -1 ^ (-1 << workerBits)
|
||||
numberMax int64 = -1 ^ (-1 << numberBits)
|
||||
timeShift uint8 = workerBits + numberBits
|
||||
workerShift uint8 = numberBits
|
||||
startTime int64 = 1136185445000
|
||||
)
|
||||
|
||||
type Worker struct {
|
||||
mu sync.Mutex
|
||||
timestamp int64
|
||||
workerID int64
|
||||
number int64
|
||||
}
|
||||
|
||||
func (w *Worker) GetID() int64 {
|
||||
w.mu.Lock()
|
||||
defer w.mu.Unlock()
|
||||
now := time.Now().UnixNano() / 1e6
|
||||
|
||||
if w.timestamp == now {
|
||||
w.number++
|
||||
if w.number > numberMax {
|
||||
for now <= w.timestamp {
|
||||
now = time.Now().UnixNano() / 1e6
|
||||
}
|
||||
}
|
||||
} else {
|
||||
w.number = 0
|
||||
w.timestamp = now
|
||||
}
|
||||
return (now-startTime)<<timeShift | (w.workerID << workerShift) | (w.number)
|
||||
}
|
||||
|
||||
func NewSnowflake(workerID int64) (*Worker, error) {
|
||||
if workerID < 0 || workerID > workerMax {
|
||||
return nil, errors.New("Worker ID Excess Of Quantity")
|
||||
}
|
||||
// 生成一个新节点
|
||||
return &Worker{
|
||||
timestamp: 0,
|
||||
workerID: workerID,
|
||||
number: 0,
|
||||
}, nil
|
||||
}
|
38
utils/strconv.go
Normal file
38
utils/strconv.go
Normal file
@ -0,0 +1,38 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func StringToInt(src string) int {
|
||||
dst, _ := strconv.Atoi(src)
|
||||
return dst
|
||||
}
|
||||
|
||||
func StringToInt64(src string) int64 {
|
||||
dst, _ := strconv.ParseInt(src, 10, 64)
|
||||
return dst
|
||||
}
|
||||
|
||||
func StringToUnit(src string) uint {
|
||||
dst, _ := strconv.Atoi(src)
|
||||
return uint(dst)
|
||||
}
|
||||
|
||||
func StringToUnit64(src string) uint64 {
|
||||
dst, _ := strconv.ParseUint(src, 10, 64)
|
||||
return dst
|
||||
}
|
||||
|
||||
func StringToFloat(src string) (float64, error) {
|
||||
return strconv.ParseFloat(src, 64)
|
||||
}
|
||||
|
||||
func IntToString(src int64) string {
|
||||
return fmt.Sprintf("%d", src)
|
||||
}
|
||||
|
||||
func UintToString(src uint64) string {
|
||||
return fmt.Sprintf("%d", src)
|
||||
}
|
30
utils/string.go
Normal file
30
utils/string.go
Normal file
@ -0,0 +1,30 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
func ToLowerCase(src []rune) rune {
|
||||
return src[0] | 0x20
|
||||
}
|
||||
|
||||
func ToUpperCase(src []rune) rune {
|
||||
return src[0] ^ 0x20
|
||||
}
|
||||
|
||||
func ToSnake(src, delimiter string) string {
|
||||
src = strings.TrimSpace(src)
|
||||
objs := strings.Split(src, delimiter)
|
||||
|
||||
out := make([]rune, 0)
|
||||
|
||||
for _, v := range objs {
|
||||
if len(v) <= 0 {
|
||||
continue
|
||||
}
|
||||
obj := []rune(v)
|
||||
obj[0] = ToUpperCase(obj)
|
||||
out = append(out, obj...)
|
||||
}
|
||||
return string(out)
|
||||
}
|
8
utils/string_test.go
Normal file
8
utils/string_test.go
Normal file
@ -0,0 +1,8 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestToSnake(t *testing.T) {
|
||||
src := "sys_"
|
||||
t.Log(ToSnake(src, "_"))
|
||||
}
|
63
utils/time.go
Normal file
63
utils/time.go
Normal file
@ -0,0 +1,63 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"math"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Week int
|
||||
|
||||
const (
|
||||
Monday Week = iota + 1
|
||||
Tuesday
|
||||
Wednesday
|
||||
Thursday
|
||||
Friday
|
||||
Saturday
|
||||
Sunday
|
||||
)
|
||||
|
||||
func IsEmptyTime(t time.Time) bool {
|
||||
return t.IsZero()
|
||||
}
|
||||
|
||||
func FormatDate(t time.Time) string {
|
||||
return t.Format("2006-01-02")
|
||||
}
|
||||
|
||||
func FormatDatetime(t time.Time) string {
|
||||
return t.Format("2006-01-02 15:04:05")
|
||||
}
|
||||
|
||||
func FormatTimeForLayout(t time.Time, layout string) string {
|
||||
return t.Format(layout)
|
||||
}
|
||||
|
||||
func DateTimeToTime(t string) time.Time {
|
||||
_time, _ := time.ParseInLocation("2006-01-02 15:04:05", t, time.Local)
|
||||
return _time
|
||||
}
|
||||
|
||||
func GetMondayTime(t time.Time) time.Time {
|
||||
offset := int(time.Monday - t.Weekday())
|
||||
|
||||
if offset > 0 {
|
||||
offset = -6
|
||||
}
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.Local).AddDate(0, 0, offset)
|
||||
}
|
||||
|
||||
func MonthBeginAt(year, month int) time.Time {
|
||||
return time.Date(year, time.Month(month), 1, 0, 0, 0, 0, time.Now().Location())
|
||||
}
|
||||
|
||||
func MonthFinishAt(year, month int) time.Time {
|
||||
mark := time.Date(year, time.Month(month), 1, 23, 59, 59, 0, time.Now().Location())
|
||||
return mark.AddDate(0, 1, -1)
|
||||
}
|
||||
|
||||
func DiffTimeMonth(time1, time2 time.Time) int {
|
||||
year := math.Abs(float64(time1.Year()) - float64(time2.Year()))
|
||||
month := math.Abs(float64(time1.Month()) - float64(time2.Month()))
|
||||
return int(year)*12 + int(month) + 1
|
||||
}
|
Reference in New Issue
Block a user