forked from golang/hotime
375 lines
7.8 KiB
Go
375 lines
7.8 KiB
Go
|
package common
|
|||
|
|
|||
|
import (
|
|||
|
"crypto/md5"
|
|||
|
"encoding/hex"
|
|||
|
"math"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
)
|
|||
|
|
|||
|
//安全锁
|
|||
|
//func SafeMutex(tag int, f func() interface{}) interface{} {
|
|||
|
//
|
|||
|
// mutexer.Lock()
|
|||
|
// if mutex[tag] == nil {
|
|||
|
//
|
|||
|
// mutex[tag] = &sync.RWMutex{}
|
|||
|
//
|
|||
|
// }
|
|||
|
// mutexer.Unlock()
|
|||
|
//
|
|||
|
// mutex[tag].Lock()
|
|||
|
// res := f()
|
|||
|
// mutex[tag].Unlock()
|
|||
|
// return res
|
|||
|
//}
|
|||
|
|
|||
|
// StrFirstToUpper 字符串首字符大写
|
|||
|
func StrFirstToUpper(str string) string {
|
|||
|
if len(str) == 0 {
|
|||
|
return str
|
|||
|
}
|
|||
|
|
|||
|
first := Substr(str, 0, 1)
|
|||
|
other := Substr(str, 1, len(str)-1)
|
|||
|
|
|||
|
return strings.ToUpper(first) + other
|
|||
|
}
|
|||
|
|
|||
|
// 时间转字符串,第二个参数支持1-5对应显示年月日时分秒
|
|||
|
func Time2Str(t time.Time, qu ...interface{}) string {
|
|||
|
if t.Unix() < 0 {
|
|||
|
return ""
|
|||
|
}
|
|||
|
tp := 5
|
|||
|
if len(qu) != 0 {
|
|||
|
tp = (qu[0]).(int)
|
|||
|
}
|
|||
|
|
|||
|
switch tp {
|
|||
|
case 1:
|
|||
|
return t.Format("2006-01")
|
|||
|
case 2:
|
|||
|
return t.Format("2006-01-02")
|
|||
|
case 3:
|
|||
|
return t.Format("2006-01-02 15")
|
|||
|
case 4:
|
|||
|
return t.Format("2006-01-02 15:04")
|
|||
|
case 5:
|
|||
|
return t.Format("2006-01-02 15:04:05")
|
|||
|
case 12:
|
|||
|
return t.Format("01-02")
|
|||
|
case 14:
|
|||
|
return t.Format("01-02 15:04")
|
|||
|
case 15:
|
|||
|
return t.Format("01-02 15:04:05")
|
|||
|
case 34:
|
|||
|
return t.Format("15:04")
|
|||
|
case 35:
|
|||
|
return t.Format("15:04:05")
|
|||
|
}
|
|||
|
return t.Format("2006-01-02 15:04:05")
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// StrLd 相似度计算 ld compares two strings and returns the levenshtein distance between them.
|
|||
|
func StrLd(s, t string, ignoreCase bool) int {
|
|||
|
if ignoreCase {
|
|||
|
s = strings.ToLower(s)
|
|||
|
t = strings.ToLower(t)
|
|||
|
}
|
|||
|
d := make([][]int, len(s)+1)
|
|||
|
for i := range d {
|
|||
|
d[i] = make([]int, len(t)+1)
|
|||
|
}
|
|||
|
for i := range d {
|
|||
|
d[i][0] = i
|
|||
|
}
|
|||
|
for j := range d[0] {
|
|||
|
d[0][j] = j
|
|||
|
}
|
|||
|
for j := 1; j <= len(t); j++ {
|
|||
|
for i := 1; i <= len(s); i++ {
|
|||
|
if s[i-1] == t[j-1] {
|
|||
|
d[i][j] = d[i-1][j-1]
|
|||
|
} else {
|
|||
|
min := d[i-1][j]
|
|||
|
if d[i][j-1] < min {
|
|||
|
min = d[i][j-1]
|
|||
|
}
|
|||
|
if d[i-1][j-1] < min {
|
|||
|
min = d[i-1][j-1]
|
|||
|
}
|
|||
|
d[i][j] = min + 1
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
return d[len(s)][len(t)]
|
|||
|
}
|
|||
|
|
|||
|
// Substr 字符串截取
|
|||
|
func Substr(str string, start int, length int) string {
|
|||
|
rs := []rune(str)
|
|||
|
rl := len(rs)
|
|||
|
end := 0
|
|||
|
|
|||
|
if start < 0 {
|
|||
|
start = rl - 1 + start
|
|||
|
}
|
|||
|
end = start + length
|
|||
|
|
|||
|
if start > end {
|
|||
|
start, end = end, start
|
|||
|
}
|
|||
|
|
|||
|
if start < 0 {
|
|||
|
start = 0
|
|||
|
}
|
|||
|
if start > rl {
|
|||
|
start = rl
|
|||
|
}
|
|||
|
if end < 0 {
|
|||
|
end = 0
|
|||
|
}
|
|||
|
if end > rl {
|
|||
|
end = rl
|
|||
|
}
|
|||
|
|
|||
|
return string(rs[start:end])
|
|||
|
}
|
|||
|
|
|||
|
// IndexLastStr 获取最后出现字符串的下标
|
|||
|
//return 找不到返回 -1
|
|||
|
func IndexLastStr(str, sep string) int {
|
|||
|
sepSlice := []rune(sep)
|
|||
|
strSlice := []rune(str)
|
|||
|
if len(sepSlice) > len(strSlice) {
|
|||
|
return -1
|
|||
|
}
|
|||
|
|
|||
|
v := sepSlice[len(sepSlice)-1]
|
|||
|
|
|||
|
for i := len(strSlice) - 1; i >= 0; i-- {
|
|||
|
vs := strSlice[i]
|
|||
|
if v == vs {
|
|||
|
j := len(sepSlice) - 2
|
|||
|
for ; j >= 0; j-- {
|
|||
|
vj := sepSlice[j]
|
|||
|
vsj := strSlice[i-(len(sepSlice)-j-1)]
|
|||
|
if vj != vsj {
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
if j < 0 {
|
|||
|
return i - len(sepSlice) + 1
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
return -1
|
|||
|
}
|
|||
|
|
|||
|
// Md5 md5
|
|||
|
func Md5(req string) string {
|
|||
|
md5Ctx := md5.New()
|
|||
|
md5Ctx.Write([]byte(req))
|
|||
|
cipherStr := md5Ctx.Sum(nil)
|
|||
|
return hex.EncodeToString(cipherStr)
|
|||
|
}
|
|||
|
|
|||
|
// Rand 随机数
|
|||
|
func Rand(count int) int {
|
|||
|
res := Random()
|
|||
|
for i := 0; i < count; i++ {
|
|||
|
res = res * 10
|
|||
|
}
|
|||
|
return ObjToInt(res)
|
|||
|
}
|
|||
|
func Random() float64 {
|
|||
|
v := float64(0)
|
|||
|
m := float64(0.1)
|
|||
|
for i := 0; i < 15; i++ {
|
|||
|
facter := map[int]int{4: 1, 9: 1, 2: 1, 3: 1, 1: 1, 7: 1, 0: 1, 5: 1, 6: 1, 8: 1}
|
|||
|
for k, _ := range facter {
|
|||
|
|
|||
|
v = v + float64(k)*m
|
|||
|
break
|
|||
|
}
|
|||
|
m = m * 0.1
|
|||
|
}
|
|||
|
|
|||
|
return v
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
// RandX 随机数范围
|
|||
|
func RandX(small int, max int) int {
|
|||
|
res := 0
|
|||
|
//随机对象
|
|||
|
if small == max {
|
|||
|
return small
|
|||
|
}
|
|||
|
|
|||
|
for {
|
|||
|
res = ObjToInt(Random() * float64(max+1))
|
|||
|
if res >= small {
|
|||
|
break
|
|||
|
}
|
|||
|
}
|
|||
|
return res
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
////路由
|
|||
|
//func Router(ctr CtrInterface) {
|
|||
|
//
|
|||
|
// str := reflect.ValueOf(ctr).Type().String()
|
|||
|
// a := strings.IndexByte(str, '.')
|
|||
|
//
|
|||
|
// c := len(str) - len("Ctr") - 1
|
|||
|
//
|
|||
|
// app := Substr(str, 0, a) //属于哪个app
|
|||
|
// ct := Substr(str, a+1, c-a) //属于哪个控制器
|
|||
|
// var x = map[string]CtrInterface{}
|
|||
|
// if _, ok := Proj[app]; ok {
|
|||
|
// //存在APP
|
|||
|
// x = Proj[app]
|
|||
|
// } else {
|
|||
|
// x = map[string]CtrInterface{}
|
|||
|
// }
|
|||
|
// x[ct] = ctr //将控制器存入APP
|
|||
|
// // fmt.Println(c)
|
|||
|
// Proj[app] = x //将APP存入测试
|
|||
|
//}
|
|||
|
//
|
|||
|
//func RunMethodListener(test func(app []string)) {
|
|||
|
// RunMethodListenerFunc = test
|
|||
|
//}
|
|||
|
|
|||
|
//func SetDb(db *sql.DB) {
|
|||
|
// db.SetMaxOpenConns(2000)
|
|||
|
// db.SetMaxIdleConns(1000)
|
|||
|
// db.Ping()
|
|||
|
// SqlDB = &*db
|
|||
|
// GetDb()
|
|||
|
//}
|
|||
|
|
|||
|
// DeepCopyMap 复制返回数组
|
|||
|
func DeepCopyMap(value interface{}) interface{} {
|
|||
|
if valueMap, ok := value.(Map); ok {
|
|||
|
newMap := make(Map)
|
|||
|
for k, v := range valueMap {
|
|||
|
newMap[k] = DeepCopyMap(v)
|
|||
|
}
|
|||
|
|
|||
|
return newMap
|
|||
|
} else if valueSlice, ok := value.([]interface{}); ok {
|
|||
|
newSlice := make([]interface{}, len(valueSlice))
|
|||
|
for k, v := range valueSlice {
|
|||
|
newSlice[k] = DeepCopyMap(v)
|
|||
|
}
|
|||
|
|
|||
|
return newSlice
|
|||
|
} else if valueMap, ok := value.(map[string]interface{}); ok {
|
|||
|
newMap := make(map[string]interface{})
|
|||
|
for k, v := range valueMap {
|
|||
|
newMap[k] = DeepCopyMap(v)
|
|||
|
}
|
|||
|
|
|||
|
return newMap
|
|||
|
|
|||
|
} else if valueSlice, ok := value.(Slice); ok {
|
|||
|
newSlice := make(Slice, len(valueSlice))
|
|||
|
for k, v := range valueSlice {
|
|||
|
newSlice[k] = DeepCopyMap(v)
|
|||
|
}
|
|||
|
|
|||
|
return newSlice
|
|||
|
}
|
|||
|
|
|||
|
return value
|
|||
|
}
|
|||
|
|
|||
|
////获取数据库
|
|||
|
//func GetDb() (HoTimeDB, error) {
|
|||
|
// Db.DB = &*SqlDB
|
|||
|
// Db.Cached = true
|
|||
|
// return Db, nil
|
|||
|
//}
|
|||
|
|
|||
|
//初始化方法
|
|||
|
//func Init() {
|
|||
|
//
|
|||
|
// http.HandleFunc("/", PublicCore.myHandler)
|
|||
|
//
|
|||
|
// InitCache()
|
|||
|
// http.ListenAndServe(":"+Config["port"].(string), nil)
|
|||
|
//}
|
|||
|
|
|||
|
////设置Config
|
|||
|
//func SetCfg(tData Map) {
|
|||
|
// for k, v := range tData {
|
|||
|
// Config[k] = v
|
|||
|
// }
|
|||
|
//}
|
|||
|
|
|||
|
// Round 浮点数四舍五入保留小数
|
|||
|
func Round(f float64, n int) float64 {
|
|||
|
pow10_n := math.Pow10(n)
|
|||
|
return math.Trunc((f+0.5/pow10_n)*pow10_n) / pow10_n
|
|||
|
}
|
|||
|
|
|||
|
//func InitDbCache(tim int64) {
|
|||
|
// res := Db.Query("SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='" + Config.GetString("dbName") + "' AND TABLE_NAME='cached'")
|
|||
|
// if len(res) == 0 {
|
|||
|
// Db.Exec("CREATE TABLE `cached` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `ckey` varchar(60) DEFAULT NULL, `cvalue` varchar(2000) DEFAULT NULL, `time` bigint(20) DEFAULT NULL, `endtime` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=198740 DEFAULT CHARSET=utf8")
|
|||
|
// }
|
|||
|
// cacheConfig := Config.GetMap("cacheConfig").GetObj("db").(CacheConfg)
|
|||
|
// cacheConfig.Used = true
|
|||
|
// if tim != 0 {
|
|||
|
// cacheConfig.Time = tim
|
|||
|
// }
|
|||
|
// Config.GetMap("cacheConfig")["db"] = cacheConfig
|
|||
|
//}
|
|||
|
//
|
|||
|
//func Cache(key interface{}, data ...interface{}) interface{} {
|
|||
|
// cachePRI := Config["cachePRI"].([]string)
|
|||
|
// var res interface{}
|
|||
|
// for i := 0; i < len(cachePRI); i++ {
|
|||
|
// if cachePRI[i] == "ridis" && Config["cacheConfig"].(Map)["ridis"].(CacheConfg).Used {
|
|||
|
// res = CacheMemIns.Cache(ObjToStr(key), data...)
|
|||
|
// }
|
|||
|
// if cachePRI[i] == "db" && Config["cacheConfig"].(Map)["db"].(CacheConfg).Used {
|
|||
|
// res = CacheDBIns.Cache(ObjToStr(key), data...)
|
|||
|
// }
|
|||
|
// if cachePRI[i] == "memory" && Config["cacheConfig"].(Map)["memory"].(CacheConfg).Used {
|
|||
|
// res = CacheMemIns.Cache(ObjToStr(key), data...)
|
|||
|
// }
|
|||
|
// //将缓存送到前面的可缓存仓库去
|
|||
|
// if res != nil {
|
|||
|
// for j := 0; j < i; j++ {
|
|||
|
// if cachePRI[j] == "ridis" && Config["cacheConfig"].(Map)["ridis"].(CacheConfg).Used {
|
|||
|
// CacheMemIns.Cache(ObjToStr(key), res)
|
|||
|
// }
|
|||
|
// if cachePRI[j] == "db" && Config["cacheConfig"].(Map)["db"].(CacheConfg).Used {
|
|||
|
// CacheDBIns.Cache(ObjToStr(key), res)
|
|||
|
// }
|
|||
|
// if cachePRI[j] == "memory" && Config["cacheConfig"].(Map)["memory"].(CacheConfg).Used {
|
|||
|
// CacheMemIns.Cache(ObjToStr(key), res)
|
|||
|
// }
|
|||
|
//
|
|||
|
// }
|
|||
|
// break
|
|||
|
// }
|
|||
|
//
|
|||
|
// }
|
|||
|
// return res
|
|||
|
//}
|
|||
|
|
|||
|
//func InitCache() {
|
|||
|
// CacheMemIns.Init(Config["cacheConfig"].(Map)["memory"].(CacheConfg).Time)
|
|||
|
// CacheDBIns.Init(Config["cacheConfig"].(Map)["db"].(CacheConfg).Time)
|
|||
|
//}
|