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.

664 lines
14 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package CommonUtil
import (
"bufio"
"bytes"
"crypto/md5"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
uuid "github.com/satori/go.uuid"
"io"
"log"
"math/rand"
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
"unsafe"
)
/**
功能获取UUID
作者:黄海
时间2020-02-03
*/
func GetUUID() string {
u2 := strings.ToUpper(uuid.NewV4().String())
return u2
}
/**
功能:判断是不是合法的日期格式
作者:黄海
时间2020-03-23
*/
func IsDate(date string) bool {
_, err := time.Parse("2006-01-02 15:04:05", date)
if err != nil {
return false
} else {
return true
}
}
/**
功能从一个数据库的查询返回结果中获取指定字段的IDS
作者:黄海
时间2020-02-14
*/
func SelectIdsFromMapInterface(list []map[string]interface{}, key string) []string {
var ids []string
for i := 0; i < len(list); i++ {
switch list[i][key].(type) {
case string:
ids = append(ids, list[i][key].(string))
break
case int64:
ids = append(ids, strconv.FormatInt(list[i][key].(int64), 10))
}
}
return ids
}
/**
功能:将一个数据库查询返回结果中的某一列,形成字典
作者:黄海
时间2020-02-14
*/
func PutSelectResultToMapByField(list []map[string]interface{}, field string) map[string]interface{} {
_dict := make(map[string]interface{})
for i, _ := range list {
record := list[i]
switch record[field].(type) {
case int64:
_dict[strconv.FormatInt(record[field].(int64), 10)] = 1
default:
_dict[record[field].(string)] = 1
}
}
return _dict
}
/**
功能:通过字典获取字符串数组
作者:黄海
时间2020-02-14
*/
func GetArrayByMap(_dict map[string]interface{}) []string {
Ids := make([]string, 0, len(_dict))
for k := range _dict {
Ids = append(Ids, k) //
}
return Ids
}
/**
功能:将数据库返回的查询结果映射成字典,用于扩展字段
作者:黄海
时间2020-02-14
*/
func ConvertMapInterfaceToMapByField(list []map[string]interface{}, key string, value string) map[string]string {
_map := make(map[string]string)
for i, _ := range list {
var areaTypeId string
switch list[i][key].(type) {
case int64:
areaTypeId = strconv.FormatInt(list[i][key].(int64), 10)
default:
areaTypeId = list[i][key].(string)
}
switch list[i][value].(type) {
case int64:
_map[areaTypeId] = strconv.FormatInt(list[i][value].(int64), 10)
default:
_map[areaTypeId] = list[i][value].(string)
}
}
return _map
}
/**
功能:扩展数据库查询结果集
作者:黄海
时间2020-02-14
*/
func ExtendList(list *[]map[string]interface{}, _map map[string]string, key string, value string) {
for i, _ := range *list {
sourceRecord := (*list)[i]
var a string
switch sourceRecord[key].(type) {
case int64:
a = strconv.FormatInt(sourceRecord[key].(int64), 10)
default:
a = sourceRecord[key].(string)
}
sourceRecord[value] = _map[a]
}
}
/**
功能:删除字符串多余的空格
作者:黄海
时间2020-01-20
*/
func DeleteExtraSpace(s string) string {
//删除字符串中的多余空格,有多个空格时,仅保留一个空格
s1 := strings.Replace(s, " ", " ", -1) //替换tab为空格
regstr := "\\s{2,}" //两个及两个以上空格的正则表达式
reg, _ := regexp.Compile(regstr) //编译正则表达式
s2 := make([]byte, len(s1)) //定义字符数组切片
copy(s2, s1) //将字符串复制到切片
spcIndex := reg.FindStringIndex(string(s2)) //在字符串中搜索
for len(spcIndex) > 0 { //找到适配项
s2 = append(s2[:spcIndex[0]+1], s2[spcIndex[1]:]...) //删除多余空格
spcIndex = reg.FindStringIndex(string(s2)) //继续在字符串中搜索
}
return string(s2)
}
//删除字符串中的空白行
func DeleteBlankString(str string) string {
var arr = strings.Split(str, "\r\n")
var resultStr = ""
for i := 0; i < len(arr); i++ {
if len(strings.Replace(strings.Replace(arr[i], " ", "", -1), "\t", "", -1)) > 0 {
resultStr += arr[i] + "\r\n"
}
}
return resultStr
}
//删除文件中空白行
func DeleteBlankFile(srcFilePah string, destFilePath string) error {
srcFile, err := os.OpenFile(srcFilePah, os.O_RDONLY, 0666)
defer srcFile.Close()
if err != nil {
return err
}
srcReader := bufio.NewReader(srcFile)
destFile, err := os.OpenFile(destFilePath, os.O_WRONLY|os.O_CREATE, 0666)
defer destFile.Close()
if err != nil {
return err
}
for {
str, err := srcReader.ReadString('\n')
if err != nil {
if err == io.EOF {
fmt.Print("The file end is touched.")
break
} else {
return err
}
}
if strings.HasSuffix(str, " \r\n") {
continue
}
if strings.HasPrefix(str, "\r\n") {
continue
}
fmt.Println(len(str))
fmt.Print(str)
destFile.WriteString(str)
}
return nil
}
//如果是小写字母, 则变换为大写字母
func StrFirstToUpper(str string) string {
var upperStr string
vv := []rune(str) // 后文有介绍
for i := 0; i < len(vv); i++ {
if i == 0 {
if vv[i] >= 97 && vv[i] <= 122 { // 后文有介绍
vv[i] -= 32 // string的码表相差32位
upperStr += string(vv[i])
} else {
return str
}
} else {
upperStr += string(vv[i])
}
}
return upperStr
}
//如果是大写字母, 则变换为小写字母
func StrFirstToLower(str string) string {
if len(str) < 1 {
return ""
}
strArry := []rune(str)
if strArry[0] >= 65 && strArry[0] <= 90 {
strArry[0] += 32
}
return string(strArry)
}
/**
功能:获取蛇形命名的字符串
作者:黄海
时间2020-01-22
*/
func GetSnakeCaseStr(str string) string {
array := strings.Split(str, "_")
var result string
for i := 0; i < len(array); i++ {
result = result + strings.ToUpper(array[i][0:1]) + array[i][1:]
}
return result
}
const (
// 可自定义盐值
TokenSalt = "DsideaL4r5t6y7u"
)
func MD5(data []byte) string {
_md5 := md5.New()
_md5.Write(data)
return hex.EncodeToString(_md5.Sum([]byte("")))
}
//isSymbol表示有无符号
func BytesToInt(b []byte, isSymbol bool) (int, error) {
if isSymbol {
return BytesToIntS(b)
}
return bytesToIntU(b)
}
//字节数(大端)组转成int(无符号的)
func bytesToIntU(b []byte) (int, error) {
if len(b) == 3 {
b = append([]byte{0}, b...)
}
bytesBuffer := bytes.NewBuffer(b)
switch len(b) {
case 1:
var tmp uint8
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
case 2:
var tmp uint16
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
case 4:
var tmp uint32
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
default:
return 0, fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!")
}
}
//字节数(大端)组转成int(有符号)
func BytesToIntS(b []byte) (int, error) {
if len(b) == 3 {
b = append([]byte{0}, b...)
}
bytesBuffer := bytes.NewBuffer(b)
switch len(b) {
case 1:
var tmp int8
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
case 2:
var tmp int16
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
case 4:
var tmp int32
err := binary.Read(bytesBuffer, binary.BigEndian, &tmp)
return int(tmp), err
default:
return 0, fmt.Errorf("%s", "BytesToInt bytes lenth is invaild!")
}
}
//整形转换成字节
func IntToBytes(n int, b byte) ([]byte, error) {
switch b {
case 1:
tmp := int8(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, &tmp)
return bytesBuffer.Bytes(), nil
case 2:
tmp := int16(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, &tmp)
return bytesBuffer.Bytes(), nil
case 3, 4:
tmp := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, &tmp)
return bytesBuffer.Bytes(), nil
}
return nil, fmt.Errorf("IntToBytes b param is invaild")
}
/**
功能:生成一个随机盐
作者: 黄海
时间2020-02-18
*/
func GetRandomSalt() string {
return GetRandomString(8)
}
//生成随机字符串
func GetRandomString(l int) string {
str := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
bytes := []byte(str)
var result []byte
r := rand.New(rand.NewSource(time.Now().UnixNano()))
for i := 0; i < l; i++ {
result = append(result, bytes[r.Intn(len(bytes))])
}
return string(result)
}
/**
功能:获取当前的时间戳,精确度纳秒
作者:黄海
时间2020-02-18
*/
func GetCurrentTimestamp() int64 {
return time.Now().UnixNano()
}
/**
功能:获取当前的时间字符串
作者:黄海
时间2020-02-21
*/
func GetCurrentTime() string {
timeStr := time.Now().Format("2006-01-02 15:04:05")
//当前时间的字符串2006-01-02 15:04:05据说是golang的诞生时间固定写法
return timeStr
}
/**
功能将Json格式的字符串转为map
作者:吴缤
日期2020-02-21
*/
func JsonStrToMap(jsonStr string) (map[string]interface{}, error) {
var _map map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &_map)
if err == nil {
if _map["code"] != nil {
var _code = int(_map["code"].(float64))
_map["code"] = _code
}
return _map, nil
} else {
return nil, err
}
}
/*
功能返回当前GO文件所在的目录
*/
func GetCurrentDirectory() string {
directory, _ := os.Getwd()
return directory
}
// 判断所给路径文件/文件夹是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
/**
功能将int数据类型转为int64
作者:黄海
时间2020-02-18
*/
func ConvertIntToInt64(i int) int64 {
s := strconv.Itoa(i)
s64, _ := strconv.ParseInt(s, 10, 64)
return s64
}
/**
功能:将字符串转为整数
作者:黄海
时间2020-04-17
*/
func ConvertStringToInt(s string) int {
i, _ := strconv.Atoi(s)
return i
}
/**
功能将字符串转为int32整数
作者:黄海
时间2020-04-17
*/
func ConvertStringToInt32(s string) int32 {
i, _ := strconv.Atoi(s)
return int32(i)
}
/**
功能将字符串转为整数64
作者:黄海
时间2020-04-17
*/
func ConvertStringToInt64(s string) int64 {
i, _ := strconv.ParseInt(s, 10, 64)
return i
}
/**
功能:将整数转为字符串
作者:黄海
时间2020-04-17
*/
func ConvertIntToString(i int) string {
s := strconv.Itoa(i)
return s
}
/**
功能将整数64转为字符串
作者:黄海
时间2020-04-17
*/
func ConvertInt64ToString(i int64) string {
s := strconv.FormatInt(i, 10)
return s
}
/**
功能将int64转为int
作者:黄海
时间2020-04-23
*/
func ConvertInt64ToInt(int64Num int64) int {
// 将 int64 转化为 int
intNum := *(*int)(unsafe.Pointer(&int64Num))
return intNum
}
/**
功能将JSON字符串转化为map数组
作者: 黄海
时间2020-04-17
*/
func ConvertJsonStringToMapArray(data string) []map[string]interface{} {
var m = make([]map[string]interface{}, 0)
str := []byte(data)
json.Unmarshal(str, &m)
return m
}
/**
功能:判断目录是否存在
*/
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
}
//获取文件修改时间 返回unix时间戳
func GetFileModTime(path string) int64 {
f, err := os.Open(path)
if err != nil {
log.Println("open file error")
return time.Now().Unix()
}
defer f.Close()
fi, err := f.Stat()
if err != nil {
log.Println("stat fileinfo error")
return time.Now().Unix()
}
return fi.ModTime().Unix()
}
//自己编写一个函数,接收两个文件路径 srcFileName dstFileName
func CopyFile(srcFileName string, dstFileName string) (written int64, err error) {
srcFile, err := os.Open(srcFileName)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer srcFile.Close()
//打开dstFileName
dstFile, err := os.OpenFile(dstFileName, os.O_WRONLY|os.O_CREATE, 0755)
if err != nil {
fmt.Printf("open file err = %v\n", err)
return
}
defer dstFile.Close()
return io.Copy(dstFile, srcFile)
}
/**
功能:将在系统中使用的类列表(比如:BasePerson)还原为数据库中的表名:t_base_person
作者:黄海
时间2020-05-30
*/
func ConvertTrueTableName(tableName string) string {
var result = "t"
for _, char := range []rune(tableName) {
if int(char) >= 65 && int(char) <= 90 {
result += "_" + strings.ToLower(string(char))
} else {
result += string(char)
}
}
return result
}
/**
功能带回显的执行DOS命令
作者:黄海
时间2020-05-18
*/
func Exec(name string, args ...string) error {
cmd := exec.Command(name, args...)
stderr, _ := cmd.StderrPipe()
stdout, _ := cmd.StdoutPipe()
if err := cmd.Start(); err != nil {
log.Println("exec the cmd ", name, " failed")
return err
}
// 正常日志
logScan := bufio.NewScanner(stdout)
go func() {
for logScan.Scan() {
log.Println(logScan.Text())
}
}()
// 错误日志
errBuf := bytes.NewBufferString("")
scan := bufio.NewScanner(stderr)
for scan.Scan() {
s := scan.Text()
log.Println("", s)
errBuf.WriteString(s)
errBuf.WriteString("\n")
}
// 等待命令执行完
cmd.Wait()
if !cmd.ProcessState.Success() {
// 执行失败,返回错误信息
return errors.New(errBuf.String())
}
return nil
}
/**
功能:数组中是否存在某个字符串
作者:黄海
时间2020-05-30
*/
func IsContainString(items []string, item string) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
func IsContainInt32(items []int32, item int32) bool {
for _, eachItem := range items {
if eachItem == item {
return true
}
}
return false
}
/**
功能:获取当前路径
作者:黄海
时间2020-06-02
*/
func GetCurrentPath() string {
dir, _ := os.Getwd()
dir = strings.ReplaceAll(dir, "\\", "/")
return dir
}
/**
功能:获取当前工作目录的父路径
作者:黄海
时间2020-06-02
*/
func GetCurrentParentPath()string{
return GetParentPath(GetCurrentPath())
}
/**
功能:返回上一级目录
*/
func GetParentPath(directory string) string {
return strings.Replace(filepath.Dir(directory), "\\", "/", -1)
}