```
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful

refactor(service): 重构宠物捕捉击杀统计功能

- 移除Barge服务和相关模型,统一使用Done服务进行里程碑数据管理
- 更新PetBargeList接口实现,从Barge服务切换到Done服务
- 修改战斗循环中宠物捕捉击杀数据的更新逻辑
- 调整里程碑模型中的Results字段类型为uint32数组

feat(done): 新增宠物里程碑数据管理功能

- 实现UpdatePet方法用于更新宠物捕捉击杀统计数据
- 添加update和get内部方法处理
This commit is contained in:
昔念
2026-01-31 19:10:36 +08:00
parent 53902a7a2e
commit b12dd742e6
9 changed files with 105 additions and 205 deletions

View File

@@ -12,14 +12,14 @@ func (h Controller) GetPetBargeList(data *pet.PetBargeListInboundInfo, player *p
ret := &pet.PetBargeListOutboundInfo{
PetBargeList: make([]pet.PetBargeListInfo, 0),
}
r := player.Service.Barge.Get(data.StartPetId, data.EndPetId)
r := player.Service.Done.PetBarge(data.StartPetId, data.EndPetId)
for _, v := range r {
ret.PetBargeList = append(ret.PetBargeList, pet.PetBargeListInfo{
PetId: v.PetId,
PetId: uint32(v.Args[0]),
EnCntCnt: 1,
IsCatched: v.CatchedCount,
IsKilled: v.KilledCount,
IsCatched: uint32(v.Results[0]),
IsKilled: uint32(v.Results[1]),
})
}

View File

@@ -93,6 +93,7 @@ func (f *FightC) battleLoop() {
})
if f.Info.Status == info.BattleMode.FIGHT_WITH_NPC {
if f.Reason == info.BattleOverReason.Cacthok {
f.WinnerId = f.ownerID
f.Opp.Player.GetInfo().PetList[0].EffectInfo = nil //清空特性信息
@@ -102,11 +103,13 @@ func (f *FightC) battleLoop() {
CatchTime: uint32(f.Opp.Player.GetInfo().PetList[0].CatchTime),
PetId: uint32(f.Opp.CurrentPet.ID),
})
defer f.Our.Player.(*player.Player).Service.Barge.Update(f.Opp.Player.GetInfo().PetList[0].ID, false)
defer f.Our.Player.(*player.Player).Service.Done.UpdatePet(f.Opp.Player.GetInfo().PetList[0], 0, 1)
//f.Reason = 0 //清空
}
if f.Reason == 0 {
defer f.Our.Player.(*player.Player).Service.Barge.Update(f.Opp.Player.GetInfo().PetList[0].ID, true)
defer f.Our.Player.(*player.Player).Service.Done.UpdatePet(f.Opp.Player.GetInfo().PetList[0], 1, 0)
}
f.Our.Player.(*player.Player).GenMonster()

View File

@@ -61,8 +61,11 @@ func (s *ShinyService) RandShiny(id uint32) *data.GlowFilter {
r := json.Unmarshal([]byte(v.Color), &t)
if r == nil {
m := cool.DBM(s.Model).Where("id", id)
m.Increment("refresh_count", 1)
if cool.Config.ServerInfo.IsVip == 0 {
m := cool.DBM(s.Model).Where("id", id)
m.Increment("refresh_count", 1)
}
return &t
}
@@ -88,8 +91,11 @@ func (s *ShinyService) FixShiny(id uint32) *data.GlowFilter {
r := json.Unmarshal([]byte(v.Color), &t)
if r == nil {
m := cool.DBM(s.Model).Where("id", v.ID)
m.Increment("usage_count", 1)
if cool.Config.ServerInfo.IsVip == 0 {
m := cool.DBM(s.Model).Where("id", v.ID)
m.Increment("usage_count", 1)
}
return &t
}

View File

@@ -1,92 +0,0 @@
package model
import (
"blazing/cool"
"errors"
)
// 表名常量定义:精灵捕捉击杀数量记录表
const (
TableNamePetCatchKillCount = "player_catch_kill_count" // 精灵捕捉击杀数量表(记录每个精灵的捕捉总数量、击杀总数量)
)
// PetBargeListInfo 精灵捕捉击杀数量核心模型(简化版,直接记录数量,摒弃状态判断)
type PetBargeListInfo struct {
Base
PlayerID uint64 `gorm:"not null;index:idx_milestone_by_player_id;comment:'所属玩家ID'" json:"player_id"`
PetId uint32 `gorm:"not null;default:0;comment:'精灵ID关联config_pet_boss表主键'" json:"pet_id" description:"精灵ID"`
EnCntCnt uint32 `gorm:"not null;default:0;comment:'预留未知字段,暂未使用'" json:"en_cnt_cnt" description:"未知"`
CatchedCount uint32 `gorm:"not null;default:0;comment:'精灵捕捉总数量'" json:"catched_count" description:"捕捉数量"` // 替换原IsCatched记录捕捉总数
KilledCount uint32 `gorm:"not null;default:0;comment:'精灵击杀总数量'" json:"killed_count" description:"击杀数量"` // 替换原IsKilled记录击杀总数
}
// -------------------------- 核心配套方法 --------------------------
// TableName 指定模型对应的数据库表名(遵循项目规范)
func (*PetBargeListInfo) TableName() string {
return TableNamePetCatchKillCount
}
// GroupName 指定表所属分组(与其他精灵表保持一致)
func (*PetBargeListInfo) GroupName() string {
return "default"
}
// NewPetBargeListInfo 创建精灵捕捉击杀数量实例(初始化默认值)
func NewPetBargeListInfo() *PetBargeListInfo {
return &PetBargeListInfo{
Base: *NewBase(),
}
}
// AddCatchedCount 增加捕捉数量支持批量累加默认累加1
// addNum要增加的数量需大于0
func (p *PetBargeListInfo) AddCatchedCount(addNum uint32) error {
if addNum <= 0 {
return errors.New("增加的捕捉数量必须大于0")
}
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法累加捕捉数量")
}
p.CatchedCount += addNum
return nil
}
// AddKilledCount 增加击杀数量支持批量累加默认累加1
// addNum要增加的数量需大于0
func (p *PetBargeListInfo) AddKilledCount(addNum uint32) error {
if addNum <= 0 {
return errors.New("增加的击杀数量必须大于0")
}
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法累加击杀数量")
}
p.KilledCount += addNum
return nil
}
// SetCatchedCount 直接设置捕捉数量(适用于批量初始化/重置)
// count目标捕捉数量非负数
func (p *PetBargeListInfo) SetCatchedCount(count uint32) error {
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法设置捕捉数量")
}
p.CatchedCount = count
return nil
}
// SetKilledCount 直接设置击杀数量(适用于批量初始化/重置)
// count目标击杀数量非负数
func (p *PetBargeListInfo) SetKilledCount(count uint32) error {
if p.PetId == 0 {
return errors.New("精灵ID不能为空无法设置击杀数量")
}
p.KilledCount = count
return nil
}
// -------------------------- 表结构自动同步 --------------------------
func init() {
// 程序启动时自动创建/同步精灵捕捉击杀数量表
cool.CreateTable(&PetBargeListInfo{})
}

View File

@@ -43,7 +43,7 @@ type Milestone struct {
DoneType EnumMilestone `gorm:"not null;comment:'里程碑类型'" json:"done_type"`
Args []int32 `gorm:"type:jsonb;not null;comment:'里程碑ID'" json:"args"`
// 注:不单独设置"里程碑ID",通过 PlayerID + DoneType + IDs 组合唯一标识一个里程碑(更灵活)
Results []int32 `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"`
Results []uint32 `gorm:"type:jsonb;not null;comment:'里程碑参数'" json:"results"`
}
// // MilestoneEX 里程碑扩展结构体,用于业务层解析后的数据操作

View File

@@ -1,60 +0,0 @@
package service
import (
"blazing/cool"
"blazing/modules/player/model"
"context"
"github.com/gogf/gf/v2/frame/g"
)
type BargeService struct {
BaseService
}
func NewBargeService(id uint32) *BargeService {
return &BargeService{
BaseService: BaseService{userid: id,
Service: &cool.Service{Model: model.NewPetBargeListInfo()},
},
}
}
func (s *BargeService) Update(petid uint32, isskill bool) {
if cool.Config.ServerInfo.IsVip != 0 {
cool.Logger.Info(context.TODO(), "测试服不消耗物品玩家数据", s.userid)
return
}
if t, _ := s.PModel(s.Model).Where("pet_id", petid).Exist(); t {
if isskill {
s.PModel(s.Model).Where("pet_id", petid).Increment("killed_count", 1)
} else {
s.PModel(s.Model).Where("pet_id", petid).Increment("catched_count", 1)
}
} else {
r := g.Map{
"player_id": s.userid,
"pet_id": petid,
}
if isskill {
r["killed_count"] = 1
} else {
r["catched_count"] = 1
}
s.PModel(s.Model).Data(r).Insert()
}
}
func (s *BargeService) Get(start, end uint32) []model.PetBargeListInfo {
var Barges []model.PetBargeListInfo
s.PModel(s.Model).WhereBetween("pet_id", start, end).Scan(&Barges)
return Barges
}

View File

@@ -3,45 +3,16 @@ package service
import (
"blazing/cool"
"blazing/modules/player/model"
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
)
type DoneService struct {
BaseService
}
// func (s *DoneService) Exec(data model.EnumMilestone, id []uint32, fn func(*model.MilestoneEX) bool) {
// if cool.Config.ServerInfo.IsVip != 0 {
// cool.Logger.Info(context.TODO(), "测试服不消耗物品玩家数据", s.userid)
// return
// }
// arss := strings.Join(gconv.Strings(id), "-")
// m := s.PModel(s.Model).Where("done_type", data).Where("args", arss)
// var tt *model.MilestoneEX
// m.Scan(&tt)
// if tt == nil {
// tt = &model.MilestoneEX{
// Milestone: model.Milestone{
// DoneType: data,
// Args: strings.Join(gconv.Strings(id), "-"),
// //Count: 1,
// },
// }
// }
// tt.Args = id
// ook := fn(tt)
// if !ook { //不需要保存
// return
// }
// tt.PlayerID = uint64(s.userid)
// tt.Milestone.Args = strings.Join(gconv.Strings(id), "-")
// _, err := m.Save(tt)
// if err != nil {
// panic(err)
// }
// }
func NewDoneService(id uint32) *DoneService {
return &DoneService{
@@ -54,3 +25,75 @@ func NewDoneService(id uint32) *DoneService {
}
}
// ID
// 击杀-捕捉
func (s *DoneService) UpdatePet(ptye model.PetInfo, res ...uint32) {
//属性->属性值->ID 击杀-捕捉-炫彩击杀-炫彩捕捉
args := []uint32{ptye.ID}
r1 := s.get(model.MilestoneMode.Pet, args)
results := make([]uint32, len(res))
if r1 != nil {
results = r1.Results
}
for i, v := range res {
results[i] += v
}
s.update(model.MilestoneMode.Pet, args, results)
}
// 内部方法,实现更新
func (s *DoneService) update(ptye model.EnumMilestone, args []uint32, results []uint32) {
if cool.Config.ServerInfo.IsVip != 0 {
cool.Logger.Info(context.TODO(), "测试服不消耗物品玩家数据", s.userid)
return
}
ar := gconv.String(args)
if t, _ := s.PModel(s.Model).Where("done_type", ptye).Wheref(`args @> ?::jsonb`, ar).
Wheref(`jsonb_typeof(args) = ?`, "array").Exist(); t {
s.PModel(s.Model).Where("done_type", ptye).Wheref(`args @> ?::jsonb`, ar).
Wheref(`jsonb_typeof(args) = ?`, "array").Data(
g.Map{
"results": results,
},
).Update()
} else {
r := g.Map{
"player_id": s.userid,
"done_type": ptye,
"args": args,
"results": results,
}
s.PModel(s.Model).Data(r).Insert()
}
}
func (s *DoneService) get(ptye model.EnumMilestone, args []uint32) *model.Milestone {
var Barges *model.Milestone
s.PModel(s.Model).Where("done_type", ptye).Wheref(`args @> ?::jsonb`, args).
Wheref(`jsonb_typeof(args) = ?`, "array").Scan(&Barges)
return Barges
}
func (s *DoneService) PetBarge(start, end uint32) []model.Milestone {
var Barges []model.Milestone
s.PModel(s.Model).Where("done_type", model.MilestoneMode.Pet).
Wheref(`jsonb_typeof(args) = ?`, "array").
Wheref(`jsonb_typeof(args) != ?`, "'[]'::jsonb").
Wheref(`(args->> 0)::int BETWEEN ? AND ?`, start, end).
Scan(&Barges)
return Barges
}

View File

@@ -37,6 +37,7 @@ func (s *PetService) PetCount(flag int) int {
return ret
}
func (s *PetService) UPdateFree(ctime uint32, free uint32) {
s.TestModel(s.Model).Where("player_id", s.userid).Where("catch_time", ctime).Data(

View File

@@ -18,7 +18,6 @@ type UserService struct {
Item *ItemService //物品
Done *DoneService //完成
Room *RoomService
Barge *BargeService
Title *TitleService
Cdk *CdkService
Friend *FriendService
@@ -28,14 +27,14 @@ type UserService struct {
func NewUserService(id uint32) *UserService {
return &UserService{
Task: NewTaskService(id),
Info: NewInfoService(id),
Pet: NewPetService(id),
Item: NewItemService(id),
Talk: NewTalkService(id),
Done: NewDoneService(id),
Room: NewRoomService(id),
Barge: NewBargeService(id),
Task: NewTaskService(id),
Info: NewInfoService(id),
Pet: NewPetService(id),
Item: NewItemService(id),
Talk: NewTalkService(id),
Done: NewDoneService(id),
Room: NewRoomService(id),
Title: NewTitleService(id),
Cdk: NewCdkService(id),
Friend: NewFriendService(id),