add
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
// common/common.go
|
||||
package common
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ---------------------- 环境变量操作 ----------------------
|
||||
// 项目中最常用的通用能力,适配Docker容器化(环境变量传配置)
|
||||
// GetEnv 读取环境变量,若不存在则返回默认值
|
||||
func GetEnv(key, defVal string) string {
|
||||
val := os.Getenv(key)
|
||||
if val == "" {
|
||||
return defVal
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// GetEnvInt 读取环境变量并转换为int,转换失败/不存在返回默认值
|
||||
func GetEnvInt(key string, defVal int) int {
|
||||
val := os.Getenv(key)
|
||||
if val == "" {
|
||||
return defVal
|
||||
}
|
||||
num, err := strconv.Atoi(val)
|
||||
if err != nil {
|
||||
return defVal
|
||||
}
|
||||
return num
|
||||
}
|
||||
|
||||
// GetEnvBool 读取环境变量并转换为bool(支持1/0、true/false、on/off),失败/不存在返回默认值
|
||||
func GetEnvBool(key string, defVal bool) bool {
|
||||
val := strings.ToLower(os.Getenv(key))
|
||||
switch val {
|
||||
case "1", "true", "on":
|
||||
return true
|
||||
case "0", "false", "off":
|
||||
return false
|
||||
default:
|
||||
return defVal
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------- 类型转换 ----------------------
|
||||
// 日常开发中频繁的类型转换,封装后避免重复写err判断
|
||||
// StrToInt 字符串转int,失败返回0和错误
|
||||
func StrToInt(s string) (int, error) {
|
||||
return strconv.Atoi(s)
|
||||
}
|
||||
|
||||
// StrToInt64 字符串转int64,失败返回0和错误
|
||||
func StrToInt64(s string) (int64, error) {
|
||||
return strconv.ParseInt(s, 10, 64)
|
||||
}
|
||||
|
||||
// IntToStr int转字符串
|
||||
func IntToStr(i int) string {
|
||||
return strconv.Itoa(i)
|
||||
}
|
||||
|
||||
// Int64ToStr int64转字符串
|
||||
func Int64ToStr(i int64) string {
|
||||
return strconv.FormatInt(i, 10)
|
||||
}
|
||||
|
||||
// StrToFloat64 字符串转float64,失败返回0和错误
|
||||
func StrToFloat64(s string) (float64, error) {
|
||||
return strconv.ParseFloat(s, 64)
|
||||
}
|
||||
|
||||
// Float64ToStr float64转字符串,保留n位小数
|
||||
func Float64ToStr(f float64, n int) string {
|
||||
format := fmt.Sprintf("%%.%df", n)
|
||||
return fmt.Sprintf(format, f)
|
||||
}
|
||||
|
||||
// ---------------------- 时间通用处理 ----------------------
|
||||
// 统一项目时间格式,避免各业务自定义格式导致的混乱
|
||||
const (
|
||||
// TimeFormatYmdHms 常规时间格式:2006-01-02 15:04:05(Go诞生时间,固定模板)
|
||||
TimeFormatYmdHms = "2006-01-02 15:04:05"
|
||||
// TimeFormatYmd 日期格式:2006-01-02
|
||||
TimeFormatYmd = "2006-01-02"
|
||||
// TimeFormatHms 时间格式:15:04:05
|
||||
TimeFormatHms = "15:04:05"
|
||||
// TimeFormatYmdHmsS 带毫秒的时间格式:2006-01-02 15:04:05.000
|
||||
TimeFormatYmdHmsS = "2006-01-02 15:04:05.000"
|
||||
)
|
||||
|
||||
// TimeToStr 时间转字符串,指定格式(不传则用默认YmdHms)
|
||||
func TimeToStr(t time.Time, format ...string) string {
|
||||
ft := TimeFormatYmdHms
|
||||
if len(format) > 0 && format[0] != "" {
|
||||
ft = format[0]
|
||||
}
|
||||
// 转换为本地时区(避免UTC时间偏移)
|
||||
return t.In(time.Local).Format(ft)
|
||||
}
|
||||
|
||||
// NowToStr 当前时间转字符串,指定格式(不传则用默认YmdHms)
|
||||
func NowToStr(format ...string) string {
|
||||
return TimeToStr(time.Now(), format...)
|
||||
}
|
||||
|
||||
// StrToTime 字符串转时间,指定格式(不传则用默认YmdHms),失败返回零值和错误
|
||||
func StrToTime(s string, format ...string) (time.Time, error) {
|
||||
ft := TimeFormatYmdHms
|
||||
if len(format) > 0 && format[0] != "" {
|
||||
ft = format[0]
|
||||
}
|
||||
return time.ParseInLocation(ft, s, time.Local)
|
||||
}
|
||||
|
||||
// GetDayStart 获取某天的开始时间(如2026-02-06 00:00:00)
|
||||
func GetDayStart(t time.Time) time.Time {
|
||||
year, month, day := t.In(time.Local).Date()
|
||||
return time.Date(year, month, day, 0, 0, 0, 0, time.Local)
|
||||
}
|
||||
|
||||
// GetDayEnd 获取某天的结束时间(如2026-02-06 23:59:59.999999999)
|
||||
func GetDayEnd(t time.Time) time.Time {
|
||||
year, month, day := t.In(time.Local).Date()
|
||||
return time.Date(year, month, day, 23, 59, 59, 999999999, time.Local)
|
||||
}
|
||||
|
||||
// ---------------------- 空值判断 ----------------------
|
||||
// 通用的空值检查,支持所有基础类型和引用类型,避免业务层重复写if判断
|
||||
// IsEmpty 判断值是否为空(0/""//nil/空切片/空map等)
|
||||
func IsEmpty(v interface{}) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
val := reflect.ValueOf(v)
|
||||
switch val.Kind() {
|
||||
case reflect.String:
|
||||
return val.String() == ""
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return val.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return val.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return val.Float() == 0
|
||||
case reflect.Bool:
|
||||
return !val.Bool()
|
||||
case reflect.Slice, reflect.Array:
|
||||
return val.Len() == 0
|
||||
case reflect.Map, reflect.Chan:
|
||||
return val.Len() == 0 || val.IsNil()
|
||||
case reflect.Ptr, reflect.Interface:
|
||||
return val.IsNil()
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsNotEmpty 判断值是否非空,与IsEmpty相反
|
||||
func IsNotEmpty(v interface{}) bool {
|
||||
return !IsEmpty(v)
|
||||
}
|
||||
|
||||
// ---------------------- 字符串通用处理 ----------------------
|
||||
// 高频的字符串操作,封装后简化调用
|
||||
// StrTrim 去除字符串两端的空格/制表符/换行符
|
||||
func StrTrim(s string) string {
|
||||
return strings.TrimSpace(s)
|
||||
}
|
||||
|
||||
// StrToLower 字符串转小写
|
||||
func StrToLower(s string) string {
|
||||
return strings.ToLower(s)
|
||||
}
|
||||
|
||||
// StrToUpper 字符串转大写
|
||||
func StrToUpper(s string) string {
|
||||
return strings.ToUpper(s)
|
||||
}
|
||||
|
||||
// StrIsIn 判断字符串是否在指定的切片中(忽略大小写)
|
||||
func StrIsIn(s string, list []string) bool {
|
||||
s = StrToLower(s)
|
||||
for _, v := range list {
|
||||
if StrToLower(v) == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// StrJoin 拼接切片为字符串,指定分隔符
|
||||
func StrJoin(list []string, sep string) string {
|
||||
return strings.Join(list, sep)
|
||||
}
|
||||
|
||||
// ---------------------- 随机数/随机字符串 ----------------------
|
||||
// 生成随机数、随机字符串(用于生成验证码、随机密码、唯一标识等)
|
||||
// RandInt 生成[min, max]范围内的随机整数,失败返回0和错误
|
||||
func RandInt(min, max int) (int, error) {
|
||||
if min > max {
|
||||
return 0, errors.New("min is greater than max")
|
||||
}
|
||||
// 基于crypto/rand生成安全随机数(比math/rand更安全,适合生产环境)
|
||||
num, err := rand.Int(rand.Reader, big.NewInt(int64(max-min+1)))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return min + int(num.Int64()), nil
|
||||
}
|
||||
|
||||
// RandStr 生成指定长度的随机字符串(数字+大小写字母),失败返回""和错误
|
||||
func RandStr(length int) (string, error) {
|
||||
if length <= 0 {
|
||||
return "", errors.New("length must be greater than 0")
|
||||
}
|
||||
// 随机字符串源(可根据需求添加/移除字符,如去掉大写字母)
|
||||
chars := "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
charsLen := big.NewInt(int64(len(chars)))
|
||||
result := make([]byte, length)
|
||||
for i := 0; i < length; i++ {
|
||||
// 逐个生成随机字符索引
|
||||
idx, err := rand.Int(rand.Reader, charsLen)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
result[i] = chars[idx.Int64()]
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
||||
|
||||
// RandNumStr 生成指定长度的纯数字随机字符串,失败返回""和错误
|
||||
func RandNumStr(length int) (string, error) {
|
||||
if length <= 0 {
|
||||
return "", errors.New("length must be greater than 0")
|
||||
}
|
||||
nums := "0123456789"
|
||||
numsLen := big.NewInt(int64(len(nums)))
|
||||
result := make([]byte, length)
|
||||
for i := 0; i < length; i++ {
|
||||
idx, err := rand.Int(rand.Reader, numsLen)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
result[i] = nums[idx.Int64()]
|
||||
}
|
||||
return string(result), nil
|
||||
}
|
||||
|
||||
// ---------------------- 其他通用工具 ----------------------
|
||||
// GetCurrentDir 获取当前程序运行目录(适配Docker容器化,避免路径问题)
|
||||
func GetCurrentDir() (string, error) {
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get current dir failed: %w", err)
|
||||
}
|
||||
return dir, nil
|
||||
}
|
||||
|
||||
// MkdirIfNotExist 目录不存在则创建(支持多级目录),适配日志/文件存储
|
||||
func MkdirIfNotExist(path string) error {
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
// 0755:所有者读写执行,其他用户读执行,符合Linux/Docker权限规范
|
||||
if err := os.MkdirAll(path, 0755); err != nil {
|
||||
return fmt.Errorf("mkdir %s failed: %w", path, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user