From a9f93d5239867a543a4450d29a6825a37cf9a508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Mon, 19 Sep 2022 11:06:10 +0800 Subject: [PATCH] =?UTF-8?q?enhance(model):=E8=B0=83=E6=95=B4=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E7=9A=84=E6=97=A5=E6=9C=9F=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E5=8F=8A=E7=9B=B8=E5=85=B3=E7=9A=84=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controller/charge.go | 2 +- controller/user.go | 5 ++--- main.go | 2 +- model/types.go | 34 +++++++++++++++++++++++++++++++--- service/charge.go | 21 ++++++++------------- service/statistics.go | 2 +- service/user.go | 6 +++--- 7 files changed, 47 insertions(+), 25 deletions(-) diff --git a/controller/charge.go b/controller/charge.go index 596b860..643919b 100644 --- a/controller/charge.go +++ b/controller/charge.go @@ -46,7 +46,7 @@ type _NewChargeFormData struct { Fee decimal.NullDecimal `json:"fee" form:"fee"` Discount decimal.NullDecimal `json:"discount" form:"discount"` Amount decimal.NullDecimal `json:"amount" form:"amount"` - ChargeTo time.Time `json:"chargeTo" form:"chargeTo" time_format:"simple_date" time_location:"shanghai"` + ChargeTo model.Date `json:"chargeTo" form:"chargeTo"` } func recordNewCharge(c *gin.Context) { diff --git a/controller/user.go b/controller/user.go index dc18139..d67386a 100644 --- a/controller/user.go +++ b/controller/user.go @@ -12,7 +12,6 @@ import ( "fmt" "net/http" "strconv" - "time" "github.com/gin-gonic/gin" "github.com/shopspring/decimal" @@ -225,7 +224,7 @@ func createOPSAndManagementAccount(c *gin.Context) { newUserDetail.Contact = creationForm.Contact newUserDetail.Phone = creationForm.Phone newUserDetail.UnitServiceFee = decimal.Zero - newUserDetail.ServiceExpiration, _ = time.Parse("2006-01-02 15:04:05", "2099-12-31 23:59:59") + newUserDetail.ServiceExpiration, _ = model.ParseDate("2099-12-31") verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail) if err != nil { result.Error(http.StatusInternalServerError, err.Error()) @@ -290,7 +289,7 @@ func createEnterpriseAccount(c *gin.Context) { result.BadRequest("用户月服务费无法解析。") return } - newUserDetail.ServiceExpiration = time.Now() + newUserDetail.ServiceExpiration = model.NewEmptyDate() verifyCode, err := service.UserService.CreateUser(newUser, newUserDetail) if err != nil { diff --git a/main.go b/main.go index 208e987..e227a70 100644 --- a/main.go +++ b/main.go @@ -143,7 +143,7 @@ func intializeSingularity() error { Enabled: true, } singularityName := "Singularity" - singularityExpires, err := time.Parse("2006-01-02 15:04:05", "2099-12-31 23:59:59") + singularityExpires, err := model.ParseDate("2099-12-31") if err != nil { return fmt.Errorf("singularity expires time parse failed: %w", err) } diff --git a/model/types.go b/model/types.go index 0acd31c..1112532 100644 --- a/model/types.go +++ b/model/types.go @@ -19,10 +19,34 @@ func NewDate(t time.Time) Date { } t = t.In(loc) return Date{ - Time: time.Date(0, 1, 1, t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), loc), + Time: time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, loc), } } +func NewEmptyDate() Date { + loc, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + panic(err) + } + return Date{ + Time: time.Date(0, 1, 1, 0, 0, 0, 0, loc), + } +} + +func ParseDate(t string) (Date, error) { + loc, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + return NewEmptyDate(), fmt.Errorf("unable to load time zone, %w", err) + } + d, err := time.ParseInLocation("2006-01-02", t, loc) + if err != nil { + return NewEmptyDate(), fmt.Errorf("unable to parse given time, %w", err) + } + return Date{ + Time: d, + }, nil +} + var _ driver.Valuer = (*Date)(nil) func (d Date) Value() (driver.Value, error) { @@ -62,7 +86,7 @@ func (d *Date) Scan(src interface{}) (err error) { var _ json.Marshaler = (*Date)(nil) func (d Date) MarshalJSON() ([]byte, error) { - return []byte(d.Time.Format("2006-01-02")), nil + return json.Marshal(d.Time.Format("2006-01-02")) } var _ json.Unmarshaler = (*Date)(nil) @@ -72,7 +96,11 @@ func (d *Date) UnmarshalJSON(raw []byte) error { if err != nil { return fmt.Errorf("unable to load time zone, %w", err) } - s := string(raw) + var s string + err = json.Unmarshal(raw, &s) + if err != nil { + return fmt.Errorf("unable to unmarshal value, %w", err) + } d.Time, err = time.ParseInLocation("2006-01-02", s, loc) return err } diff --git a/service/charge.go b/service/charge.go index 0b49622..7714010 100644 --- a/service/charge.go +++ b/service/charge.go @@ -187,9 +187,9 @@ func (c _ChargeService) CancelCharge(seq int64, uid string) error { return nil } -func (ch _ChargeService) updateUserExpiration(tx *bun.Tx, ctx context.Context, uid string, expiration time.Time) error { +func (ch _ChargeService) updateUserExpiration(tx *bun.Tx, ctx context.Context, uid string, expiration model.Date) error { _, err := tx.NewUpdate().Model((*model.UserDetail)(nil)). - Set("service_expiration = ?", expiration.Format("2006-01-02")). + Set("service_expiration = ?", expiration). Where("id = ?", uid). Exec(ctx) if err != nil { @@ -264,26 +264,21 @@ func (_ChargeService) ListPagedChargeRecord(keyword, beginDate, endDate string, return chargesWithName, int64(total), err } -func (_ChargeService) lastValidChargeTo(tx *bun.Tx, ctx *context.Context, uid string) (time.Time, error) { - veryBlankTime, _ := time.Parse("2006-01-02 15:04:05", "0001-01-01 00:00:00") - var records []string +func (_ChargeService) lastValidChargeTo(tx *bun.Tx, ctx *context.Context, uid string) (model.Date, error) { + var records []model.Date err := tx.NewSelect().Table("user_charge"). Where("settled = ? and cancelled = ? and refunded = ? and user_id = ?", true, false, false, uid). Column("charge_to"). Scan(*ctx, &records) if err != nil { - return veryBlankTime, nil + return model.NewEmptyDate(), nil } - mappedRecords := lo.Map(records, func(elem string, index int) time.Time { - t, _ := time.Parse(time.RFC3339, elem) - return utils.BeginOfDay(t) - }) - lastValid := lo.Reduce(mappedRecords, func(acc, elem time.Time, index int) time.Time { - if elem.After(acc) { + lastValid := lo.Reduce(records, func(acc, elem model.Date, index int) model.Date { + if elem.Time.After(acc.Time) { return elem } else { return acc } - }, veryBlankTime) + }, model.NewEmptyDate()) return lastValid, nil } diff --git a/service/statistics.go b/service/statistics.go index 739e017..d500881 100644 --- a/service/statistics.go +++ b/service/statistics.go @@ -79,7 +79,7 @@ func (_StatisticsService) ParksNewestState(userIds ...string) ([]model.ParkPerio } for _, p := range parks { if c, ok := groupedParks[p.Id]; ok { - if c.Period != nil && p.Period != nil && p.Period.After(*c.Period) { + if c.Period != nil && p.Period != nil && p.Period.After(c.Period.Time) { groupedParks[p.Id] = p } if c.Period == nil && p.Period != nil { diff --git a/service/user.go b/service/user.go index e4abe6a..bb59a49 100644 --- a/service/user.go +++ b/service/user.go @@ -52,7 +52,7 @@ func (u _UserService) ProcessEnterpriseUserLogin(username, password string) (*mo return nil, authErr } userDetial, _ := u.retreiveUserDetail(user.Id) - if userDetial.ServiceExpiration.Before(time.Now()) { + if userDetial.ServiceExpiration.Time.Before(time.Now()) { return nil, exceptions.NewAuthenticationError(406, "用户服务期限已过。") } session := &model.Session{ @@ -310,7 +310,7 @@ func (_UserService) findUserWithCredentialsByUsername(username string) (*model.U ctx, cancel := global.TimeoutContext() defer cancel() user := new(model.UserWithCredentials) - err := global.DB.NewSelect().Model(&user).Where("username = ?", username).Scan(ctx) + err := global.DB.NewSelect().Model(user).Where("username = ?", username).Scan(ctx) if err == nil { cache.CacheSearch(*user, []string{fmt.Sprintf("user:%s", user.Id)}, "user_with_credentials", username) } @@ -340,7 +340,7 @@ func (_UserService) retreiveUserDetail(uid string) (*model.UserDetail, error) { user := &model.UserDetail{ Id: uid, } - err := global.DB.NewSelect().Model(&user).WherePK().Scan(ctx) + err := global.DB.NewSelect().Model(user).WherePK().Scan(ctx) if err == nil { cache.CacheEntity(*user, []string{fmt.Sprintf("user:%s", uid)}, "user_detail", uid) }