统一时间格式和时区
This commit is contained in:
@@ -1,11 +1,23 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"affiliate_dash/internal/pkg/timeutil"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var (
|
||||
timeType = reflect.TypeOf(time.Time{})
|
||||
rawMessageType = reflect.TypeOf(json.RawMessage{})
|
||||
)
|
||||
|
||||
type Body struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
@@ -13,7 +25,11 @@ type Body struct {
|
||||
}
|
||||
|
||||
func OK(c *gin.Context, data interface{}) {
|
||||
c.JSON(http.StatusOK, Body{Code: 0, Message: "ok", Data: data})
|
||||
WithStatus(c, http.StatusOK, data)
|
||||
}
|
||||
|
||||
func WithStatus(c *gin.Context, httpStatus int, data interface{}) {
|
||||
c.JSON(httpStatus, Body{Code: 0, Message: "ok", Data: NormalizeTime(data)})
|
||||
}
|
||||
|
||||
func Fail(c *gin.Context, httpStatus int, code int, message string) {
|
||||
@@ -50,3 +66,127 @@ type PageData struct {
|
||||
func Page(c *gin.Context, list interface{}, total int64, page, size int) {
|
||||
OK(c, PageData{List: list, Total: total, Page: page, Size: size})
|
||||
}
|
||||
|
||||
func FormatTime(value time.Time) string {
|
||||
return timeutil.FormatAPITime(value)
|
||||
}
|
||||
|
||||
func NormalizeTime(value interface{}) interface{} {
|
||||
return normalizeTimeValue(reflect.ValueOf(value))
|
||||
}
|
||||
|
||||
func normalizeTimeValue(value reflect.Value) interface{} {
|
||||
if !value.IsValid() {
|
||||
return nil
|
||||
}
|
||||
if value.Kind() == reflect.Interface {
|
||||
if value.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return normalizeTimeValue(value.Elem())
|
||||
}
|
||||
if value.Type() == rawMessageType {
|
||||
return value.Interface()
|
||||
}
|
||||
if value.Type() == timeType {
|
||||
if !value.CanInterface() {
|
||||
return nil
|
||||
}
|
||||
return FormatTime(value.Interface().(time.Time))
|
||||
}
|
||||
switch value.Kind() {
|
||||
case reflect.Pointer:
|
||||
if value.IsNil() {
|
||||
return nil
|
||||
}
|
||||
if value.Type().Elem() == timeType {
|
||||
return FormatTime(value.Elem().Interface().(time.Time))
|
||||
}
|
||||
return normalizeTimeValue(value.Elem())
|
||||
case reflect.Slice, reflect.Array:
|
||||
if value.Kind() == reflect.Slice && value.IsNil() {
|
||||
return nil
|
||||
}
|
||||
if value.Type().Elem().Kind() == reflect.Uint8 {
|
||||
return value.Interface()
|
||||
}
|
||||
out := make([]interface{}, 0, value.Len())
|
||||
for i := 0; i < value.Len(); i++ {
|
||||
out = append(out, normalizeTimeValue(value.Index(i)))
|
||||
}
|
||||
return out
|
||||
case reflect.Map:
|
||||
if value.IsNil() {
|
||||
return nil
|
||||
}
|
||||
out := make(map[string]interface{}, value.Len())
|
||||
iter := value.MapRange()
|
||||
for iter.Next() {
|
||||
out[mapKeyString(iter.Key())] = normalizeTimeValue(iter.Value())
|
||||
}
|
||||
return out
|
||||
case reflect.Struct:
|
||||
return normalizeTimeStruct(value)
|
||||
default:
|
||||
if value.CanInterface() {
|
||||
return value.Interface()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func normalizeTimeStruct(value reflect.Value) map[string]interface{} {
|
||||
out := make(map[string]interface{}, value.NumField())
|
||||
valueType := value.Type()
|
||||
for i := 0; i < value.NumField(); i++ {
|
||||
field := valueType.Field(i)
|
||||
if field.PkgPath != "" {
|
||||
continue
|
||||
}
|
||||
name, skip, omitEmpty := jsonFieldName(field)
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
fieldValue := value.Field(i)
|
||||
if omitEmpty && fieldValue.IsZero() {
|
||||
continue
|
||||
}
|
||||
out[name] = normalizeTimeValue(fieldValue)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func jsonFieldName(field reflect.StructField) (string, bool, bool) {
|
||||
tag := field.Tag.Get("json")
|
||||
if tag == "-" {
|
||||
return "", true, false
|
||||
}
|
||||
if tag == "" {
|
||||
return field.Name, false, false
|
||||
}
|
||||
parts := strings.Split(tag, ",")
|
||||
name := parts[0]
|
||||
if name == "" {
|
||||
name = field.Name
|
||||
}
|
||||
return name, false, hasTagOption(parts[1:], "omitempty")
|
||||
}
|
||||
|
||||
func hasTagOption(options []string, target string) bool {
|
||||
for _, option := range options {
|
||||
if option == target {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func mapKeyString(value reflect.Value) string {
|
||||
if value.Kind() == reflect.String {
|
||||
return value.String()
|
||||
}
|
||||
if value.CanInterface() {
|
||||
return fmt.Sprint(value.Interface())
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user