func.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. package common
  2. import (
  3. "context"
  4. "crypto/md5"
  5. "crypto/rand"
  6. "encoding/base64"
  7. "encoding/hex"
  8. "errors"
  9. "github.com/gogf/gf/crypto/gmd5"
  10. "github.com/gogf/gf/database/gdb"
  11. "github.com/gogf/gf/encoding/gurl"
  12. "github.com/gogf/gf/errors/gerror"
  13. "github.com/gogf/gf/frame/g"
  14. "github.com/gogf/gf/os/gctx"
  15. "github.com/gogf/gf/os/gfile"
  16. "github.com/gogf/gf/os/gtime"
  17. "github.com/gogf/gf/text/gregex"
  18. "github.com/gogf/gf/util/gconv"
  19. "github.com/gogf/gf/util/grand"
  20. "io"
  21. "math"
  22. mrand "math/rand"
  23. "net"
  24. "os"
  25. "regexp"
  26. "strings"
  27. "time"
  28. "unicode/utf8"
  29. )
  30. func InArray(item int, items []int) bool {
  31. for _, v := range items {
  32. if v == item {
  33. return true
  34. }
  35. }
  36. return false
  37. }
  38. func MapIntStingInArray(item string, items map[int]string) int {
  39. for k, v := range items {
  40. if item == v {
  41. return k
  42. }
  43. }
  44. return 0
  45. }
  46. func Md5V(str string) string {
  47. h := md5.New()
  48. h.Write([]byte(str))
  49. return hex.EncodeToString(h.Sum(nil))
  50. }
  51. func UniqueId() string {
  52. b := make([]byte, 48)
  53. if _, err := io.ReadFull(rand.Reader, b); err != nil {
  54. return ""
  55. }
  56. return GetMd5(base64.URLEncoding.EncodeToString(b))
  57. }
  58. func GetMd5(str string) string {
  59. h := md5.New()
  60. h.Write([]byte(str))
  61. return hex.EncodeToString(h.Sum(nil))
  62. }
  63. //Salt 生成
  64. func Salt() string {
  65. builder := strings.Builder{}
  66. mrand.Seed(time.Now().UnixNano())
  67. for i := 0; i < 4; i++ {
  68. builder.WriteString(gconv.String(mrand.Intn(9)))
  69. }
  70. return builder.String()
  71. }
  72. //Base34 分享码
  73. func Base34(num int64) (res string) {
  74. base := strings.Split("0123456789ABCDEFGHJKLMNPQRSTUVWXYZ", "")
  75. for num >= 34 {
  76. i := num % 34
  77. res = base[i] + res
  78. num = num / 34
  79. }
  80. res = base[num] + res
  81. return strings.Repeat("0", 6-len(res)) + res
  82. }
  83. //MapIntStingInArrayResult 判断这个键名是否在数组中是否在数组中并返回键值与键名
  84. func MapIntStingKeyInArrayResult(item int, items map[int]string) (int, string) {
  85. for k, v := range items {
  86. if item == k {
  87. return k, v
  88. }
  89. }
  90. return 0, ""
  91. }
  92. func StrIsIn(str string, strs []string) bool {
  93. for _, v := range strs {
  94. if str == v {
  95. return true
  96. }
  97. }
  98. return false
  99. }
  100. /**
  101. 指定个数分割数组
  102. */
  103. func Chunk(arr []gdb.Value, base int) (res [][]gdb.Value) {
  104. Len := len(arr)
  105. num := math.Ceil(float64(Len) / float64(base)) //分割次数
  106. var i int
  107. for i = 1; i <= int(num); i++ {
  108. low := ((i - 1) * base)
  109. height := ((i-1)*base + base)
  110. if height > Len {
  111. height = Len
  112. }
  113. tmp := arr[low:height:Len]
  114. res = append(res, tmp)
  115. }
  116. return
  117. }
  118. func ChunkInts(arr []int, base int) (res [][]int) {
  119. Len := len(arr)
  120. num := math.Ceil(float64(Len) / float64(base)) //分割次数
  121. var i int
  122. for i = 1; i <= int(num); i++ {
  123. low := ((i - 1) * base)
  124. height := ((i-1)*base + base)
  125. if height > Len {
  126. height = Len
  127. }
  128. tmp := arr[low:height:Len]
  129. res = append(res, tmp)
  130. }
  131. return
  132. }
  133. func ChunkInterface(arr []interface{}, base int) (res [][]interface{}) {
  134. Len := len(arr)
  135. num := math.Ceil(float64(Len) / float64(base)) //分割次数
  136. var i int
  137. for i = 1; i <= int(num); i++ {
  138. low := ((i - 1) * base)
  139. height := ((i-1)*base + base)
  140. if height > Len {
  141. height = Len
  142. }
  143. tmp := arr[low:height:Len]
  144. res = append(res, tmp)
  145. }
  146. return
  147. }
  148. /**
  149. int去重
  150. */
  151. func IntSliceUnique(data []int) (res []int) {
  152. if len(data) == 0 {
  153. return
  154. }
  155. dict := map[int]bool{}
  156. for _, v := range data {
  157. if dict[v] == true {
  158. continue
  159. }
  160. dict[v] = true
  161. res = append(res, v)
  162. }
  163. return
  164. }
  165. /**
  166. string去重
  167. */
  168. func StrSliceUnique(data []string) (res []string) {
  169. if len(data) == 0 {
  170. return
  171. }
  172. dict := map[string]bool{}
  173. for _, v := range data {
  174. if dict[v] == true {
  175. continue
  176. }
  177. dict[v] = true
  178. res = append(res, v)
  179. }
  180. return
  181. }
  182. /**
  183. * 数组去重 去空
  184. */
  185. func RemoveDuplicatesAndEmpty(a []string) (ret []string) {
  186. a_len := len(a)
  187. for i := 0; i < a_len; i++ {
  188. if (i > 0 && a[i-1] == a[i]) || len(a[i]) == 0 {
  189. continue
  190. }
  191. ret = append(ret, a[i])
  192. }
  193. return
  194. }
  195. //GetDayTime i 1 昨天 7 7天前 15 15天前
  196. // i天前的 00:00:00 与昨天的 23:59:59
  197. func GetDayTime(i int) (startTime, endTime int64) {
  198. currentTime := time.Now()
  199. startTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day()-i, 00, 00, 00, 0, currentTime.Location()).Unix()
  200. endTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day()-1, 23, 59, 59, 0, currentTime.Location()).Unix()
  201. return
  202. }
  203. //GetStartAndEndTime 获取时间戳当天的 00:00:00 与 23:59:59
  204. func GetStartAndEndTime(t int64) (startTime, endTime int64) {
  205. currentTime := time.Unix(t, 0)
  206. startTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 00, 00, 00, 0, currentTime.Location()).Unix()
  207. endTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location()).Unix()
  208. return
  209. }
  210. func CutTime(createTime, endTime int) (arr []int) {
  211. newTime := createTime
  212. for {
  213. if newTime <= endTime {
  214. arr = append(arr, newTime)
  215. newTime += 86400
  216. } else {
  217. return arr
  218. }
  219. }
  220. }
  221. func SotrTowMap(towMap []map[string]interface{}) []map[string]interface{} {
  222. var tmp []map[string]interface{}
  223. lens := len(towMap)
  224. var i int
  225. for i = lens - 1; i >= 0; i-- {
  226. tmp = append(tmp, towMap[i])
  227. }
  228. return tmp
  229. }
  230. ////字符串获取首字母
  231. //func StrInitial(hans string) (initial string) {
  232. // //数字开头
  233. // if unicode.IsDigit(int32(hans[0])) {
  234. // initial = strings.ToUpper(string([]byte(hans)[:1]))
  235. // return
  236. // }
  237. // //字母开头且不是汉字
  238. // if unicode.IsLetter(int32(hans[0])) && int32(hans[0]) >= 65 && int32(hans[0]) <= 122 {
  239. // initial = strings.ToUpper(string([]byte(hans)[:1]))
  240. // return
  241. // }
  242. //
  243. // //第一个匹配的是全部元素
  244. // var hzRegexp, _ = regexp.Compile("([\u4e00-\u9fa5]+)")
  245. // sub := hzRegexp.FindSubmatch([]byte(hans))
  246. // if len(sub) == 0 {
  247. // return
  248. // }
  249. // pynew := pinyin.NewArgs()
  250. //
  251. // pys := pinyin.Pinyin(string(sub[0]), pynew)[0][0]
  252. // initial = strings.ToUpper(string([]byte(pys)[:1]))
  253. // return
  254. //}
  255. //两数差集 只差slice1的差集
  256. func Difference(slice1, slice2 []string) []string {
  257. m := make(map[string]int)
  258. nn := make([]string, 0)
  259. inter := Intersect(slice1, slice2)
  260. for _, v := range inter {
  261. m[v]++
  262. }
  263. for _, value := range slice1 {
  264. times, _ := m[value]
  265. if times == 0 {
  266. nn = append(nn, value)
  267. }
  268. }
  269. return nn
  270. }
  271. //并集
  272. func Intersect(slice1, slice2 []string) []string {
  273. m := make(map[string]int)
  274. nn := make([]string, 0)
  275. for _, v := range slice1 {
  276. m[v]++
  277. }
  278. for _, v := range slice2 {
  279. times, _ := m[v]
  280. if times == 1 {
  281. nn = append(nn, v)
  282. }
  283. }
  284. return nn
  285. }
  286. //数组平分
  287. func splitArray(arr []int, num int64) [][]int {
  288. max := int64(len(arr))
  289. if max < num {
  290. return nil
  291. }
  292. var segmens = make([][]int, 0)
  293. quantity := max / num
  294. end := int64(0)
  295. for i := int64(1); i <= num; i++ {
  296. qu := i * quantity
  297. if i != num {
  298. segmens = append(segmens, arr[i-1+end:qu])
  299. } else {
  300. segmens = append(segmens, arr[i-1+end:])
  301. }
  302. end = qu - i
  303. }
  304. return segmens
  305. }
  306. func InArrayString(need string, needArr []string) bool {
  307. for _, v := range needArr {
  308. if need == v {
  309. return true
  310. }
  311. }
  312. return false
  313. }
  314. //Sn 流水号
  315. func Sn(pre ...string) (res string) {
  316. if len(pre) > 0 {
  317. res = pre[0]
  318. }
  319. res += gtime.Now().Format("YmdHisu") + grand.Digits(3)
  320. return
  321. }
  322. func LocalPath() (path string, err error) {
  323. path, err = mkdir()
  324. if err != nil {
  325. return
  326. }
  327. path = uniqueFilename(path)
  328. return
  329. }
  330. func mkdir() (path string, err error) {
  331. path = g.Log().GetPath() + "/files/"
  332. err = gfile.Mkdir(path)
  333. return
  334. }
  335. func uniqueFilename(path string) string {
  336. return path + Sn() + ".xlsx"
  337. }
  338. //Split 字符串分割
  339. func Split(s, sep string) []string {
  340. if s == "" {
  341. return []string{}
  342. }
  343. return strings.Split(s, sep)
  344. }
  345. //UserPhone 脱敏手机号
  346. func UserPhone(phone string) (res string) {
  347. if phone == "" {
  348. return ""
  349. }
  350. res, _ = gregex.ReplaceString(`(\d{3})(\d{4})(\d{4})`, "$1****$3", phone)
  351. return
  352. }
  353. //UserName 脱敏文字
  354. func UserName(name string) string {
  355. nameString := []rune(name)
  356. newName := ""
  357. reg := `^[A-Za-z]+$`
  358. regNum := `^[0-9]+$`
  359. rgx := regexp.MustCompile(reg)
  360. resAz := rgx.MatchString(name)
  361. rgxNum := regexp.MustCompile(regNum)
  362. resNum := rgxNum.MatchString(name)
  363. if resAz == true || resNum == true || utf8.RuneCountInString(name) <= 2 {
  364. rangeright := utf8.RuneCountInString(name) - 1
  365. if rangeright < 1 {
  366. rangeright = 1
  367. }
  368. numLeft := string(nameString[0:rangeright])
  369. newName = numLeft + "*"
  370. } else if utf8.RuneCountInString(name) == 3 {
  371. numLeft := string(nameString[0:1])
  372. numRight := string(nameString[2:3])
  373. newName = numLeft + "*" + numRight
  374. } else {
  375. numLeft := string(nameString[0:1])
  376. numRange := utf8.RuneCountInString(name) - 2
  377. Encryption := ""
  378. for i := 0; i <= numRange; i++ {
  379. Encryption += "*"
  380. }
  381. rangeright := utf8.RuneCountInString(name) - 1
  382. if rangeright < 1 {
  383. rangeright = 0
  384. }
  385. numRight := string(nameString[rangeright:utf8.RuneCountInString(name)])
  386. newName = numLeft + Encryption + numRight
  387. }
  388. return newName
  389. }
  390. func Take(a float64, b int) float64 {
  391. f1 := gconv.Float64(a) * gconv.Float64(b)
  392. return gconv.Float64(f1)
  393. }
  394. //业务层是uint 没有泛型只能固定
  395. func IsRepeat(num []uint) bool {
  396. hash := make(map[interface{}]bool)
  397. for _, v := range num {
  398. if hash[v] == true {
  399. return true
  400. } else {
  401. hash[v] = true
  402. }
  403. }
  404. return false
  405. }
  406. func InArrayInt(search uint, values []uint) bool {
  407. for _, value := range values {
  408. if value == search {
  409. return true
  410. }
  411. }
  412. return false
  413. }
  414. func DelItems(vs []int, dels []int) []int {
  415. dMap := make(map[int]bool)
  416. for _, s := range dels {
  417. dMap[s] = true
  418. }
  419. for i := 0; i < len(vs); i++ {
  420. if _, ok := dMap[vs[i]]; ok {
  421. vs = append(vs[:i], vs[i+1:]...)
  422. i = i - 1
  423. }
  424. }
  425. return vs
  426. }
  427. /*
  428. 获取真实IP
  429. */
  430. func ExternalIP() (net.IP, error) {
  431. ifaces, err := net.Interfaces()
  432. if err != nil {
  433. return nil, err
  434. }
  435. for _, iface := range ifaces {
  436. if iface.Flags&net.FlagUp == 0 {
  437. continue // interface down
  438. }
  439. if iface.Flags&net.FlagLoopback != 0 {
  440. continue // loopback interface
  441. }
  442. addrs, err := iface.Addrs()
  443. if err != nil {
  444. return nil, err
  445. }
  446. for _, addr := range addrs {
  447. ip := getIpFromAddr(addr)
  448. if ip == nil {
  449. continue
  450. }
  451. return ip, nil
  452. }
  453. }
  454. return nil, errors.New("connected to the network?")
  455. }
  456. func getIpFromAddr(addr net.Addr) net.IP {
  457. var ip net.IP
  458. switch v := addr.(type) {
  459. case *net.IPNet:
  460. ip = v.IP
  461. case *net.IPAddr:
  462. ip = v.IP
  463. }
  464. if ip == nil || ip.IsLoopback() {
  465. return nil
  466. }
  467. ip = ip.To4()
  468. if ip == nil {
  469. return nil // not an ipv4 address
  470. }
  471. return ip
  472. }
  473. //两数差集 只差slice1的差集
  474. func DifferenceInt(slice1, slice2 []int) []int {
  475. m := make(map[int]int)
  476. nn := make([]int, 0)
  477. inter := IntersectInt(slice1, slice2)
  478. for _, v := range inter {
  479. m[v]++
  480. }
  481. for _, value := range slice1 {
  482. times, _ := m[value]
  483. if times == 0 {
  484. nn = append(nn, value)
  485. }
  486. }
  487. return nn
  488. }
  489. func IntersectInt(slice1, slice2 []int) []int {
  490. m := make(map[int]int)
  491. nn := make([]int, 0)
  492. for _, v := range slice1 {
  493. m[v]++
  494. }
  495. for _, v := range slice2 {
  496. times, _ := m[v]
  497. if times == 1 {
  498. nn = append(nn, v)
  499. }
  500. }
  501. return nn
  502. }
  503. func Password(password, Salt string) (res string) {
  504. return gmd5.MustEncryptString(gmd5.MustEncryptString(password) + Salt)
  505. }
  506. //判断文件夹是否存在
  507. func PathExists(path string) (bool, error) {
  508. _, err := os.Stat(path)
  509. if err == nil {
  510. return true, nil
  511. }
  512. if os.IsNotExist(err) {
  513. return false, nil
  514. }
  515. return false, err
  516. }
  517. func Reverse(arr *[]int, length int) {
  518. var temp int
  519. for i := 0; i < length/2; i++ {
  520. temp = (*arr)[i]
  521. (*arr)[i] = (*arr)[length-1-i]
  522. (*arr)[length-1-i] = temp
  523. }
  524. }
  525. //获取模型
  526. func GetModule(url string) (string, error) {
  527. pathInfo, err := gurl.ParseURL(url, -1)
  528. if err != nil {
  529. g.Log().Error(err)
  530. err = gerror.New("解析附件路径失败")
  531. return "", err
  532. }
  533. urls := strings.Split(gconv.String(pathInfo["host"]), ".")
  534. return urls[0], nil
  535. }
  536. func Ctx(pre ...string) context.Context {
  537. var ctx = context.WithValue(gctx.New(), "RequestId", Sn(pre...))
  538. return ctx
  539. }
  540. //获取当前时间戳 uint
  541. func Timestamp() uint {
  542. return gconv.Uint(gtime.Timestamp())
  543. }