diff --git a/pkg/u/u.go b/pkg/u/u.go index 6c193de..3c9c26b 100644 --- a/pkg/u/u.go +++ b/pkg/u/u.go @@ -12,6 +12,15 @@ func Today() time.Time { return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) } +func Date(date time.Time) time.Time { + return time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, date.Location()) +} + +func SameDate(date time.Time) bool { + var now = time.Now() + return date.Year() == now.Year() && date.Month() == now.Month() && date.Day() == now.Day() +} + func Z[T any](v *T) T { if v == nil { var zero T diff --git a/web/domains/user/types.go b/web/domains/user/types.go index 0209ff9..0207fa8 100644 --- a/web/domains/user/types.go +++ b/web/domains/user/types.go @@ -7,3 +7,10 @@ const ( IdTypePersonal // 个人认证 IdTypeEnterprise // 企业认证 ) + +type Status int32 + +const ( + StatusDisabled Status = iota // 禁用 + StatusEnabled // 启用 +) diff --git a/web/handlers/iden.go b/web/handlers/iden.go index 4b1b243..96f6d0f 100644 --- a/web/handlers/iden.go +++ b/web/handlers/iden.go @@ -7,6 +7,7 @@ import ( "platform/pkg/env" "platform/pkg/u" "platform/web/auth" + "platform/web/core" g "platform/web/globals" m "platform/web/models" q "platform/web/queries" @@ -74,6 +75,15 @@ func Identify(c *fiber.Ctx) error { return err } + if resp.Error.Code != 0 { + var msg string + switch resp.Error.Code { + case 1007: + msg = "身份证号码格式错误" + } + return core.NewBizErr(fmt.Sprintf("活体认证失败: %s", msg)) + } + // 保存认证中间状态 info := idenInfo{ Uid: authCtx.Payload.Id, diff --git a/web/handlers/resource.go b/web/handlers/resource.go index b7b16bc..3479da0 100644 --- a/web/handlers/resource.go +++ b/web/handlers/resource.go @@ -241,15 +241,15 @@ type StatisticPersonalResp struct { } type StatisticShort struct { - ResourceCount int - ResourceQuotaSum int - ResourceDailyFreeSum int + ResourceCount int `json:"resource_count"` + ResourceQuotaSum int `json:"resource_quota_sum"` + ResourceDailyFreeSum int `json:"resource_daily_free_sum"` } type StatisticLong struct { - ResourceCount int - ResourceQuotaSum int - ResourceDailyFreeSum int + ResourceCount int `json:"resource_count"` + ResourceQuotaSum int `json:"resource_quota_sum"` + ResourceDailyFreeSum int `json:"resource_daily_free_sum"` } func StatisticResourceFree(c *fiber.Ctx) error { @@ -260,7 +260,7 @@ func StatisticResourceFree(c *fiber.Ctx) error { } // 统计套餐剩余数量 - resources, err := q.Resource. + resources, err := q.Resource.Debug(). Preload( q.Resource.Short, q.Resource.Long, @@ -269,7 +269,7 @@ func StatisticResourceFree(c *fiber.Ctx) error { q.Resource.UserID.Eq(session.Payload.Id), q.Resource.Active.Is(true), ). - Select(q.Resource.ID). + Select(q.Resource.ID, q.Resource.Type). Find() if err != nil { return err @@ -297,7 +297,7 @@ func StatisticResourceFree(c *fiber.Ctx) error { // 短效包时 case resource2.Type(resource.Type) == resource2.TypeShort && resource2.Mode(resource.Short.Type) == resource2.ModeTime: if time.Time(*resource.Short.Expire).After(time.Now()) { - if time.Time(*resource.Short.DailyLast) != u.Today() { + if resource.Short.DailyLast == nil || u.SameDate(time.Time(*resource.Short.DailyLast)) == false { shortCount++ shortDailyFreeSum += int(resource.Short.DailyLimit) } else if resource.Short.DailyLimit > resource.Short.DailyUsed { @@ -309,7 +309,7 @@ func StatisticResourceFree(c *fiber.Ctx) error { // 长效包时 case resource2.Type(resource.Type) == resource2.TypeLong && resource2.Mode(resource.Long.Type) == resource2.ModeTime: if time.Time(*resource.Long.Expire).After(time.Now()) { - if time.Time(*resource.Long.DailyLast) != u.Today() { + if resource.Long.DailyLast == nil || u.SameDate(time.Time(*resource.Long.DailyLast)) == false { longCount++ longDailyFreeSum += int(resource.Long.DailyLimit) } else if resource.Long.DailyLimit > resource.Long.DailyUsed { @@ -359,7 +359,7 @@ func StatisticResourceUsage(c *fiber.Ctx) error { } // 统计套餐提取数量 - do := q.LogsUserUsage.Where() + do := q.LogsUserUsage.Where(q.LogsUserUsage.UserID.Eq(session.Payload.Id)) if req.ResourceNo != nil && *req.ResourceNo != "" { var resourceID int32 err := q.Resource. @@ -382,15 +382,12 @@ func StatisticResourceUsage(c *fiber.Ctx) error { } var data = new(StatisticResourceUsageResp) - err = q.LogsUserUsage. + err = q.LogsUserUsage.Debug(). Select( q.LogsUserUsage.Count_.Sum().As("count"), field.NewUnsafeFieldRaw("date_trunc('day', time)").As("date"), ). - Where( - q.LogsUserUsage.UserID.Eq(session.Payload.Id), - do, - ). + Where(do). Group( field.NewUnsafeFieldRaw("date_trunc('day', time)"), ). diff --git a/web/handlers/trade.go b/web/handlers/trade.go index dc47401..a4bc4b4 100644 --- a/web/handlers/trade.go +++ b/web/handlers/trade.go @@ -105,6 +105,7 @@ type TradeCheckReq struct { } func TradeCheckSSE(c *fiber.Ctx) error { + // 设置响应头 c.Set("Content-Type", "text/event-stream") c.Set("Cache-Control", "no-cache") diff --git a/web/services/auth.go b/web/services/auth.go index a21fdf7..0d21551 100644 --- a/web/services/auth.go +++ b/web/services/auth.go @@ -3,9 +3,13 @@ package services import ( "context" "errors" + "golang.org/x/crypto/bcrypt" + "log/slog" "platform/pkg/u" auth2 "platform/web/auth" + "platform/web/core" client2 "platform/web/domains/client" + user2 "platform/web/domains/user" "platform/web/globals/orm" m "platform/web/models" q "platform/web/queries" @@ -84,23 +88,35 @@ func (s *authService) OauthPassword(ctx context.Context, _ *m.Client, data *Gran return err } case auth2.GrantPasswordEmail: - var err error - user, err = tx.User.Where(tx.User.Email.Eq(data.Username)).Take() - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - return err - } + return core.NewServErr("邮箱登录暂不可用") case auth2.GrantPasswordSecret: var err error user, err = tx.User. - Where(tx.User.Or( - tx.User.Phone.Eq(data.Username), - tx.User.Email.Eq(data.Username), - tx.User.Username.Eq(data.Username), - )). + Where(tx.User.Phone.Eq(data.Username)). + Or(tx.User.Email.Eq(data.Username)). + Or(tx.User.Username.Eq(data.Username)). Take() - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - return err + if err != nil { + slog.Debug("查找用户失败", "error", err) + return core.NewBizErr("用户不存在或密码错误") } + + // 账户状态 + if user2.Status(user.Status) == user2.StatusDisabled { + slog.Debug("账户状态异常", "username", data.Username, "status", user.Status) + return core.NewBizErr("用户不存在或密码错误") + } + + // 验证密码 + if user.Password == nil || *user.Password == "" { + slog.Debug("用户未设置密码", "username", data.Username) + return core.NewBizErr("用户不存在或密码错误") + } + if bcrypt.CompareHashAndPassword([]byte(*user.Password), []byte(data.Password)) != nil { + slog.Debug("密码验证失败", "username", data.Username) + return core.NewBizErr("用户不存在或密码错误") + } + default: return ErrOauthInvalidRequest } @@ -117,7 +133,7 @@ func (s *authService) OauthPassword(ctx context.Context, _ *m.Client, data *Gran user.LastLogin = u.P(orm.LocalDateTime(time.Now())) user.LastLoginHost = u.P(ip) user.LastLoginAgent = u.P(agent) - if err := tx.User.Omit(q.User.AdminID).Save(user); err != nil { + if err := tx.User.Save(user); err != nil { return err }