common.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  1. package util
  2. import (
  3. "crypto/md5"
  4. cryptoRand "crypto/rand"
  5. "encoding/hex"
  6. "encoding/json"
  7. "encoding/xml"
  8. "fmt"
  9. "io"
  10. "log"
  11. "math"
  12. "math/big"
  13. mathRand "math/rand"
  14. "reflect"
  15. "regexp"
  16. "runtime"
  17. "sort"
  18. "strconv"
  19. "strings"
  20. "time"
  21. )
  22. const (
  23. tmp = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12345678900"
  24. )
  25. func Uuid(length int) string {
  26. ret := []string{}
  27. r := mathRand.New(mathRand.NewSource(time.Now().UnixNano()))
  28. for i := 0; i < length; i++ {
  29. index := r.Intn(62)
  30. ret = append(ret, tmp[index:index+1])
  31. }
  32. return strings.Join(ret, "")
  33. }
  34. // 计算字符串和值
  35. func Sumstring(code string) (sum int) {
  36. tmp := []rune(code)
  37. for _, v := range tmp {
  38. sum = sum + int(v)
  39. }
  40. return
  41. }
  42. // 获取复杂的随机数
  43. func GetLetterRandom(length int, flag ...bool) string {
  44. var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
  45. var mod byte = 52
  46. if len(flag) > 0 && flag[0] {
  47. idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
  48. mod = 26
  49. }
  50. b := make([]byte, length)
  51. maxrb := byte(256 - (256 % int(mod)))
  52. i := 0
  53. EXIT:
  54. for {
  55. r := make([]byte, length+(length/4))
  56. if _, err := io.ReadFull(cryptoRand.Reader, r); err != nil {
  57. panic("captcha: error reading random source: " + err.Error())
  58. }
  59. for _, c := range r {
  60. if c > maxrb {
  61. continue
  62. }
  63. b[i] = c % mod
  64. i++
  65. if i == length {
  66. break EXIT
  67. }
  68. }
  69. }
  70. for i, c := range b {
  71. b[i] = idChars[c]
  72. }
  73. return string(b)
  74. }
  75. /*隐藏部分账号
  76. *返回手机号:150...70765 邮箱:...shenjun@vip.qq.com
  77. */
  78. func EncryCode(value string) string {
  79. if len(value) == 0 {
  80. return value
  81. } else if strings.Contains(value, "@") {
  82. start := strings.Index(value, "@") / 2
  83. if start == 0 {
  84. start++
  85. }
  86. value = "...." + string(value[start:])
  87. } else {
  88. value = string(value[0:3]) + "..." + string(value[len(value)-4:])
  89. }
  90. return value
  91. }
  92. // 生成32位md5字串
  93. func GetMd5String(s string) string {
  94. h := md5.New()
  95. h.Write([]byte(s))
  96. return hex.EncodeToString(h.Sum(nil))
  97. }
  98. // obj(string,M)转M,查询用到
  99. func ObjToMap(obj interface{}) *map[string]interface{} {
  100. data := make(map[string]interface{})
  101. if s, ok := obj.(string); ok {
  102. json.Unmarshal([]byte(strings.Replace(s, "'", "\"", -1)), &data)
  103. } else if s1, ok1 := obj.(map[string]interface{}); ok1 {
  104. data = s1
  105. } else if s1, ok1 := obj.(*map[string]interface{}); ok1 {
  106. return s1
  107. } else {
  108. data = nil
  109. }
  110. return &data
  111. }
  112. /*UTC类型时间转字符串
  113. *flag==true,日期格式yyyy-mm-dd hh:mm:ss
  114. *flag==false,日期格式yyyy-mm-dd
  115. */
  116. func LongToDate(date interface{}, flag bool) string {
  117. var int64Date int64
  118. if l1, ok1 := date.(float64); ok1 {
  119. int64Date = int64(l1)
  120. } else if l2, ok2 := date.(int64); ok2 {
  121. int64Date = l2
  122. } else if l3, ok3 := date.(int); ok3 {
  123. int64Date = int64(l3)
  124. }
  125. t := time.Unix(int64Date, 0)
  126. if flag {
  127. return t.Format("2006-01-02 15:04:05")
  128. } else {
  129. return t.Format("2006-01-02")
  130. }
  131. }
  132. func IntAll(num interface{}) int {
  133. return IntAllDef(num, 0)
  134. }
  135. func Int64All(num interface{}) int64 {
  136. if i, ok := num.(int64); ok {
  137. return int64(i)
  138. } else if i0, ok0 := num.(int32); ok0 {
  139. return int64(i0)
  140. } else if i1, ok1 := num.(float64); ok1 {
  141. return int64(i1)
  142. } else if i2, ok2 := num.(int); ok2 {
  143. return int64(i2)
  144. } else if i3, ok3 := num.(float32); ok3 {
  145. return int64(i3)
  146. } else if i4, ok4 := num.(string); ok4 {
  147. i64, _ := strconv.ParseInt(i4, 10, 64)
  148. //in, _ := strconv.Atoi(i4)
  149. return i64
  150. } else if i5, ok5 := num.(int16); ok5 {
  151. return int64(i5)
  152. } else if i6, ok6 := num.(int8); ok6 {
  153. return int64(i6)
  154. } else if i7, ok7 := num.(*big.Int); ok7 {
  155. in, _ := strconv.ParseInt(fmt.Sprint(i7), 10, 64)
  156. return int64(in)
  157. } else if i8, ok8 := num.(*big.Float); ok8 {
  158. in, _ := strconv.ParseInt(fmt.Sprint(i8), 10, 64)
  159. return int64(in)
  160. } else {
  161. return 0
  162. }
  163. }
  164. func Float64All(num interface{}) float64 {
  165. if i, ok := num.(float64); ok {
  166. return float64(i)
  167. } else if i0, ok0 := num.(int32); ok0 {
  168. return float64(i0)
  169. } else if i1, ok1 := num.(int64); ok1 {
  170. return float64(i1)
  171. } else if i2, ok2 := num.(int); ok2 {
  172. return float64(i2)
  173. } else if i3, ok3 := num.(float32); ok3 {
  174. return float64(i3)
  175. } else if i4, ok4 := num.(string); ok4 {
  176. in, _ := strconv.ParseFloat(i4, 64)
  177. return in
  178. } else if i5, ok5 := num.(int16); ok5 {
  179. return float64(i5)
  180. } else if i6, ok6 := num.(int8); ok6 {
  181. return float64(i6)
  182. } else if i6, ok6 := num.(uint); ok6 {
  183. return float64(i6)
  184. } else if i6, ok6 := num.(uint8); ok6 {
  185. return float64(i6)
  186. } else if i6, ok6 := num.(uint16); ok6 {
  187. return float64(i6)
  188. } else if i6, ok6 := num.(uint32); ok6 {
  189. return float64(i6)
  190. } else if i6, ok6 := num.(uint64); ok6 {
  191. return float64(i6)
  192. } else if i7, ok7 := num.(*big.Float); ok7 {
  193. in, _ := strconv.ParseFloat(fmt.Sprint(i7), 64)
  194. return float64(in)
  195. } else if i8, ok8 := num.(*big.Int); ok8 {
  196. in, _ := strconv.ParseFloat(fmt.Sprint(i8), 64)
  197. return float64(in)
  198. } else {
  199. return 0
  200. }
  201. }
  202. func IntAllDef(num interface{}, defaultNum int) int {
  203. if i, ok := num.(int); ok {
  204. return int(i)
  205. } else if i0, ok0 := num.(int32); ok0 {
  206. return int(i0)
  207. } else if i1, ok1 := num.(float64); ok1 {
  208. return int(i1)
  209. } else if i2, ok2 := num.(int64); ok2 {
  210. return int(i2)
  211. } else if i3, ok3 := num.(float32); ok3 {
  212. return int(i3)
  213. } else if i4, ok4 := num.(string); ok4 {
  214. in, _ := strconv.Atoi(i4)
  215. return int(in)
  216. } else if i5, ok5 := num.(int16); ok5 {
  217. return int(i5)
  218. } else if i6, ok6 := num.(int8); ok6 {
  219. return int(i6)
  220. } else if i7, ok7 := num.(*big.Int); ok7 {
  221. in, _ := strconv.Atoi(fmt.Sprint(i7))
  222. return int(in)
  223. } else if i8, ok8 := num.(*big.Float); ok8 {
  224. in, _ := strconv.Atoi(fmt.Sprint(i8))
  225. return int(in)
  226. } else {
  227. return defaultNum
  228. }
  229. }
  230. func ObjToString(old interface{}) string {
  231. if nil == old {
  232. return ""
  233. } else {
  234. r, _ := old.(string)
  235. return r
  236. }
  237. }
  238. func ObjToStringDef(old interface{}, defaultstr string) string {
  239. if nil == old {
  240. return defaultstr
  241. } else {
  242. r, _ := old.(string)
  243. if r == "" {
  244. return defaultstr
  245. }
  246. return r
  247. }
  248. }
  249. // 对象数组转成string数组
  250. func ObjArrToStringArr(old []interface{}) []string {
  251. if old != nil {
  252. new := make([]string, len(old))
  253. for i, v := range old {
  254. new[i], _ = v.(string)
  255. }
  256. return new
  257. } else {
  258. return nil
  259. }
  260. }
  261. // 对象数组转成map数组
  262. func ObjArrToMapArr(old []interface{}) []map[string]interface{} {
  263. if old != nil {
  264. new := make([]map[string]interface{}, len(old))
  265. for i, v := range old {
  266. new[i], _ = v.(map[string]interface{})
  267. }
  268. return new
  269. } else {
  270. return nil
  271. }
  272. }
  273. // map数组转成对象数组
  274. func MapArrToObjArr(old []map[string]interface{}) []interface{} {
  275. if old != nil {
  276. new := make([]interface{}, len(old))
  277. for i, v := range old {
  278. new[i] = v
  279. }
  280. return new
  281. } else {
  282. return nil
  283. }
  284. }
  285. func SubstrByByte(str string, length int) string {
  286. bs := []byte(str)[:length]
  287. bl := 0
  288. for i := len(bs) - 1; i >= 0; i-- {
  289. switch {
  290. case bs[i] >= 0 && bs[i] <= 127:
  291. return string(bs[:i+1])
  292. case bs[i] >= 128 && bs[i] <= 191:
  293. bl++
  294. case bs[i] >= 192 && bs[i] <= 253:
  295. cl := 0
  296. switch {
  297. case bs[i]&252 == 252:
  298. cl = 6
  299. case bs[i]&248 == 248:
  300. cl = 5
  301. case bs[i]&240 == 240:
  302. cl = 4
  303. case bs[i]&224 == 224:
  304. cl = 3
  305. default:
  306. cl = 2
  307. }
  308. if bl+1 == cl {
  309. return string(bs[:i+cl])
  310. }
  311. return string(bs[:i])
  312. }
  313. }
  314. return ""
  315. }
  316. func SubString(str string, begin, length int) (substr string) {
  317. // 将字符串的转换成[]rune
  318. rs := []rune(str)
  319. lth := len(rs)
  320. // 简单的越界判断
  321. if begin < 0 {
  322. begin = 0
  323. }
  324. if begin >= lth {
  325. begin = lth
  326. }
  327. end := begin + length
  328. if end > lth {
  329. end = lth
  330. }
  331. // 返回子串
  332. return string(rs[begin:end])
  333. }
  334. // 捕获异常
  335. func Try(fun func(), handler func(interface{})) {
  336. defer func() {
  337. if err := recover(); err != nil {
  338. for skip := 1; ; skip++ {
  339. _, file, line, ok := runtime.Caller(skip)
  340. if !ok {
  341. break
  342. }
  343. go log.Printf("%v,%v\n", file, line)
  344. }
  345. handler(err)
  346. }
  347. }()
  348. fun()
  349. }
  350. // 3目运算
  351. func If(b bool, to, fo interface{}) interface{} {
  352. if b {
  353. return to
  354. } else {
  355. return fo
  356. }
  357. }
  358. // HashCode值
  359. func HashCode(uid string) int {
  360. var h uint32 = 0
  361. rs := []rune(uid)
  362. for i := 0; i < len(rs); i++ {
  363. h = 31*h + uint32(rs[i])
  364. }
  365. return int(h)
  366. }
  367. // 获取离n天的秒差
  368. func GetDayStartSecond(n int) int64 {
  369. now := time.Now()
  370. tom := time.Date(now.Year(), now.Month(), now.Day()+n, 0, 0, 0, 0, time.Local)
  371. return tom.Unix()
  372. }
  373. func InterfaceArrTointArr(arr []interface{}) []int {
  374. tmp := make([]int, 0)
  375. for _, v := range arr {
  376. tmp = append(tmp, int(v.(float64)))
  377. }
  378. return tmp
  379. }
  380. func InterfaceArrToint64Arr(arr []interface{}) []int64 {
  381. tmp := make([]int64, 0)
  382. for _, v := range arr {
  383. tmp = append(tmp, int64(v.(float64)))
  384. }
  385. return tmp
  386. }
  387. func GetSubDay(t1 int64) int {
  388. tt1 := time.Unix(t1, 0)
  389. tt2 := time.Now()
  390. nt1 := time.Date(tt1.Year(), tt1.Month(), tt1.Day(), 0, 0, 0, 0, time.Local)
  391. nt2 := time.Date(tt2.Year(), tt2.Month(), tt2.Day(), 0, 0, 0, 0, time.Local)
  392. return int((nt1.Unix() - nt2.Unix()) / 86400)
  393. }
  394. func StartWith(value, str string) bool {
  395. ok, _ := regexp.MatchString("^"+str, value)
  396. return ok
  397. }
  398. func EndWith(value, str string) bool {
  399. ok, _ := regexp.MatchString(str+"$", value)
  400. return ok
  401. }
  402. // 出错拦截
  403. func Catch() {
  404. if r := recover(); r != nil {
  405. log.Println(r)
  406. for skip := 0; ; skip++ {
  407. _, file, line, ok := runtime.Caller(skip)
  408. if !ok {
  409. break
  410. }
  411. go log.Printf("%v,%v\n", file, line)
  412. }
  413. }
  414. }
  415. func ConvertFileSize(s int) string {
  416. size := float64(s)
  417. var kb float64 = 1024
  418. var mb float64 = kb * 1024
  419. var gb float64 = mb * 1024
  420. if size >= gb {
  421. return fmt.Sprintf("%.1f GB", float64(size/gb))
  422. } else if size >= mb {
  423. f := float64(size / mb)
  424. if f > 100 {
  425. return fmt.Sprintf("%.0f MB", f)
  426. }
  427. return fmt.Sprintf("%.1f MB", f)
  428. } else if size >= kb {
  429. f := float64(size / kb)
  430. if f > 100 {
  431. return fmt.Sprintf("%.0f KB", f)
  432. }
  433. return fmt.Sprintf("%.1f KB", f)
  434. }
  435. return fmt.Sprintf("%d B", s)
  436. }
  437. // MD5签名
  438. func WxSign(format string, param ...interface{}) string {
  439. data := fmt.Sprintf(format, param...)
  440. h := md5.New()
  441. h.Write([]byte(data))
  442. sign := strings.ToUpper(hex.EncodeToString(h.Sum(nil)))
  443. return sign
  444. }
  445. func FloatFormat(tmp float64, n int) float64 {
  446. fs := fmt.Sprintf("%."+fmt.Sprint(n)+"f", tmp)
  447. f, _ := strconv.ParseFloat(fs, 64)
  448. return f
  449. }
  450. // 生成微信支付的签名
  451. func CreateWxSign(afterStr string, obj interface{}, filter ...string) string {
  452. filter = append(filter, "sign", "xml")
  453. keys := []string{}
  454. m := make(map[string]string)
  455. t := reflect.TypeOf(obj)
  456. v := reflect.ValueOf(obj)
  457. k := t.Kind()
  458. if t.Kind() == reflect.Ptr {
  459. t = t.Elem()
  460. k = t.Kind()
  461. v = v.Elem()
  462. }
  463. if k == reflect.Map {
  464. for _, key := range v.MapKeys() {
  465. keys = append(keys, key.String())
  466. m[key.String()] = fmt.Sprint(v.MapIndex(key).Interface())
  467. }
  468. } else if k == reflect.Struct {
  469. for n := 0; n < t.NumField(); n++ {
  470. tagName := t.Field(n).Tag.Get("xml")
  471. if tagName == "" {
  472. tagName = t.Field(n).Tag.Get("json")
  473. }
  474. if tagName == "" {
  475. tagName = t.Field(n).Name
  476. }
  477. keys = append(keys, tagName)
  478. m[tagName] = fmt.Sprint(v.Field(n))
  479. }
  480. }
  481. sort.Strings(keys)
  482. vs := []string{}
  483. L:
  484. for _, v := range keys {
  485. for _, f := range filter {
  486. if f == v {
  487. continue L
  488. }
  489. }
  490. if strings.TrimSpace(m[v]) == "" {
  491. continue
  492. }
  493. vs = append(vs, fmt.Sprintf("%s=%s", v, m[v]))
  494. }
  495. return WxSign(strings.Join(vs, "&") + afterStr)
  496. }
  497. // 简单的xml转map,只有一个层级,没有多层嵌套
  498. func XmlToMap(input string) map[string]string {
  499. var t xml.Token
  500. var err error
  501. inputReader := strings.NewReader(input)
  502. decoder := xml.NewDecoder(inputReader)
  503. isStart := false
  504. nodeName := ""
  505. m := make(map[string]string)
  506. for t, err = decoder.Token(); err == nil; t, err = decoder.Token() {
  507. switch token := t.(type) {
  508. // 处理元素开始(标签)
  509. case xml.StartElement:
  510. isStart = true
  511. nodeName = token.Name.Local
  512. // 处理元素结束(标签)
  513. case xml.EndElement:
  514. isStart = false
  515. // 处理字符数据(这里就是元素的文本)
  516. case xml.CharData:
  517. if isStart {
  518. m[nodeName] = string([]byte(token))
  519. }
  520. default:
  521. // ...
  522. }
  523. }
  524. return m
  525. }
  526. func SimpleCrontab(flag bool, c string, f func()) {
  527. array := strings.Split(c, ":")
  528. if len(array) != 2 {
  529. log.Fatalln("定时任务参数错误!", c)
  530. }
  531. if flag {
  532. go f()
  533. }
  534. now := time.Now()
  535. t := time.Date(now.Year(), now.Month(), now.Day(), IntAll(array[0]), IntAll(array[1]), 0, 0, time.Local)
  536. if t.Before(now) {
  537. t = t.AddDate(0, 0, 1)
  538. }
  539. sub := t.Sub(now)
  540. log.Println(c, "run after", sub)
  541. timer := time.NewTimer(sub)
  542. for {
  543. select {
  544. case <-timer.C:
  545. go f()
  546. log.Println(c, "run after", 24*time.Hour)
  547. timer.Reset(24 * time.Hour)
  548. }
  549. }
  550. }
  551. // v保留n为小数,n后的四舍五入
  552. func RetainDecimal(v float64, n int) float64 {
  553. n10 := math.Pow10(n)
  554. return math.Trunc((v+0.5/n10)*n10) / n10
  555. }
  556. func LinkSplit(url string) (link, androidUrl, iosUrl, weChatUrl string) {
  557. if url != "" {
  558. arr := strings.Split(url, ",")
  559. if len(arr) == 4 {
  560. link = arr[0]
  561. androidUrl = arr[1]
  562. iosUrl = arr[2]
  563. weChatUrl = arr[3]
  564. } else {
  565. if len(arr) > 0 {
  566. link = arr[0]
  567. } else {
  568. link = ""
  569. }
  570. androidUrl = ""
  571. iosUrl = ""
  572. weChatUrl = ""
  573. }
  574. }
  575. return link, androidUrl, iosUrl, weChatUrl
  576. }