common.go 15 KB

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