Files
bl/modules/player/service/talk.go
xinian f6aa0c3339
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
feat: 重构任务奖励系统并增加宠物技能和皮肤奖励
将任务奖励逻辑重构到单独的文件中,增加对宠物技能和皮肤奖励的支持,优化任务完成处理流程
2026-04-11 19:25:59 +08:00

126 lines
2.7 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"
configmodel "blazing/modules/config/model"
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) progress(flag int) (uint32, *model.Talk, *configmodel.MineralCollectionConfig, bool) {
var talks *model.Talk
s.dbm(s.Model).Where("talk_id", flag).Scan(&talks)
cfg := config.NewTalkConfigService().GetCache(flag)
if cfg == nil {
return 0, talks, nil, false
}
if talks == nil {
return 0, nil, cfg, true
}
switch cfg.Limit {
case 0:
if !utils.IsToday(talks.LastResetTime) {
s.reset(flag)
return 0, talks, cfg, true
}
case 1:
if !utils.IsWEEK(talks.LastResetTime) {
s.reset(flag)
return 0, talks, cfg, true
}
case 2:
if !utils.IsMon(talks.LastResetTime) {
s.reset(flag)
return 0, talks, cfg, true
}
}
return talks.Count, talks, cfg, true
}
func (s *TalkService) Progress(flag int) (uint32, bool) {
count, _, _, ok := s.progress(flag)
return count, ok
}
//实现挖矿次数确认
func (s *TalkService) Cheak(mapid uint32, flag int) (int, bool) {
count, _, cfg, ok := s.progress(flag)
if !ok || cfg == nil {
return 0, false //没在地图
}
if uint32(mapid) != cfg.MapID {
return 0, false //没在地图
}
if count >= cfg.DailyCollectCount {
return 0, false
}
return int(count), true //int(config.MaxDailyCnt - talks.Count)
}
func (s *TalkService) Update(flag int, count int) bool {
// VIP 直接返回失败
if cool.Config.ServerInfo.IsVip != 0 {
return true
}
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. 原子操作不存在则插入count=0存在则不操作
talk := model.Talk{
PlayerID: userID,
TalkID: talkID,
}
// 唯一索引 + InsertIgnore 保证只会插入1次
_, _ = db.Data(talk).InsertIgnore()
// 3. 原子条件自增(只有没超上限才会增加)
affected, err := db.
Where("talk_id = ?", talkID).
Where("player_id = ?", userID). // 关键:必须加 player_id 条件
Where("count + ? <= ?", count, maxCount).
Increment("count", count)
if err != nil {
return false
}
row, _ := affected.RowsAffected()
// 0 行受影响 = 已达上限
return row > 0
}