Files
bl/modules/player/service/talk.go
xinian 6767075dcd
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed
fix: 修复购买道具数量上限校验逻辑
2026-03-27 16:53:07 +08:00

124 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package service
import (
"blazing/common/utils"
"blazing/cool"
config "blazing/modules/config/service"
"blazing/modules/player/model"
"github.com/gogf/gf/v2/os/gtime"
)
type TalkService struct {
BaseService
}
func NewTalkService(id uint32) *TalkService {
return &TalkService{
BaseService: BaseService{userid: id,
Service: &cool.Service{Model: model.NewTalk()},
},
}
}
func (s *TalkService) reset(flag int) {
s.dbm(s.Model).Where("talk_id", flag).Data("count", 0, "last_reset_time", gtime.Now()).Update()
}
//实现挖矿次数确认
func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
m1 := s.dbm(s.Model)
var talks *model.Talk
m1.Where("talk_id", flag).Scan(&talks)
if talks == nil {
return 0, true //如果表里没有记载数据,那么就可以直接挖矿
}
c := config.NewTalkConfigService().GetCache(flag)
//因为这个是挖一次更新一次,而且是实时更新的,如果更新日期是今天,那么就可以确认不用再重置,否则就需要重置挖矿记录
if c == nil {
return 0, false //没在地图
}
switch c.Type {
case 0:
if !utils.IsToday(talks.LastResetTime) {
s.reset(flag)
return int(0), true
}
case 1:
if !utils.IsWEEK(talks.LastResetTime) {
s.reset(flag)
return int(0), true
}
case 2:
if !utils.IsMon(talks.LastResetTime) {
s.reset(flag)
return int(0), true
}
}
if uint32(mapid) != c.MapID {
return 0, false //没在地图
}
if talks.Count >= c.DailyCollectCount {
return 0, false
}
return int(talks.Count), true //int(config.MaxDailyCnt - talks.Count)
}
// Update 原子更新返回是否更新成功true=成功 false=上限/失败/VIP
func (s *TalkService) Update(flag int, count int) bool {
// VIP 直接返回失败
if cool.Config.ServerInfo.IsVip != 0 {
return false
}
talkID := uint32(flag)
userID := uint64(s.userid)
db := s.dbm(s.Model)
// 1. 获取配置上限
cfg := config.NewTalkConfigService().GetCache(flag)
if cfg == nil {
return false
}
maxCount := int(cfg.DailyCollectCount)
// 2. 原子插入(不存在则插入,存在忽略,高并发安全)
talk := model.NewTalk()
talk.PlayerID = userID
talk.TalkID = talkID
_, _ = db.Data(talk).FieldsEx("id").InsertIgnore()
// 3. 原子条件自增:只有没超过上限才会更新
// 核心:数据库原子判断,绝对不溢出
affected, err := db.
Where("talk_id = ?", talkID).
Where("count + ? <= ?", count, maxCount).
Increment("count", count)
if err != nil {
return false
}
row, _ := affected.RowsAffected()
// 有错误 或 没有影响行数 = 更新失败(已达上限)
if row == 0 {
return false
}
return true
}