commit 0d6f8a8cec1db0ed52524dda18c83f5acd8e09d1 Author: 白茶清欢 Date: Sat May 14 13:45:51 2022 +0800 搬迁代码 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() +}