first commit

This commit is contained in:
jiangyong 2022-12-20 23:45:07 +08:00
commit dc13f589c5
11 changed files with 590 additions and 0 deletions

11
.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
*.iml
.idea/
output/
dockerfiles/
log
.DS_Store
doc
cmd/test
go.sum
pkg
test.go

93
array.go Normal file
View File

@ -0,0 +1,93 @@
package goutil
import "reflect"
func Sort(data interface{}, fun interface{}) {
fValue := reflect.ValueOf(fun)
fType := fValue.Type()
dValue := reflect.Indirect(reflect.ValueOf(data))
dType := dValue.Type()
if (dType.Kind() != reflect.Slice && dType.Kind() != reflect.Array) ||
fType.Kind() != reflect.Func || fType.NumIn() != 2 || fType.NumOut() != 1 {
panic("sort paramter type format error")
}
firstType := fType.In(0)
secondType := fType.In(1)
outType := fType.Out(0)
elemType := dType.Elem()
if elemType.Kind() != firstType.Kind() || elemType.Kind() != secondType.Kind() ||
outType.Kind() != reflect.Bool {
panic("sort elem type format error")
}
tmp := reflect.Indirect(reflect.New(elemType))
for i := 0; i < dValue.Len(); i++ {
for j := i + 1; j < dValue.Len(); j++ {
out := fValue.Call([]reflect.Value{dValue.Index(i), dValue.Index(j)})
if out[0].Bool() {
continue
}
tmp.Set(dValue.Index(i))
dValue.Index(i).Set(dValue.Index(j))
dValue.Index(j).Set(tmp)
}
}
}
func Filter(data interface{}, fun interface{}) {
fValue := reflect.ValueOf(fun)
fType := fValue.Type()
dValue := reflect.Indirect(reflect.ValueOf(data))
dType := dValue.Type()
if (dType.Kind() != reflect.Slice && dType.Kind() != reflect.Array) ||
fType.Kind() != reflect.Func || fType.NumIn() != 1 || fType.NumOut() != 1 {
panic("sort paramter type format error")
}
firstType := fType.In(0)
outType := fType.Out(0)
elemType := dType.Elem()
if elemType.Kind() != firstType.Kind() || outType.Kind() != reflect.Bool {
panic("sort elem type format error")
}
pos := 0
for i := 0; i < dValue.Len(); i++ {
out := fValue.Call([]reflect.Value{dValue.Index(i)})
if !out[0].Bool() {
continue
}
dValue.Index(pos).Set(dValue.Index(i))
pos++
}
dValue.SetLen(pos)
}
func Traverse(data interface{}, fun interface{}) {
fValue := reflect.ValueOf(fun)
fType := fValue.Type()
dValue := reflect.Indirect(reflect.ValueOf(data))
dType := dValue.Type()
if (dType.Kind() != reflect.Slice && dType.Kind() != reflect.Array) ||
fType.Kind() != reflect.Func || fType.NumIn() != 1 || fType.NumOut() != 0 {
panic("sort paramter type format error")
}
firstType := fType.In(0)
elemType := dType.Elem()
if elemType.Kind() != firstType.Kind() {
panic("sort elem type format error")
}
for i := 0; i < dValue.Len(); i++ {
fValue.Call([]reflect.Value{dValue.Index(i)})
}
}

30
encoding.go Normal file
View File

@ -0,0 +1,30 @@
package goutil
import (
"encoding/json"
"encoding/xml"
)
// EncodeJSON encode anything to json string
func EncodeJSON(v interface{}) string {
b, _ := json.Marshal(v)
return string(b)
}
// EncodeJSON encode anything to json string
func EncodeJSONIndent(v interface{}) string {
b, _ := json.MarshalIndent(v, " ", " ")
return string(b)
}
// EncodeJSON encode anything to json string
func EncodeXML(v interface{}) string {
b, _ := xml.Marshal(v)
return string(b)
}
// EncodeJSON encode anything to json string
func EncodeXMLIndent(v interface{}) string {
b, _ := xml.MarshalIndent(v, " ", " ")
return string(b)
}

19
file.go Normal file
View File

@ -0,0 +1,19 @@
package goutil
import "io/ioutil"
func FileList(dirPath string) ([]string, error) {
lis, err := ioutil.ReadDir(dirPath)
if err != nil {
return nil, err
}
fileList := make([]string, 0)
for _, f := range lis {
if f.IsDir() {
continue
}
fileList = append(fileList, f.Name())
}
return fileList, nil
}

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module github.com/smbrave/goutil
go 1.19

73
http.go Normal file
View File

@ -0,0 +1,73 @@
package goutil
import (
"bytes"
"crypto/tls"
"fmt"
"io"
"net/http"
"net/url"
"time"
)
// PostJson 请求
func HttpPost(link string, params map[string]string, json []byte) ([]byte, error) {
client := &http.Client{Timeout: 20 * time.Second}
//忽略https的证书
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
p := url.Values{}
u, _ := url.Parse(link)
if params != nil {
for k, v := range params {
p.Set(k, v)
}
}
u.RawQuery = p.Encode()
req, err := http.NewRequest("POST", u.String(), bytes.NewBuffer(json))
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
}
return io.ReadAll(resp.Body)
}
// Get 请求 link请求url
func HttpGet(link string, params map[string]string) ([]byte, error) {
client := &http.Client{Timeout: 20 * time.Second}
//忽略https的证书
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
p := url.Values{}
u, _ := url.Parse(link)
if params != nil {
for k, v := range params {
p.Set(k, v)
}
}
u.RawQuery = p.Encode()
req, err := http.NewRequest("GET", u.String(), nil)
if err != nil {
return nil, err
}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("%d:%s", resp.StatusCode, resp.Status)
}
return io.ReadAll(resp.Body)
}

20
network.go Normal file
View File

@ -0,0 +1,20 @@
package goutil
import "net"
func GetIp() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
return err.Error()
}
for _, address := range addrs {
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
return ipnet.IP.String()
}
}
}
return "none"
}

70
number.go Normal file
View File

@ -0,0 +1,70 @@
package goutil
import (
"crypto/md5"
"sync"
"sync/atomic"
"time"
)
func IsNumber(str string) bool {
for i := 0; i < len(str); i++ {
if str[i] != '-' && (str[i] < '0' || str[i] > '9') {
return false
}
}
return true
}
// ID生成规则32B secondtime + 6B sid + 6B flag + 20B autoinc, 每秒最大调用量为1048576
var auto_inc_sig uint64 = 0
var big_id_lock = new(sync.RWMutex)
func GetBigID(sid int, flag int) uint64 {
localSig := atomic.AddUint64(&auto_inc_sig, 1)
bigID := uint64(time.Now().Unix())
bigID = bigID<<20 | (localSig % (1 << 20)) //避免产生连续ID
bigID = bigID<<6 | (uint64(sid) % (1 << 6))
bigID = bigID<<6 | (uint64(flag) % (1 << 6))
return bigID
}
func ParseBigID(bigID uint64) (int, int, int64) {
flag := int(bigID % (1 << 6))
sid := int(bigID >> 6 % (1 << 6))
tiemstamp := int64(bigID >> 32)
return sid, flag, tiemstamp
}
// 取低8个字节作为digest的值
func Hash64(s string) uint64 {
sum := md5.Sum([]byte(s))
digest := uint64(0)
for i := 0; i < 8; i++ {
idx := uint64(sum[i])
digest += (idx << uint64(i*8))
}
return digest
}
// 取低8个字节作为digest的值
func Hash56(s string) uint64 {
sum := md5.Sum([]byte(s))
digest := uint64(0)
for i := 0; i < 7; i++ {
idx := uint64(sum[i])
digest += (idx << uint64(i*8))
}
return digest
}
// 取低8个字节作为digest的值
func Hash32(s string) uint32 {
sum := md5.Sum([]byte(s))
digest := uint32(0)
for i := 0; i < 4; i++ {
idx := uint32(sum[i])
digest += (idx << uint64(i*8))
}
return digest
}

77
string.go Normal file
View File

@ -0,0 +1,77 @@
package goutil
import (
"crypto/md5"
"encoding/hex"
"math/rand"
"strings"
"time"
)
func Md5(str string) string {
h := md5.New()
h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil))
}
func StrInField(key string, str string) bool {
str = strings.ReplaceAll(str, "", ",")
s1 := strings.Split(str, ",")
for _, v := range s1 {
if v == key {
return true
}
}
return false
}
func StrInSlice(key string, slice []string) bool {
if len(slice) == 0 {
return false
}
for _, v := range slice {
if v == key {
return true
}
}
return false
}
func StrInPrefix(s string, arr []string) bool {
for _, a := range arr {
if strings.HasPrefix(s, a) {
return true
}
}
return false
}
// ArrayUnique 数组去重
func StrUnique(arr []string) []string {
set := make(map[string]bool)
j := 0
for _, v := range arr {
_, ok := set[v]
if ok {
continue
}
set[v] = true
arr[j] = v
j++
}
return arr[:j]
}
// 生成随机字符串
func RandomStr(length int64) string {
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
bytes := []byte(str)
result := []byte{}
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := int64(0); i < length; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}

117
time.go Normal file
View File

@ -0,0 +1,117 @@
package goutil
import (
"fmt"
"time"
)
// 时间戳转为日期
func TimeToDate(t int64) string {
tm := time.Unix(t, 0)
return tm.Format("2006-01-02")
}
// 时间戳转为datetime格式
func TimeToDateTime(t int64) string {
tm := time.Unix(t, 0)
return tm.Format("2006-01-02 15:04:05")
}
// 日期转为时间戳
func DateTimeToTime(date string) int64 {
var LOC, _ = time.LoadLocation("Asia/Shanghai")
tim, _ := time.ParseInLocation("2006-01-02 15:04:05", date, LOC)
return tim.Unix()
}
func GetNowTime() string {
return time.Now().Format("2006-01-02 15:04:05")
}
// 获取一天开始的时间戳
func GetTodayStartTime() int64 {
now := time.Now().Unix()
return now - (now+28800)%86400
}
// 获取一周开始的时间戳
func GetWeekStartTime() int64 {
now := time.Now()
week := int(now.Weekday())
if week == 0 {
week = 7
}
t := now.AddDate(0, 0, 1-week).Unix()
return t - (t+28800)%86400
}
// 获取一月开始的时间戳
func GetMonthStartTime() int64 {
now := time.Now().AddDate(0, 0, 1-time.Now().Day()).Unix()
return now - (now+28800)%86400
}
func TimeToWeek(t int64) string {
week := time.Unix(t, 0)
switch week.Weekday() {
case time.Monday:
return "星期一"
case time.Tuesday:
return "星期二"
case time.Wednesday:
return "星期三"
case time.Thursday:
return "星期四"
case time.Friday:
return "星期五"
case time.Saturday:
return "星期六"
case time.Sunday:
return "星期天"
}
return ""
}
// 时间戳转时间提示
func TimeToTips(t int64) string {
now := time.Now().Unix()
span := now - t
result := ""
if span > 0 {
if span < 60 {
result = "刚刚"
} else if span <= 1800 {
result = fmt.Sprintf("%d分钟前", span/60)
} else if span <= 3600 {
result = "半小时前"
} else if span <= 86400 {
result = fmt.Sprintf("%d小时前", span/3600)
} else if span <= 86400*30 {
result = fmt.Sprintf("%d天前", span/(86400))
} else if span <= 86400*30*12 {
result = fmt.Sprintf("%d月前", span/(86400*30))
} else {
result = fmt.Sprintf("%d年前", span/(86400*30*12))
}
} else {
span = 0 - span
if span < 60 {
result = fmt.Sprintf("%d秒后", span)
} else if span <= 1800 {
result = fmt.Sprintf("%d分钟后", span/60)
} else if span <= 3600 {
result = "半小时后"
} else if span <= 86400 {
result = fmt.Sprintf("%d小时后", span/3600)
} else if span <= 86400*30 {
result = fmt.Sprintf("%d天后", span/(86400))
} else if span <= 86400*30*12 {
result = fmt.Sprintf("%d月后", span/(86400*30))
} else {
result = fmt.Sprintf("%d年后", span/(86400*30*12))
}
}
return result
}

77
util.go Normal file
View File

@ -0,0 +1,77 @@
package goutil
import (
"errors"
"fmt"
"reflect"
)
// format bytes number friendly
func BytesToTips(bytes uint64) string {
switch {
case bytes < 1024:
return fmt.Sprintf("%dB", bytes)
case bytes < 1024*1024:
return fmt.Sprintf("%.2fK", float64(bytes)/1024)
case bytes < 1024*1024*1024:
return fmt.Sprintf("%.2fM", float64(bytes)/1024/1024)
default:
return fmt.Sprintf("%.2fG", float64(bytes)/1024/1024/1024)
}
}
func If[T any](condition bool, trueVal, falseVal T) T {
if condition {
return trueVal
}
return falseVal
}
func CopyStruct(dst interface{}, src interface{}) {
dtype := reflect.TypeOf(dst)
stype := reflect.TypeOf(src)
if stype.Kind() != reflect.Ptr || stype.Kind() != dtype.Kind() {
panic(errors.New("src/dst must ptr"))
}
if reflect.ValueOf(dst).IsNil() || reflect.ValueOf(src).IsNil() {
panic(errors.New("src/dst is nil"))
}
dval := reflect.ValueOf(dst).Elem()
sval := reflect.ValueOf(src).Elem()
for i := 0; i < sval.NumField(); i++ {
sValue := sval.Field(i)
dValue := dval.FieldByName(sval.Type().Field(i).Name)
if sValue.IsZero() || dValue.IsValid() == false || !dValue.CanSet() {
continue
}
if sValue.Kind() != dValue.Kind() {
continue
}
switch sValue.Type().Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
dValue.SetInt(sValue.Int())
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
dValue.SetUint(sValue.Uint())
case reflect.Float32, reflect.Float64:
dValue.SetFloat(sValue.Float())
case reflect.String:
dValue.SetString(sValue.String())
case reflect.Bool:
dValue.SetBool(sValue.Bool())
case reflect.Ptr:
CopyStruct(dValue.Interface(), sValue.Interface())
}
}
}