|  | @@ -0,0 +1,407 @@
 | 
	
		
			
				|  |  | +package lib
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +import (
 | 
	
		
			
				|  |  | +	"encoding/json"
 | 
	
		
			
				|  |  | +	"fmt"
 | 
	
		
			
				|  |  | +	"github.com/beego/beego/v2/server/web/context"
 | 
	
		
			
				|  |  | +	"github.com/mssola/user_agent"
 | 
	
		
			
				|  |  | +	"github.com/shopspring/decimal"
 | 
	
		
			
				|  |  | +	"math/rand"
 | 
	
		
			
				|  |  | +	"os"
 | 
	
		
			
				|  |  | +	"path/filepath"
 | 
	
		
			
				|  |  | +	"runtime"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	"sort"
 | 
	
		
			
				|  |  | +	"strconv"
 | 
	
		
			
				|  |  | +	"strings"
 | 
	
		
			
				|  |  | +	"time"
 | 
	
		
			
				|  |  | +)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type JSONS struct {
 | 
	
		
			
				|  |  | +	//必须的大写开头
 | 
	
		
			
				|  |  | +	Code int16
 | 
	
		
			
				|  |  | +	Msg  string
 | 
	
		
			
				|  |  | +	Data interface{} // 泛型
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +type R_JSONS_List struct {
 | 
	
		
			
				|  |  | +	//必须的大写开头
 | 
	
		
			
				|  |  | +	Data      []interface{}
 | 
	
		
			
				|  |  | +	Num       int64
 | 
	
		
			
				|  |  | +	Page      int
 | 
	
		
			
				|  |  | +	Page_size int
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +type R_JSONS struct {
 | 
	
		
			
				|  |  | +	//必须的大写开头
 | 
	
		
			
				|  |  | +	Data      interface{}
 | 
	
		
			
				|  |  | +	Num       int64
 | 
	
		
			
				|  |  | +	Page      int
 | 
	
		
			
				|  |  | +	Page_size int
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +type R1_JSONS struct {
 | 
	
		
			
				|  |  | +	//必须的大写开头
 | 
	
		
			
				|  |  | +	List      interface{}
 | 
	
		
			
				|  |  | +	Num       int
 | 
	
		
			
				|  |  | +	Page      int
 | 
	
		
			
				|  |  | +	Page_size int
 | 
	
		
			
				|  |  | +	Pages     []Page_T
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// func_page 分页   [{3 1} {4 2} {4 3} {4 4} {4 5} {4 6} {4 7} {4 8} {4 9} {5 2}]-
 | 
	
		
			
				|  |  | +type Page_T struct {
 | 
	
		
			
				|  |  | +	A int
 | 
	
		
			
				|  |  | +	V int64
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func Func_page(Page int64, Page_size int64) (page_t_list []Page_T) {
 | 
	
		
			
				|  |  | +	if Page > 1 {
 | 
	
		
			
				|  |  | +		page_t_list = append(page_t_list, Page_T{A: 1, V: Page - 1})
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	i := int64(0)
 | 
	
		
			
				|  |  | +	for aa := int64(1); aa < 5; aa++ {
 | 
	
		
			
				|  |  | +		if Page-aa <= 0 {
 | 
	
		
			
				|  |  | +			break
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		page_t_list = append(page_t_list, Page_T{A: 2, V: Page - aa})
 | 
	
		
			
				|  |  | +		i++
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	page_t_list = append(page_t_list, Page_T{A: 3, V: Page})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	for aa := int64(1); aa < 10-i; aa++ {
 | 
	
		
			
				|  |  | +		if Page_size < Page+aa {
 | 
	
		
			
				|  |  | +			break
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		page_t_list = append(page_t_list, Page_T{A: 4, V: Page + aa})
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	sort.Slice(page_t_list, func(i, j int) bool {
 | 
	
		
			
				|  |  | +		if page_t_list[i].V < page_t_list[j].V {
 | 
	
		
			
				|  |  | +			return true
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return false
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +	sort.Slice(page_t_list, func(i, j int) bool {
 | 
	
		
			
				|  |  | +		if page_t_list[i].A < page_t_list[j].A {
 | 
	
		
			
				|  |  | +			return true
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		return false
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +	if Page < Page_size {
 | 
	
		
			
				|  |  | +		page_t_list = append(page_t_list, Page_T{A: 5, V: Page + 1})
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return page_t_list
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func Strval(value interface{}) string {
 | 
	
		
			
				|  |  | +	var key string
 | 
	
		
			
				|  |  | +	if value == nil {
 | 
	
		
			
				|  |  | +		return key
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch value.(type) {
 | 
	
		
			
				|  |  | +	case float64:
 | 
	
		
			
				|  |  | +		ft := value.(float64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatFloat(ft, 'f', -1, 64)
 | 
	
		
			
				|  |  | +	case float32:
 | 
	
		
			
				|  |  | +		ft := value.(float32)
 | 
	
		
			
				|  |  | +		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
 | 
	
		
			
				|  |  | +	case int:
 | 
	
		
			
				|  |  | +		it := value.(int)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(it)
 | 
	
		
			
				|  |  | +	case uint:
 | 
	
		
			
				|  |  | +		it := value.(uint)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int8:
 | 
	
		
			
				|  |  | +		it := value.(int8)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint8:
 | 
	
		
			
				|  |  | +		it := value.(uint8)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int16:
 | 
	
		
			
				|  |  | +		it := value.(int16)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint16:
 | 
	
		
			
				|  |  | +		it := value.(uint16)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int32:
 | 
	
		
			
				|  |  | +		it := value.(int32)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint32:
 | 
	
		
			
				|  |  | +		it := value.(uint32)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int64:
 | 
	
		
			
				|  |  | +		it := value.(int64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatInt(it, 10)
 | 
	
		
			
				|  |  | +	case uint64:
 | 
	
		
			
				|  |  | +		it := value.(uint64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatUint(it, 10)
 | 
	
		
			
				|  |  | +	case string:
 | 
	
		
			
				|  |  | +		key = value.(string)
 | 
	
		
			
				|  |  | +	case []byte:
 | 
	
		
			
				|  |  | +		key = string(value.([]byte))
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		newValue, _ := json.Marshal(value)
 | 
	
		
			
				|  |  | +		key = string(newValue)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return key
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func To_int(value interface{}) int {
 | 
	
		
			
				|  |  | +	var key int
 | 
	
		
			
				|  |  | +	if value == nil {
 | 
	
		
			
				|  |  | +		return key
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	switch value.(type) {
 | 
	
		
			
				|  |  | +	case float64:
 | 
	
		
			
				|  |  | +		key = int(value.(float64))
 | 
	
		
			
				|  |  | +	case float32:
 | 
	
		
			
				|  |  | +		key = int(value.(float32))
 | 
	
		
			
				|  |  | +	case int:
 | 
	
		
			
				|  |  | +		key = int(value.(int))
 | 
	
		
			
				|  |  | +	case uint:
 | 
	
		
			
				|  |  | +		key = int(value.(uint))
 | 
	
		
			
				|  |  | +	case int8:
 | 
	
		
			
				|  |  | +		key = int(value.(int8))
 | 
	
		
			
				|  |  | +	case uint8:
 | 
	
		
			
				|  |  | +		key = int(value.(uint8))
 | 
	
		
			
				|  |  | +	case int16:
 | 
	
		
			
				|  |  | +		key = int(value.(int16))
 | 
	
		
			
				|  |  | +	case uint16:
 | 
	
		
			
				|  |  | +		key = int(value.(uint16))
 | 
	
		
			
				|  |  | +	case int32:
 | 
	
		
			
				|  |  | +		key = int(value.(int32))
 | 
	
		
			
				|  |  | +	case uint32:
 | 
	
		
			
				|  |  | +		key = int(value.(uint32))
 | 
	
		
			
				|  |  | +	case int64:
 | 
	
		
			
				|  |  | +		key = int(value.(int64))
 | 
	
		
			
				|  |  | +	case uint64:
 | 
	
		
			
				|  |  | +		key = int(value.(uint64))
 | 
	
		
			
				|  |  | +	case string:
 | 
	
		
			
				|  |  | +		key, _ = strconv.Atoi(value.(string))
 | 
	
		
			
				|  |  | +	case []byte:
 | 
	
		
			
				|  |  | +		key, _ = strconv.Atoi(string(value.([]byte)))
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		newValue, _ := json.Marshal(value)
 | 
	
		
			
				|  |  | +		key, _ = strconv.Atoi(string(newValue))
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return key
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func To_float32(value interface{}) float32 {
 | 
	
		
			
				|  |  | +	var key float32
 | 
	
		
			
				|  |  | +	if value == nil {
 | 
	
		
			
				|  |  | +		return key
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch value.(type) {
 | 
	
		
			
				|  |  | +	case float64:
 | 
	
		
			
				|  |  | +		key = float32(value.(float64))
 | 
	
		
			
				|  |  | +	case float32:
 | 
	
		
			
				|  |  | +		key = float32(value.(float32))
 | 
	
		
			
				|  |  | +	case int:
 | 
	
		
			
				|  |  | +		key = float32(value.(int))
 | 
	
		
			
				|  |  | +	case uint:
 | 
	
		
			
				|  |  | +		key = float32(value.(uint))
 | 
	
		
			
				|  |  | +	case int8:
 | 
	
		
			
				|  |  | +		key = float32(value.(int8))
 | 
	
		
			
				|  |  | +	case uint8:
 | 
	
		
			
				|  |  | +		key = float32(value.(uint8))
 | 
	
		
			
				|  |  | +	case int16:
 | 
	
		
			
				|  |  | +		key = float32(value.(int16))
 | 
	
		
			
				|  |  | +	case uint16:
 | 
	
		
			
				|  |  | +		key = float32(value.(uint16))
 | 
	
		
			
				|  |  | +	case int32:
 | 
	
		
			
				|  |  | +		key = float32(value.(int32))
 | 
	
		
			
				|  |  | +	case uint32:
 | 
	
		
			
				|  |  | +		key = float32(value.(uint32))
 | 
	
		
			
				|  |  | +	case int64:
 | 
	
		
			
				|  |  | +		key = float32(value.(int64))
 | 
	
		
			
				|  |  | +	case uint64:
 | 
	
		
			
				|  |  | +		key = float32(value.(uint64))
 | 
	
		
			
				|  |  | +	case string:
 | 
	
		
			
				|  |  | +		key_float64, _ := strconv.ParseFloat(value.(string), 32/64)
 | 
	
		
			
				|  |  | +		key = float32(key_float64)
 | 
	
		
			
				|  |  | +	case []byte:
 | 
	
		
			
				|  |  | +		key_float64, _ := strconv.ParseFloat(string(value.([]byte)), 32/64)
 | 
	
		
			
				|  |  | +		key = float32(key_float64)
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		newValue, _ := json.Marshal(value)
 | 
	
		
			
				|  |  | +		key_float64, _ := strconv.ParseFloat(string(newValue), 32/64)
 | 
	
		
			
				|  |  | +		key = float32(key_float64)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	key_float64, _ := strconv.ParseFloat(fmt.Sprintf("%.2f", key), 32/64)
 | 
	
		
			
				|  |  | +	key = float32(key_float64)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return key
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func To_string(value interface{}) string {
 | 
	
		
			
				|  |  | +	var key string
 | 
	
		
			
				|  |  | +	if value == nil {
 | 
	
		
			
				|  |  | +		return key
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	switch value.(type) {
 | 
	
		
			
				|  |  | +	case float64:
 | 
	
		
			
				|  |  | +		ft := value.(float64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatFloat(ft, 'f', -1, 64)
 | 
	
		
			
				|  |  | +	case float32:
 | 
	
		
			
				|  |  | +		ft := value.(float32)
 | 
	
		
			
				|  |  | +		key = strconv.FormatFloat(float64(ft), 'f', -1, 64)
 | 
	
		
			
				|  |  | +	case int:
 | 
	
		
			
				|  |  | +		it := value.(int)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(it)
 | 
	
		
			
				|  |  | +	case uint:
 | 
	
		
			
				|  |  | +		it := value.(uint)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int8:
 | 
	
		
			
				|  |  | +		it := value.(int8)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint8:
 | 
	
		
			
				|  |  | +		it := value.(uint8)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int16:
 | 
	
		
			
				|  |  | +		it := value.(int16)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint16:
 | 
	
		
			
				|  |  | +		it := value.(uint16)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int32:
 | 
	
		
			
				|  |  | +		it := value.(int32)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case uint32:
 | 
	
		
			
				|  |  | +		it := value.(uint32)
 | 
	
		
			
				|  |  | +		key = strconv.Itoa(int(it))
 | 
	
		
			
				|  |  | +	case int64:
 | 
	
		
			
				|  |  | +		it := value.(int64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatInt(it, 10)
 | 
	
		
			
				|  |  | +	case uint64:
 | 
	
		
			
				|  |  | +		it := value.(uint64)
 | 
	
		
			
				|  |  | +		key = strconv.FormatUint(it, 10)
 | 
	
		
			
				|  |  | +	case string:
 | 
	
		
			
				|  |  | +		key = value.(string)
 | 
	
		
			
				|  |  | +	case []byte:
 | 
	
		
			
				|  |  | +		key = string(value.([]byte))
 | 
	
		
			
				|  |  | +	default:
 | 
	
		
			
				|  |  | +		newValue, _ := json.Marshal(value)
 | 
	
		
			
				|  |  | +		key = string(newValue)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	return key
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func Random(min, max int) int {
 | 
	
		
			
				|  |  | +	rand.Seed(time.Now().Unix()) //Seed生成的随机数
 | 
	
		
			
				|  |  | +	return rand.Intn(max-min) + min
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 取文本(字符串)中间
 | 
	
		
			
				|  |  | +func GetBetweenStr(str, start, end string) string {
 | 
	
		
			
				|  |  | +	n := strings.Index(str, start)
 | 
	
		
			
				|  |  | +	if n == -1 {
 | 
	
		
			
				|  |  | +		n = 0
 | 
	
		
			
				|  |  | +	} else {
 | 
	
		
			
				|  |  | +		n = n + len(start) // 增加了else,不加的会把start带上
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	str = string([]byte(str)[n:])
 | 
	
		
			
				|  |  | +	m := strings.Index(str, end)
 | 
	
		
			
				|  |  | +	if m == -1 {
 | 
	
		
			
				|  |  | +		m = len(str)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	str = string([]byte(str)[:m])
 | 
	
		
			
				|  |  | +	return str
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// getYearMonthToDay 查询指定年份指定月份有多少天
 | 
	
		
			
				|  |  | +// @params year int 指定年份
 | 
	
		
			
				|  |  | +// @params month int 指定月份
 | 
	
		
			
				|  |  | +func GetYearMonthToDay(year int, month int) int {
 | 
	
		
			
				|  |  | +	// 有31天的月份
 | 
	
		
			
				|  |  | +	day31 := map[int]bool{
 | 
	
		
			
				|  |  | +		1:  true,
 | 
	
		
			
				|  |  | +		3:  true,
 | 
	
		
			
				|  |  | +		5:  true,
 | 
	
		
			
				|  |  | +		7:  true,
 | 
	
		
			
				|  |  | +		8:  true,
 | 
	
		
			
				|  |  | +		10: true,
 | 
	
		
			
				|  |  | +		12: true,
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	if day31[month] == true {
 | 
	
		
			
				|  |  | +		return 31
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	// 有30天的月份
 | 
	
		
			
				|  |  | +	day30 := map[int]bool{
 | 
	
		
			
				|  |  | +		4:  true,
 | 
	
		
			
				|  |  | +		6:  true,
 | 
	
		
			
				|  |  | +		9:  true,
 | 
	
		
			
				|  |  | +		11: true,
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	if day30[month] == true {
 | 
	
		
			
				|  |  | +		return 30
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	// 计算是平年还是闰年
 | 
	
		
			
				|  |  | +	if (year%4 == 0 && year%100 != 0) || year%400 == 0 {
 | 
	
		
			
				|  |  | +		// 得出2月的天数
 | 
	
		
			
				|  |  | +		return 29
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	// 得出2月的天数
 | 
	
		
			
				|  |  | +	return 28
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func Decimal(value float64) float64 {
 | 
	
		
			
				|  |  | +	value, _ = strconv.ParseFloat(fmt.Sprintf("%.1f", value), 64)
 | 
	
		
			
				|  |  | +	return value
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +func Strconv_Atoi(string string) int {
 | 
	
		
			
				|  |  | +	int, _ := strconv.Atoi(string)
 | 
	
		
			
				|  |  | +	return int
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// golang获取程序运行路径
 | 
	
		
			
				|  |  | +func GetCurrentDirectory() string {
 | 
	
		
			
				|  |  | +	dir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return strings.Replace(dir, "\\", "/", -1)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 获取正在运行的函数名
 | 
	
		
			
				|  |  | +func FuncName() string {
 | 
	
		
			
				|  |  | +	pc := make([]uintptr, 1)
 | 
	
		
			
				|  |  | +	runtime.Callers(2, pc)
 | 
	
		
			
				|  |  | +	f := runtime.FuncForPC(pc[0])
 | 
	
		
			
				|  |  | +	return f.Name()
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 获取两个时间相差的天数,0表同一天,正数表t1>t2,负数表t1<t2
 | 
	
		
			
				|  |  | +func GetDiffDays(t1, t2 time.Time) int {
 | 
	
		
			
				|  |  | +	t1 = time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.Local)
 | 
	
		
			
				|  |  | +	t2 = time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.Local)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	return int(t1.Sub(t2).Hours() / 24)
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 获取用户登录信息
 | 
	
		
			
				|  |  | +func GetUserLoginInfo(ctx *context.Context) map[string]interface{} {
 | 
	
		
			
				|  |  | +	//Ipaddr      ip地址
 | 
	
		
			
				|  |  | +	//Browser     浏览器
 | 
	
		
			
				|  |  | +	//Os          系统
 | 
	
		
			
				|  |  | +	//Platform    固件
 | 
	
		
			
				|  |  | +	l := make(map[string]interface{})
 | 
	
		
			
				|  |  | +	ua := user_agent.New(ctx.Request.UserAgent())
 | 
	
		
			
				|  |  | +	l["ipaddr"] = ctx.Input.IP()
 | 
	
		
			
				|  |  | +	l["remark"] = ctx.Request.UserAgent()
 | 
	
		
			
				|  |  | +	browserName, browserVersion := ua.Browser()
 | 
	
		
			
				|  |  | +	l["browser"] = browserName + " " + browserVersion
 | 
	
		
			
				|  |  | +	l["os"] = ua.OS()
 | 
	
		
			
				|  |  | +	l["platform"] = ua.Platform()
 | 
	
		
			
				|  |  | +	return l
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// Float64转float64保留2位小数
 | 
	
		
			
				|  |  | +func Float64ToFloat64TwoDecimal(num float64) float64 {
 | 
	
		
			
				|  |  | +	f, _ := decimal.NewFromFloat(num).Round(2).Float64()
 | 
	
		
			
				|  |  | +	return f
 | 
	
		
			
				|  |  | +}
 |