Files
baseapi/utils/typeconv.go
2018-11-19 20:10:22 +08:00

356 lines
7.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package utils
import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"reflect"
"strconv"
"strings"
"time"
"git.rosy.net.cn/baseapi"
"github.com/fatih/structs"
)
var (
DefaultTimeValue = Str2Time("1970-01-01 00:00:00")
)
func GetConcretValue(value reflect.Value) reflect.Value {
for {
if value.Kind() == reflect.Interface || value.Kind() == reflect.Ptr {
value = value.Elem()
} else {
break
}
}
return value
}
func UnmarshalUseNumber(data []byte, result interface{}) error {
d := json.NewDecoder(bytes.NewReader(data))
d.UseNumber()
err := d.Decode(result)
if err != nil {
baseapi.SugarLogger.Infof("decode data:%v, error:%v", string(data), err)
}
return err
}
// 这个函数将解析json返回的map中的字段类型与structObj中的完全一样的
func Unmarshal2Map(data []byte, structObj interface{}) (resultMap map[string]interface{}, err error) {
if err = json.Unmarshal(data, structObj); err == nil {
if err = json.Unmarshal(data, &resultMap); err == nil {
m := structs.Map(structObj)
for k := range resultMap {
if value, ok := m[k]; ok {
resultMap[k] = value
} else {
delete(resultMap, k)
}
}
}
}
return resultMap, err
}
func MustMarshal(obj interface{}) []byte {
byteArr, err := json.Marshal(obj)
if err != nil {
panic(fmt.Sprintf("err when Marshal obj:%v with error:%v", obj, err))
}
return byteArr
}
func MustInterface2Int64(data interface{}) int64 {
dataNumber, ok := data.(json.Number)
if !ok {
panic(fmt.Sprintf("error when cast:%v to int64", data))
}
retVal, err := dataNumber.Int64()
if err != nil {
panic(err.Error())
}
return retVal
}
func Interface2Int64WithDefault(data interface{}, defValue int64) int64 {
if data == nil {
return defValue
}
return MustInterface2Int64(data)
}
func Interface2DirectIntWithDefault(data interface{}, defValue int) int {
if data == nil {
return defValue
}
return data.(int)
}
func MustInterface2Float64(data interface{}) float64 {
dataNumber, ok := data.(json.Number)
if !ok {
panic(fmt.Sprintf("error when convert:%v", data))
}
retVal, err := dataNumber.Float64()
if err != nil {
panic(err.Error())
}
return retVal
}
func Interface2FloatWithDefault(data interface{}, defValue float64) (retVal float64) {
if data == nil {
return defValue
}
return MustInterface2Float64(data)
}
func Interface2String(data interface{}) string {
if data == nil {
return ""
}
return data.(string)
}
func Interface2Int64List(data interface{}) []int64 {
if data == nil {
return nil
}
list := data.([]interface{})
retVal := make([]int64, len(list))
for k, v := range list {
retVal[k] = MustInterface2Int64(v)
}
return retVal
}
func Interface2StringList(data interface{}) []string {
if data == nil {
return nil
}
list := data.([]interface{})
retVal := make([]string, len(list))
for k, v := range list {
retVal[k] = Interface2String(v)
}
return retVal
}
func Interface2Slice(value interface{}) (retVal []interface{}) {
typeInfo := reflect.TypeOf(value)
if typeInfo.Kind() != reflect.Slice {
panic("list must be slice type!")
}
if value != nil {
valueInfo := reflect.ValueOf(value)
retVal = make([]interface{}, valueInfo.Len())
for i := 0; i < valueInfo.Len(); i++ {
retVal[i] = valueInfo.Index(i).Interface()
}
}
return retVal
}
func Slice2MapSlice(data []interface{}) []map[string]interface{} {
retVal := make([]map[string]interface{}, len(data))
for k, v := range data {
retVal[k] = v.(map[string]interface{})
}
return retVal
}
//
func Bool2String(value bool) string {
if value {
return "true"
}
return "false"
}
func Str2Int64WithDefault(str string, defValue int64) int64 {
retVal, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return defValue
}
return retVal
}
func Str2Int64(str string) int64 {
retVal, err := strconv.ParseInt(str, 10, 64)
if err != nil {
baseapi.SugarLogger.Errorf("error when convert %s to int64", str)
}
return retVal
}
func Str2Float64WithDefault(str string, defValue float64) float64 {
retVal, err := strconv.ParseFloat(str, 64)
if err != nil {
retVal = defValue
}
return retVal
}
func Str2Float64(str string) float64 {
retVal, err := strconv.ParseFloat(str, 64)
if err != nil {
baseapi.SugarLogger.Errorf("error when convert %s to float64", str)
}
return retVal
}
func Int64ToStr(value int64) string {
return strconv.FormatInt(value, 10)
}
func Int2Str(value int) string {
return strconv.Itoa(value)
}
// timestamp is in second
func Timestamp2Str(timestamp int64) string {
return Time2Str(Timestamp2Time(timestamp))
}
func Timestamp2Time(timestamp int64) time.Time {
const normalTimestamp = 1533709322
if timestamp > normalTimestamp*100 { // 传成毫秒了
baseapi.SugarLogger.Errorf("Timestamp2Time wrong timestamp:%d", timestamp)
timestamp = timestamp / 1000
}
return time.Unix(timestamp, 0)
}
func Time2Str(t time.Time) string {
return t.Format("2006-01-02 15:04:05")
}
func Str2Time(timeStr string) time.Time {
retVal, err := TryStr2Time(timeStr)
if err != nil {
baseapi.SugarLogger.Errorf("time.ParseInLocation failed, timeStr:%v, error:%v", timeStr, err)
}
return retVal
}
func TryStr2Time(timeStr string) (time.Time, error) {
timeStr = strings.Replace(timeStr, "T", " ", 1)
if strings.Index(timeStr, " ") == -1 {
timeStr += " 00:00:00"
}
return time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local)
}
func Str2TimeWithDefault(timeStr string, defValue time.Time) time.Time {
timeStr = strings.Replace(timeStr, "T", " ", 1)
retVal, err := time.ParseInLocation("2006-1-2 15:4:5", timeStr, time.Local)
if err != nil {
return defValue
}
return retVal
}
func HTTPResponse2Json(response *http.Response) (map[string]interface{}, error) {
var jsonResult map[string]interface{}
bodyData, err := ioutil.ReadAll(response.Body)
if err != nil {
baseapi.SugarLogger.Errorf("ioutil.ReadAll error:%v, response:%v", err, response)
return nil, err
}
if err = UnmarshalUseNumber(bodyData, &jsonResult); err != nil {
return nil, err
}
return jsonResult, nil
}
func HTTPBody2Values(data []byte, needDecode bool) (url.Values, error) {
bodyStr := string(data)
if needDecode {
bodyStr1, err := url.QueryUnescape(bodyStr)
if err != nil {
baseapi.SugarLogger.Errorf("QueryUnescape error:%v, bodyStr:%v", err, bodyStr)
return nil, err
}
bodyStr = bodyStr1
}
result, err := url.ParseQuery(bodyStr)
if err != nil {
baseapi.SugarLogger.Errorf("ParseQuery error:%v, bodyStr:%v", err, bodyStr)
return nil, err
}
return result, nil
}
func Params2Map(key1, value1 interface{}, kv ...interface{}) (retVal map[string]interface{}) {
retVal = make(map[string]interface{})
retVal[key1.(string)] = value1
key := ""
for index, v := range kv {
if index%2 == 0 {
key = v.(string)
} else {
retVal[key] = v
}
}
return retVal
}
func URLValues2Map(values url.Values) (retVal map[string]interface{}) {
retVal = make(map[string]interface{})
for k := range values {
retVal[k] = values.Get(k)
}
return retVal
}
func Map2URLValues(mapData map[string]interface{}) (retVal url.Values) {
retVal = make(url.Values)
for k, v := range mapData {
retVal.Set(k, fmt.Sprint(v))
}
return retVal
}
func MapKV2List(mapData map[string]interface{}) []map[string]interface{} {
retVal := make([]map[string]interface{}, len(mapData))
index := 0
for _, v := range mapData {
retVal[index] = v.(map[string]interface{})
index++
}
return retVal
}
func Format4Output(obj interface{}, isSingleLine bool) (retVal string) {
retVal, ok := obj.(string)
if !ok {
var (
result []byte
err error
)
if isSingleLine {
if result, err = json.Marshal(obj); err == nil {
retVal = string(result)
}
} else {
if result, err = json.MarshalIndent(obj, "", "\t"); err == nil {
retVal = string(result)
}
}
if err != nil {
baseapi.SugarLogger.Infof("Format4Output Marshal:%v failed with error:%v", obj, err)
retVal = fmt.Sprintf("%v", obj)
}
}
return retVal
}