samba/server/other/handler/codeHandler.go
2025-06-04 09:51:39 +08:00

211 lines
5.0 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 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)
}