package common import ( "bytes" "encoding/json" "errors" "fmt" "go_dreamfactory/lego/core" "io" "io/ioutil" "math" "os" "path/filepath" "strconv" "strings" "github.com/sirupsen/logrus" "github.com/spf13/cast" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" ) func MF(s1 core.M_Modules, s2 string) string { return fmt.Sprintf("%s.%s", s1, s2) } func FormatJson(data string) (string, error) { var out bytes.Buffer err := json.Indent(&out, []byte(data), "", " ") return out.String(), err } func SubStr(str string, start int, length int) (result string) { s := []rune(str) total := len(s) if total == 0 { return } // 允许从尾部开始计算 if start < 0 { start = total + start if start < 0 { return } } if start > total { return } // 到末尾 if length < 0 { length = total } end := start + length if end > total { result = string(s[start:]) } else { result = string(s[start:end]) } return } // 是否升级 func IsUpgrade(newVersion, oldVersion string) bool { nvArr := strings.SplitN(newVersion, ".", 3) if len(nvArr) != 3 { logrus.Error("new version format err") return false } ovArr := strings.SplitN(oldVersion, ".", 3) if len(ovArr) != 3 { logrus.Error("old version format err") return false } nvNum := cast.ToInt(nvArr[0])*100 + cast.ToInt(nvArr[1])*10 + cast.ToInt(nvArr[2]) ovNum := cast.ToInt(ovArr[0])*100 + cast.ToInt(ovArr[1])*10 + cast.ToInt(ovArr[2]) if nvNum > ovNum { return true } return false } func Copy(src, dst string) (len int64, err error) { dstWriter, err := os.Create(dst) if err != nil { logrus.Error(err) return } srcReader, err := os.Open(src) if err != nil { logrus.Error(err) return } // Copy()函数其实是调用了 // io包中私有函数copyBuffer() 默认缓冲区是32K // 与Copy()函数功能一致的是CopyBuffer()可以设置缓冲区 len, err = io.Copy(dstWriter, srcReader) if err != nil { logrus.Error(err) return } return } func DeleteFile(filePath string) error { return os.Remove(filePath) } func RemoveContents(dir string) error { d, err := os.Open(dir) if err != nil { return err } defer d.Close() names, err := d.Readdirnames(-1) if err != nil { return err } for _, name := range names { err = os.RemoveAll(filepath.Join(dir, name)) if err != nil { return err } } return nil } func ConvertFileSize(size int64) string { if size == 0 { return "0" } kb := float64(size) / float64(1024) if kb < 1024 { f := math.Ceil(kb) return strconv.Itoa(int(f)) + " KB" } mb := kb / float64(1024) if mb < 1024 { f := math.Ceil(mb) return strconv.Itoa(int(f)) + " MB" } gb := mb / float64(1024) if gb < 1024 { f := math.Ceil(mb) return strconv.Itoa(int(f)) + " G" } t := gb / float64(1024) if t < 1024 { f := math.Ceil(mb) return strconv.Itoa(int(f)) + " T" } if t >= 1024 { return "VeryBig" } return "0" } type Config struct { Path string } func (this *Config) SetPath(path string) { this.Path = path } // "F:\\projects\\workspace\\go_dreamfactory\\bin\\json" func (this *Config) Loader(file string) ([]map[string]interface{}, error) { if this.Path == "" { return nil, errors.New("no setting config path") } path := filepath.Join(this.Path, file+".json") if bytes, err := ioutil.ReadFile(path); err != nil { return nil, err } else { jsonData := make([]map[string]interface{}, 0) if err = json.Unmarshal(bytes, &jsonData); err != nil { return nil, err } return jsonData, nil } } func Json2Pb(jsonString string, pb proto.Message) error { m := pb.ProtoReflect().Interface() if err := protojson.Unmarshal([]byte(jsonString), m); err != nil { return err } return nil } func Pb2Json(pb proto.Message) string { return protojson.Format(pb.ProtoReflect().Interface()) } // 保留两位小数 通用 func FormatFloatCommon(num float64) float64 { value, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", num), 64) return value } // 保留两位小数,舍弃尾数,无进位运算 // 主要逻辑就是先乘,trunc之后再除回去,就达到了保留N位小数的效果 func FormatFloat(num float64, decimal int) (float64, error) { // 默认乘1 d := float64(1) if decimal > 0 { // 10的N次方 d = math.Pow10(decimal) } // math.trunc作用就是返回浮点数的整数部分 // 再除回去,小数点后无效的0也就不存在了 res := strconv.FormatFloat(math.Trunc(num*d)/d, 'f', -1, 64) return strconv.ParseFloat(res, 64) } // 强制舍弃尾数 func FormatFloatFloor(num float64, decimal int) (float64, error) { // 默认乘1 d := float64(1) if decimal > 0 { // 10的N次方 d = math.Pow10(decimal) } // math.trunc作用就是返回浮点数的整数部分 // 再除回去,小数点后无效的0也就不存在了 res := strconv.FormatFloat(math.Floor(num*d)/d, 'f', -1, 64) return strconv.ParseFloat(res, 64) } // 舍弃的尾数不为0,强制进位 func FormatFloatCeil(num float64, decimal int) (float64, error) { // 默认乘1 d := float64(1) if decimal > 0 { // 10的N次方 d = math.Pow10(decimal) } // math.trunc作用就是返回浮点数的整数部分 // 再除回去,小数点后无效的0也就不存在了 res := strconv.FormatFloat(math.Ceil(num*d)/d, 'f', -1, 64) return strconv.ParseFloat(res, 64) } func LastChars(str string, count int) string { if len(str) <= count { return str } return str[len(str)-count:] }