From 0d6f8a8cec1db0ed52524dda18c83f5acd8e09d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 14 May 2022 13:45:51 +0800 Subject: [PATCH] =?UTF-8?q?=E6=90=AC=E8=BF=81=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 22 ++++++ cli.go | 46 ++++++++++++ file.go | 87 ++++++++++++++++++++++ go.mod | 3 + hash.go | 32 ++++++++ ip.go | 53 ++++++++++++++ json.go | 91 +++++++++++++++++++++++ map.go | 209 +++++++++++++++++++++++++++++++++++++++++++++++++++++ string.go | 82 +++++++++++++++++++++ struct.go | 30 ++++++++ time.go | 19 +++++ url.go | 89 +++++++++++++++++++++++ 12 files changed, 763 insertions(+) create mode 100644 .gitignore create mode 100644 cli.go create mode 100644 file.go create mode 100644 go.mod create mode 100644 hash.go create mode 100644 ip.go create mode 100644 json.go create mode 100644 map.go create mode 100644 string.go create mode 100644 struct.go create mode 100644 time.go create mode 100644 url.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df8e306 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# Created by .ignore support plugin (hsz.mobi) +### Go template +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib +*.xlsx + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ +.idea +.vscode +mail_test.go + diff --git a/cli.go b/cli.go new file mode 100644 index 0000000..905939e --- /dev/null +++ b/cli.go @@ -0,0 +1,46 @@ +// Package util ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 1:53 下午 2021/8/14 +package util + +import "flag" + +// ParseCLIParameter 解析命令含参数 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 1:54 下午 2021/8/14 +func ParseCLIParameter(parameterNameList []string) map[string]string { + cliParameterTable := make(map[string]*string) + for _, parameterName := range parameterNameList { + cliParameterTable[parameterName] = flag.String(parameterName, "", parameterName) + } + // 这里有一个非常中的操作,转换,必须调用该方法 + flag.Parse() + formatTable := make(map[string]string) + for k, v := range cliParameterTable { + formatTable[k] = *v + } + return formatTable +} + +// ParseCLIParameterWithDefaultValue 解析命令行参数,并提供可选的默认值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 1:55 下午 2021/8/14 +func ParseCLIParameterWithDefaultValue(parameterParseTable map[string]string) map[string]string { + cliParameterTable := make(map[string]*string) + for parameterName, defaultValue := range parameterParseTable { + cliParameterTable[parameterName] = flag.String(parameterName, defaultValue, parameterName) + } + // 这里有一个非常中的操作,转换,必须调用该方法 + flag.Parse() + formatTable := make(map[string]string) + for k, v := range cliParameterTable { + formatTable[k] = *v + } + return formatTable +} diff --git a/file.go b/file.go new file mode 100644 index 0000000..c7b00df --- /dev/null +++ b/file.go @@ -0,0 +1,87 @@ +// Package util... +// +// Description : 文件相关工具 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-04-26 6:00 下午 +package util + +import ( + "io/ioutil" + "os" + "strings" + + "github.com/pkg/errors" + yml "gopkg.in/yaml.v2" +) + +// GetProjectPath 获取项目路径(可执行文件所在目录) +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:32 下午 2021/4/26 +func GetProjectPath() (string, error) { + rootPath, err := os.Getwd() + if nil != err { + return "", err + } + pathArr := strings.Split(rootPath, "/") + if len(pathArr) > 0 { + if pathArr[len(pathArr)-1] == "test" { + rootPath = strings.Join(pathArr[0:len(pathArr)-1], "/") + } + } + return rootPath, nil +} + +// ReadYmlConfig 读取yml配置问价,并解析到指定的结构体中 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:35 下午 2021/4/26 +func ReadYmlConfig(filePath string, result interface{}) error { + if nil == result { + return errors.New("接收读取结果的数据指针为NIL") + } + var ( + fileContent []byte + err error + ) + if fileContent, err = ReadFileContent(filePath); nil != err { + return err + } + return yml.Unmarshal(fileContent, result) +} + +// ReadFileContent 读取文件内容 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:37 下午 2021/4/26 +func ReadFileContent(filePath string) ([]byte, error) { + if exist, isFile := IsFileExist(filePath); !exist || !isFile { + //文件不存在或者是一个目录 + return nil, errors.New(filePath + " 文件不存在或者是一个目录!") + } + //打开文件 + var ( + f *os.File + err error + ) + if f, err = os.Open(filePath); nil != err { + return nil, err + } + + return ioutil.ReadAll(f) +} + +// IsFileExist 判断文件是否存在 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 10:37 下午 2021/4/26 +func IsFileExist(filePath string) (bool, bool) { + f, err := os.Stat(filePath) + return nil == err || os.IsExist(err), (nil == err || os.IsExist(err)) && !f.IsDir() +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..104d923 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.zhangdeman.cn/zhangdeman/util + +go 1.17 diff --git a/hash.go b/hash.go new file mode 100644 index 0000000..9d10327 --- /dev/null +++ b/hash.go @@ -0,0 +1,32 @@ +// Package util... +// +// Description : util... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-02-24 11:04 下午 +package util + +import ( + "fmt" + + "github.com/spaolacci/murmur3" +) + +// GetHashID ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:04 下午 2021/2/24 +func GetHashID(key interface{}) uint64 { + return murmur3.Sum64([]byte(fmt.Sprintf("%v", key))) +} + +// GetHashIDMod 获取hashID并取模 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:07 下午 2021/2/24 +func GetHashIDMod(key interface{}, shard int) int { + return int(GetHashID(key) % uint64(shard)) +} diff --git a/ip.go b/ip.go new file mode 100644 index 0000000..9ae7966 --- /dev/null +++ b/ip.go @@ -0,0 +1,53 @@ +// Package util... +// +// Description : util... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-03-09 5:56 下午 +package util + +import ( + "net" + "net/http" +) + +// GetHostIP 获取本机IP地址 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:58 下午 2021/3/9 +func GetHostIP() string { + hostIP := "127.0.0.1" + addrs, _ := net.InterfaceAddrs() + for _, address := range addrs { + if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { + if ipnet.IP.To4() != nil { + hostIP = ipnet.IP.String() + break + } + } + } + return hostIP +} + +// GetRemoteIp 获取远端IP +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:35 下午 2021/11/22 +func GetRemoteIp(req *http.Request) string { + + // Try via request + + ip, _, err := net.SplitHostPort(req.RemoteAddr) + + if err != nil { + return "::1" + } + userIP := net.ParseIP(ip) + if userIP == nil { + return "::1" + } + return userIP.String() +} diff --git a/json.go b/json.go new file mode 100644 index 0000000..610f916 --- /dev/null +++ b/json.go @@ -0,0 +1,91 @@ +// Package util... +// +// Description : json 工具函数 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-09-14 8:38 下午 +package util + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "os" + "reflect" +) + +// JSONUnmarshalWithNumber 解析json +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 8:39 下午 2021/9/14 +func JSONUnmarshalWithNumber(byteData []byte, receiver interface{}) error { + decoder := json.NewDecoder(bytes.NewReader(byteData)) + decoder.UseNumber() + return decoder.Decode(receiver) +} + +// JSONUnmarshalWithNumberForIOReader ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 8:43 下午 2021/9/14 +func JSONUnmarshalWithNumberForIOReader(ioReader io.ReadCloser, receiver interface{}) error { + decoder := json.NewDecoder(ioReader) + decoder.UseNumber() + return decoder.Decode(receiver) +} + +// JSONConsoleOutput ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:45 下午 2021/11/5 +func JSONConsoleOutput(data interface{}) { + var out bytes.Buffer + switch reflect.TypeOf(data).Kind() { + case reflect.Slice: + fallthrough + case reflect.Array: + fallthrough + case reflect.Map: + fallthrough + case reflect.Ptr: + byteData, _ := json.Marshal(data) + _ = json.Indent(&out, []byte(string(byteData)+"\n"), "", "\t") + _, _ = out.WriteTo(os.Stdout) + return + case reflect.Int: + fallthrough + case reflect.Int8: + fallthrough + case reflect.Int16: + fallthrough + case reflect.Int32: + fallthrough + case reflect.Int64: + fallthrough + case reflect.Uint: + fallthrough + case reflect.Uint8: + fallthrough + case reflect.Uint16: + fallthrough + case reflect.Uint32: + fallthrough + case reflect.Uint64: + fallthrough + case reflect.Float32: + fallthrough + case reflect.Float64: + fallthrough + case reflect.String: + _ = json.Indent(&out, []byte(fmt.Sprintf("%v\n", data)), "", "\t") + _, _ = out.WriteTo(os.Stdout) + return + default: + fmt.Println("") + } +} diff --git a/map.go b/map.go new file mode 100644 index 0000000..88cd1fc --- /dev/null +++ b/map.go @@ -0,0 +1,209 @@ +// Package util ... +// +// Description : 从map中读取数据 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-16 4:28 下午 +package util + +import ( + "git.zhangdeman.cn/zhangdeman/gopkg/convert" + "github.com/pkg/errors" +) + +// Exist 检测一个key在map中是否存在 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:52 下午 2021/11/16 +func Exist(source map[interface{}]interface{}, key interface{}) bool { + if nil == source { + return false + } + if _, exist := source[key]; !exist { + return false + } + return true +} + +// GetInt 获取int值 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:30 下午 2021/11/16 +func GetInt(source map[interface{}]interface{}, key interface{}, defaultVal int) int { + var result int + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetInt8 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:59 下午 2021/11/16 +func GetInt8(source map[interface{}]interface{}, key interface{}, defaultVal int8) int8 { + var result int8 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetInt16 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:59 下午 2021/11/16 +func GetInt16(source map[interface{}]interface{}, key interface{}, defaultVal int16) int16 { + var result int16 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetInt32 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:00 下午 2021/11/16 +func GetInt32(source map[interface{}]interface{}, key interface{}, defaultVal int32) int32 { + var result int32 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetInt64 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:00 下午 2021/11/16 +func GetInt64(source map[interface{}]interface{}, key interface{}, defaultVal int64) int64 { + var result int64 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetUint ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:01 下午 2021/11/16 +func GetUint(source map[interface{}]interface{}, key interface{}, defaultVal uint) uint { + var result uint + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetUint8 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:01 下午 2021/11/16 +func GetUint8(source map[interface{}]interface{}, key interface{}, defaultVal uint8) uint8 { + var result uint8 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetUint16 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:02 下午 2021/11/16 +func GetUint16(source map[interface{}]interface{}, key interface{}, defaultVal uint16) uint16 { + var result uint16 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetUint32 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:02 下午 2021/11/16 +func GetUint32(source map[interface{}]interface{}, key interface{}, defaultVal uint32) uint32 { + var result uint32 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetUint64 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:03 下午 2021/11/16 +func GetUint64(source map[interface{}]interface{}, key interface{}, defaultVal uint64) uint64 { + var result uint64 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetFloat32 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:03 下午 2021/11/16 +func GetFloat32(source map[interface{}]interface{}, key interface{}, defaultVal float32) float32 { + var result float32 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetFloat64 ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:04 下午 2021/11/16 +func GetFloat64(source map[interface{}]interface{}, key interface{}, defaultVal float64) float64 { + var result float64 + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetString ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 5:07 下午 2021/11/16 +func GetString(source map[interface{}]interface{}, key interface{}, defaultVal string) string { + var result string + if err := GetDataWithReceiver(source, key, &result); nil != err { + return defaultVal + } + return result +} + +// GetDataWithReceiver 使用制定的数据指针接受结果 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:54 下午 2021/11/16 +func GetDataWithReceiver(source map[interface{}]interface{}, key interface{}, receiver interface{}) error { + if !Exist(source, key) { + return errors.New("key is not found") + } + return convert.ConvertAssign(receiver, source[key]) +} diff --git a/string.go b/string.go new file mode 100644 index 0000000..03c8473 --- /dev/null +++ b/string.go @@ -0,0 +1,82 @@ +// Package util... +// +// Description : 字符串相关的工具 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-03-09 6:00 下午 +package util + +import ( + "crypto/md5" + "encoding/hex" + "math/rand" + "strings" + "time" +) + +// GenRandomString 获取随机长度的字符串 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 6:01 下午 2021/3/9 +func GenRandomString(source string, length uint) string { + if length == 0 { + return "" + } + if len(source) == 0 { + //字符串为空,默认字符源为如下(去除易混淆的i/l): + source = "0123456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNOPQRSTUVWXYZ" + } + strByte := []byte(source) + var genStrByte = make([]byte, 0) + r := rand.New(rand.NewSource(time.Now().UnixNano())) + for i := 0; i < int(length); i++ { + genStrByte = append(genStrByte, strByte[r.Intn(len(strByte))]) + } + return string(genStrByte) +} + +// Md5 对字符串进行md5加密 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 6:01 下午 2021/3/9 +func Md5(str string) string { + h := md5.New() + _, _ = h.Write([]byte(str)) + return hex.EncodeToString(h.Sum(nil)) +} + +// SnakeCaseToCamel 蛇形字符串转换为驼峰 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:58 下午 2021/10/25 +func SnakeCaseToCamel(str string) string { + if len(str) == 0 { + return "" + } + builder := strings.Builder{} + index := 0 + if str[0] >= 'a' && str[0] <= 'z' { + builder.WriteByte(str[0] - ('a' - 'A')) + index = 1 + } + for i := index; i < len(str); i++ { + if str[i] == '_' && i+1 < len(str) { + if str[i+1] >= 'a' && str[i+1] <= 'z' { + builder.WriteByte(str[i+1] - ('a' - 'A')) + i++ + continue + } + } + // 将ID转为大写 + if str[i] == 'd' && i-1 >= 0 && (str[i-1] == 'i' || str[i-1] == 'I') && (i+1 == len(str) || i+1 < len(str) && str[i+1] == '_') { + builder.WriteByte('d' - ('a' - 'A')) + continue + } + builder.WriteByte(str[i]) + } + return builder.String() +} diff --git a/struct.go b/struct.go new file mode 100644 index 0000000..0e200af --- /dev/null +++ b/struct.go @@ -0,0 +1,30 @@ +// Package util... +// +// Description : util ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-03-14 11:11 下午 +package util + +import "encoding/json" + +// StructToMap 结构体转为map +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:12 下午 2021/3/14 +func StructToMap(data interface{}) (map[string]interface{}, error) { + var ( + byteData []byte + err error + result map[string]interface{} + ) + if byteData, err = json.Marshal(data); nil != err { + return nil, err + } + if err = json.Unmarshal(byteData, &result); nil != err { + return nil, err + } + return result, nil +} diff --git a/time.go b/time.go new file mode 100644 index 0000000..89c7752 --- /dev/null +++ b/time.go @@ -0,0 +1,19 @@ +// Package util ... +// +// Description : 时间相关操作 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-10-07 1:33 上午 +package util + +import "time" + +// GetCurrentFormatTime 获取当前时间的格式化时间(秒) +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 1:34 上午 2021/10/7 +func GetCurrentFormatTime() string { + return time.Now().Format("2006-01-02 15:04:05") +} diff --git a/url.go b/url.go new file mode 100644 index 0000000..74ef78e --- /dev/null +++ b/url.go @@ -0,0 +1,89 @@ +// Package util... +// +// Description : util... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-04 2:38 下午 +package util + +import ( + "net/url" + "strings" +) + +// URLParseResult url解析 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:51 下午 2021/11/4 +type URLParseResult struct { + Scheme string `json:"scheme"` + Domain string `json:"domain"` + URI string `json:"uri"` + Parameter map[string]string `json:"parameter"` +} + +// URLEncode ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:39 下午 2021/11/4 +func URLEncode(inputURL string) string { + return url.QueryEscape(inputURL) +} + +// URLDecode ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:39 下午 2021/11/4 +func URLDecode(inputURL string) (string, error) { + return url.QueryUnescape(inputURL) +} + +// URLParse url解析 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:39 下午 2021/11/4 +func URLParse(inputURL string) (*URLParseResult, error) { + var ( + parseResult *url.URL + err error + ) + if parseResult, err = url.Parse(inputURL); nil != err { + return nil, err + } + detail := &URLParseResult{ + Scheme: parseResult.Scheme, + Domain: parseResult.Host, + URI: parseResult.Path, + Parameter: make(map[string]string), + } + for k, v := range parseResult.Query() { + if len(v) > 1 { + detail.Parameter[k] = "[" + strings.Join(v, ",") + "]" + } else { + detail.Parameter[k] = v[0] + } + } + return detail, nil +} + +// BuildQueryURL 构建GET链接 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:43 下午 2021/11/4 +func BuildQueryURL(apiURL string, parameter map[string]string) string { + u := url.Values{} + for k, v := range parameter { + u.Set(k, v) + } + apiURL = strings.Trim(apiURL, "?") + if strings.Contains(apiURL, "?") { + return apiURL + "&" + u.Encode() + } + return apiURL + "?" + u.Encode() +}