存储到数据库为时间格式,json 序列化与反序列化为时间戳
import (
"database/sql/driver"
"encoding/json"
"fmt"
"github.com/jinzhu/gorm"
"strconv"
"time"
)
type GormBase struct {
CreatedAt JSONTime `json:"created_at" gorm:"type:timestamp"`
UpdateAt JSONTime `json:"updated_at" gorm:"type:timestamp"`
DeletedAt *time.Time `json:"-" gorm:"type:timestamp"`
}
type JSONTime struct {
Time time.Time
}
/*
*@ date 2019-04-19
*@ author majianyu
*@ description only support second
*/
func (this JSONTime) MarshalJSON() ([]byte, error) {
return json.Marshal(this.Time.Unix())
}
/*
*@ date 2019-04-19
*@ author majianyu
*@ description support second and millisecond parse
*/
func (this *JSONTime) UnmarshalJSON(b []byte) error {
str := string(b)
ts, err := strconv.ParseInt(str, 10, 64)
if err != nil {
return err
}
if len(str) == 10 {
// second
this.Time = time.Unix(ts, 0)
} else if len(str) == 13 {
// millisecond
this.Time = time.Unix(0, ts*1e6)
} else {
return fmt.Errorf("can not convert %s to time", str)
}
return nil
}
func (this JSONTime) Value() (driver.Value, error) {
var zeroTime time.Time
if this.Time.UnixNano() == zeroTime.UnixNano() {
return nil, nil
}
return this.Time, nil
}
func (this *JSONTime) Scan(v interface{}) error {
value, ok := v.(time.Time)
if ok {
*this = JSONTime{Time: value}
return nil
}
return fmt.Errorf("can not convert %v to timestamp", v)
}
func (g *GormBase) BeforeUpdate(scope *gorm.Scope) error {
scope.SetColumn("UpdateAt", time.Now())
return nil
}
func (g *GormBase) BeforeCreate(scope *gorm.Scope) error {
if g.UpdateAt.Time.Unix() <= 0 {
scope.SetColumn("UpdateAt", time.Now())
}
scope.SetColumn("CreatedAt", time.Now())
return nil
}
type Report struct {
tableName struct{} `sql:"toptutor.report"`
CourseID string `json:"course_id" gorm:"type:uuid"`
OrderID string `json:"order_id" gorm:"type:uuid"`
Questions []Question `json:"questions" gorm:"type:jsonb"`
gormstruct.GormBase
}
type Question struct {
ID int `json:"id"`
Question string `json:"question"`
Answer string `json:"answer"`
ZhQuestion string `json:"zh_question"`
ZhAnswer string `json:"zh_answer"`
}
func (this *Question) Scan(v interface{}) error {
value, ok := v.([]byte)
if ok {
q := Question{}
err := json.Unmarshal(value, &q)
if err != nil {
return fmt.Errorf("can not convert %v to Question", v)
}
*this = q
return nil
}
return fmt.Errorf("can not convert %v to Question", v)
}
func (this Question) Value() (driver.Value, error) {
bytes, err := json.Marshal(this)
if err != nil {
return nil, err
}
return bytes, nil
}