package daytask import ( "app/commons/model/entity" "github.com/gin-gonic/gin" "time" ) // SignInfo 签到信息 func (s *Server) SignInfo(c *gin.Context) { ctx := s.FromContext(c) db := s.DB() userId := ctx.UserId() // 获取用户信息 user := &entity.DtUser{} if err := db.Where("id = ?", userId).First(user).Error; err != nil { ctx.Fail("user_not_found") return } // 获取今日签到记录 today := time.Now().Format("2006-01-02") var todaySign entity.DtUserSign todaySigned := false if err := db.Where("user_id = ? AND sign_date = ?", userId, today).First(&todaySign).Error; err == nil { todaySigned = true } // 获取本月签到记录 month := time.Now().Format("2006-01") var monthSigns []entity.DtUserSign db.Where("user_id = ? AND month = ?", userId, month). Order("sign_date ASC"). Find(&monthSigns) // 构建签到日历 signDates := make([]string, 0) for _, sign := range monthSigns { signDates = append(signDates, sign.SignDate) } // 构建奖励配置 rewards := make([]gin.H, 0) for i, reward := range entity.SignRewardConfig { rewards = append(rewards, gin.H{ "day": i + 1, "reward": reward, }) } ctx.OK(gin.H{ "continuousDays": user.ContinuousSignDays, "totalDays": user.TotalSignDays, "todaySigned": todaySigned, "signDates": signDates, "rewards": rewards, }) } // SignDo 执行签到 func (s *Server) SignDo(c *gin.Context) { ctx := s.FromContext(c) db := s.DB() userId := ctx.UserId() // 检查今日是否已签到 today := time.Now().Format("2006-01-02") month := time.Now().Format("2006-01") var existSign entity.DtUserSign if err := db.Where("user_id = ? AND sign_date = ?", userId, today).First(&existSign).Error; err == nil { ctx.Fail("already_signed") return } // 获取用户信息 user := &entity.DtUser{} if err := db.Where("id = ?", userId).First(user).Error; err != nil { ctx.Fail("user_not_found") return } // 检查昨天是否签到,判断是否连续 yesterday := time.Now().AddDate(0, 0, -1).Format("2006-01-02") var yesterdaySign entity.DtUserSign isContinuous := false if err := db.Where("user_id = ? AND sign_date = ?", userId, yesterday).First(&yesterdaySign).Error; err == nil { isContinuous = true } // 计算连续签到天数 continuousDays := 1 if isContinuous { continuousDays = user.ContinuousSignDays + 1 } // 根据连续天数获取奖励(8天循环) dayIndex := (continuousDays - 1) % len(entity.SignRewardConfig) reward := entity.SignRewardConfig[dayIndex] // 开启事务 tx := db.Begin() // 创建签到记录 sign := &entity.DtUserSign{ UserId: userId, SignDate: today, SignDay: continuousDays, RewardAmount: reward, Month: month, } if err := tx.Create(sign).Error; err != nil { tx.Rollback() ctx.Fail("sign_failed") return } // 更新用户签到信息和余额(原子操作) updates := map[string]interface{}{ "continuous_sign_days": continuousDays, "total_sign_days": db.Raw("total_sign_days + 1"), "balance": db.Raw("balance + ?", reward), } if err := tx.Model(&entity.DtUser{}).Where("id = ?", userId).Updates(updates).Error; err != nil { tx.Rollback() ctx.Fail("sign_failed") return } // 重新查询更新后的余额 var updatedUser entity.DtUser tx.Where("id = ?", userId).First(&updatedUser) // 记录余额变动 balanceLog := &entity.DtBalanceLog{ UserId: userId, Type: entity.BalanceLogTypeSignReward, Amount: reward, BeforeBalance: updatedUser.Balance - reward, AfterBalance: updatedUser.Balance, Remark: ctx.I18n("sign_reward"), } if err := tx.Create(balanceLog).Error; err != nil { tx.Rollback() ctx.Fail("sign_failed") return } tx.Commit() ctx.OK(gin.H{ "reward": reward, "continuousDays": continuousDays, "totalDays": user.TotalSignDays + 1, }) }