feat: 新增服务器冠名CDK兑换功能
Some checks failed
ci/woodpecker/push/my-first-workflow Pipeline failed

This commit is contained in:
xinian
2026-04-08 15:49:03 +08:00
committed by cnb
parent 9825944efc
commit 1ca0ff344e
6 changed files with 194 additions and 72 deletions

View File

@@ -16,6 +16,7 @@ type CDKConfig struct {
// 核心字段
CDKCode string `gorm:"not null;size:16;uniqueIndex;comment:'CDK编号唯一标识用于玩家兑换'" json:"cdk_code" description:"CDK编号"`
CDKType uint32 `gorm:"column:type;not null;default:0;comment:'CDK类型:0普通奖励,1服务器冠名'" json:"type" description:"CDK类型"`
//cdk可兑换次数where不等于0
ExchangeRemainCount int64 `gorm:"not null;default:1;comment:'CDK剩余可兑换次数不能为0才允许兑换支持查询where !=0'" json:"exchange_remain_count" description:"剩余可兑换次数"`

View File

@@ -7,6 +7,7 @@ import (
"crypto/rand"
"fmt"
"math/big"
"time"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/errors/gerror"
@@ -17,6 +18,9 @@ import (
const charsetWithSymbol = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz"
const (
CDKTypeReward uint32 = 0
CDKTypeServerNaming uint32 = 1
cdkCodeLength = 16
maxBatchGenerateCount = 5000
)
@@ -156,6 +160,74 @@ func (s *CdkService) Set(id string) bool {
return true
}
func (s *CdkService) UseServerNamingCDK(ctx context.Context, code string, ownerID, serverID uint32, serverName string) (*model.ServerList, error) {
if ctx == nil {
ctx = context.TODO()
}
now := time.Now()
serverService := NewServerService()
var updated model.ServerList
err := g.DB(s.Model.GroupName()).Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
var cfg model.CDKConfig
if err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Scan(&cfg); err != nil {
return err
}
if cfg.ID == 0 {
return gerror.New("cdk不存在")
}
if cfg.CDKType != CDKTypeServerNaming {
return gerror.New("cdk类型不匹配")
}
if cfg.BindUserId != 0 && cfg.BindUserId != ownerID {
return gerror.New("cdk已绑定其他用户")
}
if !cfg.ValidEndTime.IsZero() && cfg.ValidEndTime.Before(now) {
return gerror.New("cdk已过期")
}
var server model.ServerList
if err := tx.Model(model.NewServerList()).Where("online_id", serverID).Scan(&server); err != nil {
return err
}
if !serverService.CanUseDonationName(server, now) {
return gerror.New("服务器不可冠名")
}
res, err := tx.Model(s.Model).Where("cdk_code", code).WhereNot("exchange_remain_count", 0).Decrement("exchange_remain_count", 1)
if err != nil {
return err
}
rows, _ := res.RowsAffected()
if rows == 0 {
return gerror.New("cdk已被使用")
}
baseTime := now
if server.ExpireTime.After(now) {
baseTime = server.ExpireTime
}
updated = server
updated.Name = serverName
updated.Owner = ownerID
updated.ExpireTime = baseTime.AddDate(0, 1, 0)
_, err = tx.Model(model.NewServerList()).Where("online_id", serverID).Data(g.Map{
"name": updated.Name,
"owner": updated.Owner,
"expire_time": updated.ExpireTime,
}).Update()
return err
})
if err != nil {
return nil, err
}
g.DB(s.Model.GroupName()).GetCore().ClearCache(context.TODO(), s.Model.TableName())
g.DB(model.NewServerList().GroupName()).GetCore().ClearCache(context.TODO(), model.NewServerList().TableName())
return &updated, nil
}
func (s *CdkService) BatchGenerate(ctx context.Context, count int) (interface{}, error) {
if count <= 0 {
return nil, gerror.New("生成数量必须大于0")

View File

@@ -6,6 +6,7 @@ import (
"blazing/modules/config/model"
"fmt"
"sort"
"time"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
@@ -130,6 +131,35 @@ func (s *ServerService) GetServerID(OnlineID uint32) model.ServerList {
}
func (s *ServerService) GetDonationAvailableServerIDs() []uint32 {
now := time.Now()
builder := dbm_nocache_noenable(s.Model).Builder().Where("owner", 0).WhereOr("expire_time <= ?", now)
var rows []struct {
OnlineID uint32 `json:"online_id"`
}
dbm_nocache_noenable(s.Model).Fields("online_id").Where(builder).OrderAsc("online_id").Scan(&rows)
ids := make([]uint32, 0, len(rows))
for _, row := range rows {
if row.OnlineID == 0 {
continue
}
ids = append(ids, row.OnlineID)
}
return ids
}
func (s *ServerService) CanUseDonationName(server model.ServerList, now time.Time) bool {
if server.OnlineID == 0 {
return false
}
if server.Owner == 0 {
return true
}
return !server.ExpireTime.After(now)
}
// 保存版本号
func (s *ServerService) SetServerScreen(id uint32, name string) {