samba/server/other/handler/codeHandler.go

211 lines
5.0 KiB
Go
Raw Permalink Normal View History

2025-06-04 09:51:39 +08:00
package handler
import (
"errors"
"fmt"
"github.com/rabbitmq/amqp091-go"
"samba/pkg/log"
"samba/pkg/xtime"
"samba/proto"
"samba/server/other/code"
"samba/stub"
"samba/util/model"
"samba/util/routingKey"
"samba/util/util"
"time"
)
// onReqGenerateCode 生成兑换码
func onReqGenerateCode(d *amqp091.Delivery, msg map[string]any) {
_, _, _, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqGenerateCode](data)
if err != nil {
log.Error(err.Error())
return
}
rule := model.Rule(req.Rule)
r := &model.RedeemCode{
Code: req.Code,
StartTime: xtime.TimestampToTime(req.StartTime).StdTime(),
EndTime: xtime.TimestampToTime(req.EndTime).StdTime(),
Count: req.Count,
Item: (*model.Items)(&req.Item),
Rule: &rule,
CreateTime: xtime.Now().StdTime(),
}
rsp := &proto.RspGenerateCode{}
err = code.CodeManager.AddCode(r)
if err != nil {
rsp.Code = util.TieOrFn(errors.Is(err, code.ErrCodeIsExists), proto.CodeIsExist, func() proto.ErrorCode {
log.Error(err.Error())
return proto.Internal
})
rsp.Msg = err.Error()
}
SendMsgToRPC(d, rsp, "onReqGenerateCode")
}
// 使用兑换码
func onReqUseCode(_ *amqp091.Delivery, msg map[string]any) {
_, _, uid, data := ParseMsg(msg)
req, err := util.MapToStructT[proto.ReqUseCode](data)
if err != nil {
log.Error(err.Error())
return
}
c, err := code.CodeManager.GetCode(req.Code)
if err != nil {
SendMsgToGate(uid, proto.RspUseCodeId, proto.RspUseCode{Code: proto.CodeIsInValid})
log.Error(err.Error())
return
}
err = code.CodeManager.UseCode(uid, c)
if err != nil {
SendMsgToGate(uid, proto.RspUseCodeId, proto.RspUseCode{
Code: util.Tie(errors.Is(err, code.ErrCodeIsUsed), proto.CodeIsUsed, proto.CodeIsInValid),
})
log.Error(err.Error())
return
}
// TODO 根据Item发放奖励
items := make(map[stub.ItemId]int64, len(*c.Item))
for it, count := range *c.Item {
item := stub.ItemId(it)
switch item {
case stub.Coin, stub.ClubCoins, stub.Diamonds:
items[item] = int64(count)
default:
log.Error(fmt.Sprintf("奖励发放失败未知item=%d code=%s uid=%d", it, req.Code, uid))
}
}
addResource(uid, items)
}
// 兑换码使用查询
func onReqCodeUseQuery(d *amqp091.Delivery, msg map[string]any) {
_, _, _, data := ParseMsg(msg)
var err error
req, err := util.MapToStructT[proto.ReqCodeUseQuery](data)
if err != nil {
log.Error(err.Error())
return
}
defer func() {
if err != nil {
SendMsgToRPC(d, proto.RspCodeUseQuery{Code: proto.Internal, Msg: err.Error()}, "onReqCodeUseQuery")
}
}()
cs, err := model.NewRedeemCodeOp().GetList(req.Limit, req.Offset)
if err != nil {
return
}
count, err := model.NewRedeemCodeOp().Count()
if err != nil {
return
}
uses := make([]proto.CodeUse, 0, len(cs))
now := xtime.Now().StdTime()
op := model.NewRedeemCodeUseRecordOp()
for _, c := range cs {
var count int64
count, err = op.CodeUsedCount(c.Code)
if err != nil {
return
}
uses = append(uses, proto.CodeUse{
Code: c.Code,
Count: c.Count,
Item: *c.Item,
Status: util.TieOrFn(xtime.IsInDuration(now, c.StartTime, c.EndTime), 2, func() int {
return util.Tie(xtime.IsAfter(c.StartTime, now), 1, 3)
}),
UsedCount: int(count),
ValidDuration: xtime.FormatDuration(c.StartTime, c.EndTime, time.DateTime),
CreateTime: xtime.ConvertToCarbon(c.CreateTime).Timestamp(),
})
}
SendMsgToRPC(d, proto.RspCodeUseQuery{
CodeUse: uses,
Count: count,
}, "onReqCodeUseQuery")
}
// 兑换玩家信息查询
func onReqCodeUsePlayerQuery(d *amqp091.Delivery, msg map[string]any) {
_, _, _, data := ParseMsg(msg)
var err error
req, err := util.MapToStructT[proto.ReqCodeUsePlayerQuery](data)
if err != nil {
log.Error(err.Error())
return
}
defer func() {
if err != nil {
SendMsgToRPC(d, proto.RspCodeUsePlayerQuery{Code: proto.Internal, Msg: err.Error()}, "onReqCodeUsePlayerQuery")
}
}()
rc, err := model.NewRedeemCodeOp().Get(req.Code)
if err != nil {
return
}
op := model.NewRedeemCodeUseRecordOp()
cs, err := op.GetByCode(req.Code, req.Limit, req.Offset)
if err != nil {
return
}
count, err := op.CountByCode(req.Code)
if err != nil {
return
}
uses := make([]proto.CodeUsePlayer, 0, len(cs))
for _, c := range cs {
uses = append(uses, proto.CodeUsePlayer{
Code: c.Code,
Item: *rc.Item,
MNick: c.MNick,
MTime: c.MTime,
Uid: c.Uid,
UseTime: c.UseTime.Unix(),
Api: c.API,
})
}
SendMsgToRPC(d, proto.RspCodeUsePlayerQuery{
Count: count,
CodeUsePlayer: uses,
}, "onReqCodeUsePlayerQuery")
}
func addResource(uid int64, items map[stub.ItemId]int64) {
req := proto.ReqBatchAddResource{
UserId: uid,
ReqResources: make([]proto.ReqAddResource, 0, len(items)),
IsNotify: true,
}
for id, count := range items {
req.ReqResources = append(req.ReqResources, proto.ReqAddResource{
UserId: uid,
ResValue: count,
ResType: model.ItemIdToRes(id),
Reason: "code",
IsNotify: true,
})
}
SendMsgToDb(routingKey.DbKey(uid), uid, proto.ReqBatchAddResourceId, req)
}