From 10c66436fdb2d0dcc394f2a48ab8cf10d3c63486 Mon Sep 17 00:00:00 2001 From: huzhe01 <47627651+huzhe01@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:34:17 +0800 Subject: [PATCH] fix(redenvelope): use local midnight for daily limit --- internal/apps/redenvelope/routers.go | 2 +- internal/apps/redenvelope/utils.go | 5 ++++ internal/apps/redenvelope/utils_test.go | 32 +++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 internal/apps/redenvelope/utils_test.go diff --git a/internal/apps/redenvelope/routers.go b/internal/apps/redenvelope/routers.go index a1e5df0c..2a258bc1 100644 --- a/internal/apps/redenvelope/routers.go +++ b/internal/apps/redenvelope/routers.go @@ -150,7 +150,7 @@ func Create(c *gin.Context) { // 查询今日已发送的红包数量 var todayCount int64 - today := time.Now().Truncate(24 * time.Hour) + today := startOfDay(time.Now()) if err := db.DB(c.Request.Context()).Model(&model.RedEnvelope{}). Where("creator_id = ? AND created_at >= ?", currentUser.ID, today). Count(&todayCount).Error; err != nil { diff --git a/internal/apps/redenvelope/utils.go b/internal/apps/redenvelope/utils.go index a3b26b3e..61053076 100644 --- a/internal/apps/redenvelope/utils.go +++ b/internal/apps/redenvelope/utils.go @@ -18,10 +18,15 @@ package redenvelope import ( "math/rand" + "time" "github.com/shopspring/decimal" ) +func startOfDay(now time.Time) time.Time { + return time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) +} + // calculateRandomAmount 二倍均值算法计算随机红包金额 func calculateRandomAmount(remaining decimal.Decimal, count int) decimal.Decimal { // 如果是最后一个红包,返回所有剩余金额(避免舍入误差) diff --git a/internal/apps/redenvelope/utils_test.go b/internal/apps/redenvelope/utils_test.go new file mode 100644 index 00000000..76aa617b --- /dev/null +++ b/internal/apps/redenvelope/utils_test.go @@ -0,0 +1,32 @@ +/* +Copyright 2025 linux.do + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package redenvelope + +import ( + "testing" + "time" +) + +func TestStartOfDayUsesLocalMidnight(t *testing.T) { + location := time.FixedZone("UTC+8", 8*60*60) + now := time.Date(2026, time.September, 4, 1, 30, 0, 0, location) + want := time.Date(2026, time.September, 4, 0, 0, 0, 0, location) + + if got := startOfDay(now); !got.Equal(want) { + t.Fatalf("startOfDay(%v) = %v, want %v", now, got, want) + } +}