增加提取castile到游戏的逻辑。

This commit is contained in:
yuming88
2025-04-28 19:26:17 +08:00
parent e50137a90e
commit d40cdda6ae
11 changed files with 205 additions and 73 deletions

View File

@@ -17,26 +17,22 @@ service novatask {
type TransferCastileToGameReq {
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
}
type TransferCastileToGameResp {
TransferToGameLog
Amount int64 `json:"amount,range=[1:]"` // 数量
}
type TransferCastileToGameListReq {
RoleID int64 `json:"role_id,optional"` // 角色id
}
type TransferToGameLog {
Id int `json:"id"` // id
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
Status string `json:"elf_name"` // 状态
type TransferCastileToGameResp {
Id int `json:"id"` // id
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
Status int64 `json:"status"` // 状态
}
type TransferCastileToGameListResp {
Total int `json:"total"` // 总数
List []TransferToGameLog `json:"list"` // 列表
Total int `json:"total"` // 总数
List []TransferCastileToGameResp `json:"list"` // 列表
}

View File

@@ -1945,7 +1945,7 @@
"list": {
"type": "array",
"items": {
"$ref": "#/definitions/TransferToGameLog"
"$ref": "#/definitions/TransferCastileToGameResp"
},
"description": " 列表"
}
@@ -1994,42 +1994,18 @@
"format": "int64",
"description": " 数量"
},
"elf_name": {
"type": "string",
"status": {
"type": "integer",
"format": "int64",
"description": " 状态"
}
},
"title": "TransferCastileToGameResp"
},
"TransferToGameLog": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int32",
"description": " id"
},
"role_id": {
"type": "integer",
"format": "int64",
"description": " 角色id"
},
"amount": {
"type": "integer",
"format": "int64",
"description": " 数量"
},
"elf_name": {
"type": "string",
"description": " 状态"
}
},
"title": "TransferToGameLog",
"title": "TransferCastileToGameResp",
"required": [
"id",
"role_id",
"amount",
"elf_name"
"status"
]
},
"UnStakeNftReq": {

View File

@@ -3,4 +3,5 @@ package consts
const (
GameActionGetHomePointsState = "getStakeHomePointsState"
GameActionStakePoints = "stakeHomePoints"
GameActionSendNoticeAward = "SendNoticeAward" //给多角色发邮件
)

View File

@@ -1,7 +1,11 @@
package transfercastile
import (
"errors"
"fmt"
"net/http"
"nova_task/internal/pkg/utils"
"time"
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/transfercastile"
@@ -18,8 +22,22 @@ func TransferCastileToGameHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return
}
uid := utils.GetUidUint(r.Context())
redisKey := fmt.Sprintf("transferCastile:uid:%d", uid)
//加锁
lock, err := svcCtx.Redis.SetnxEx(redisKey, time.Now().String(), 120)
if !lock || err != nil {
httpx.ErrorCtx(r.Context(), w, errors.New("operation frequently"))
return
}
l := transfercastile.NewTransferCastileToGameLogic(r.Context(), svcCtx)
resp, err := l.TransferCastileToGame(&req)
//删除redis KEY
_, _ = svcCtx.Redis.Del(redisKey)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {

View File

@@ -2,11 +2,16 @@ package transfercastile
import (
"context"
"errors"
"github.com/zeromicro/go-zero/core/jsonx"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"nova_task/internal/consts"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"nova_task/internal/pkg/utils"
"nova_task/internal/svc"
"nova_task/internal/types"
"github.com/zeromicro/go-zero/core/logx"
)
type TransferCastileToGameLogic struct {
@@ -25,7 +30,117 @@ func NewTransferCastileToGameLogic(ctx context.Context, svcCtx *svc.ServiceConte
}
func (l *TransferCastileToGameLogic) TransferCastileToGame(req *types.TransferCastileToGameReq) (resp *types.TransferCastileToGameResp, err error) {
// todo: add your logic here and delete this line
return
//获取JWT中的UID
uid := utils.GetUidUint(l.ctx)
//验证是否当前用户的角色
r, err := l.svcCtx.RoleModel.FindOneByRoleId(l.ctx, req.RoleID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.New(errs.ErrRoleNotFound, "role not exist")
}
l.Errorw("find role error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
u, err := l.svcCtx.UserModel.FindOneByEmail(l.ctx, r.Account)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.New(errs.ErrUserNotFound, "user not found")
}
l.Errorw("find user error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
if u.Id != uid {
return nil, errs.New(errs.ErrRoleNotFound, "role not exist.")
}
cToken, err := l.svcCtx.CastileTokenModel.FindOneByEmail(l.ctx, r.Account)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.New(errs.ErrPointLevelConfigNotFound, "castile record is not exists")
}
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
//判断余额
remain := int(cToken.Total) - int(cToken.Transfer) - int(req.Amount)
if remain < 0 {
return nil, errs.New(errs.ErrInsufficientCastile, "castile insufficient")
}
lastId := int64(0)
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
err := l.svcCtx.CastileTokenModel.WithSession(session).UpdateTransferIncrease(ctx, uint(req.Amount), cToken.Id)
if err != nil {
logx.Errorw("castile 余额更新失败", logx.Field("err", err), logx.Field("id", cToken.Id), logx.Field("roleId", req.RoleID))
return err
}
res, err := l.svcCtx.CastileTokenLogModel.WithSession(session).Insert(ctx, &model.NhCastileTokenLog{
Uid: u.Id,
RoleId: uint64(req.RoleID),
Amount: uint(req.Amount),
Action: 1,
})
if err != nil {
logx.Errorw("castile 日志插入失败", logx.Field("err", err), logx.Field("id", cToken.Id), logx.Field("roleId", req.RoleID))
return err
}
lastId, err = res.LastInsertId()
if err != nil {
return err
}
return nil
})
if err != nil {
logx.Errorw("castile 更新的事务报错", logx.Field("err", err), logx.Field("id", cToken.Id), logx.Field("roleId", req.RoleID))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
itemList := []map[string]any{
{
"itemId": 32110,
"itemCount": 20,
},
}
data, _ := jsonx.MarshalToString(itemList)
//给多角色发邮件
_, err = l.svcCtx.GameAction(l.ctx, int64(req.RoleID), consts.GameActionSendNoticeAward, map[string]any{
"role_ids": req.RoleID,
"item_list": data,
"template_id": 120338,
"mail_ttl": 24 * 90,
})
if err != nil {
logx.Errorw("game 发送邮件失败", logx.Field("err", err), logx.Field("roleId", req.RoleID))
return nil, errs.New(errs.ErrInternalServer, err)
}
res, err := l.svcCtx.CastileTokenLogModel.FindOne(l.ctx, uint(lastId))
if err != nil {
logx.Errorw("查询 castile 日志表出错", logx.Field("err", err), logx.Field("Id", lastId))
return nil, errs.New(errs.ErrInternalServer, err)
}
//更新状态
res.CallbackStatus = 1
err = l.svcCtx.CastileTokenLogModel.Update(l.ctx, res)
if err != nil {
logx.Errorw("更新 castile 日志表状态出错", logx.Field("err", err), logx.Field("Id", lastId))
return nil, errs.New(errs.ErrInternalServer, err)
}
return &types.TransferCastileToGameResp{
Id: int(res.Id),
RoleID: int64(res.RoleId),
Amount: int64(res.Amount),
Status: int64(res.CallbackStatus),
}, nil
}

View File

@@ -1,6 +1,10 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
import (
"context"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ NhCastileTokenLogModel = (*customNhCastileTokenLogModel)(nil)
@@ -9,7 +13,8 @@ type (
// and implement the added methods in customNhCastileTokenLogModel.
NhCastileTokenLogModel interface {
nhCastileTokenLogModel
withSession(session sqlx.Session) NhCastileTokenLogModel
WithSession(session sqlx.Session) NhCastileTokenLogModel
UpdateStatus(ctx context.Context, status uint, id uint) error
}
customNhCastileTokenLogModel struct {
@@ -24,6 +29,12 @@ func NewNhCastileTokenLogModel(conn sqlx.SqlConn) NhCastileTokenLogModel {
}
}
func (m *customNhCastileTokenLogModel) withSession(session sqlx.Session) NhCastileTokenLogModel {
func (m *customNhCastileTokenLogModel) WithSession(session sqlx.Session) NhCastileTokenLogModel {
return NewNhCastileTokenLogModel(sqlx.NewSqlConnFromSession(session))
}
func (m *customNhCastileTokenLogModel) UpdateStatus(ctx context.Context, status uint, id uint) error {
query := fmt.Sprintf("update %s set `callback_status` = ? where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, status, id)
return err
}

View File

@@ -1,6 +1,10 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
import (
"context"
"fmt"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
var _ NhCastileTokenModel = (*customNhCastileTokenModel)(nil)
@@ -9,7 +13,8 @@ type (
// and implement the added methods in customNhCastileTokenModel.
NhCastileTokenModel interface {
nhCastileTokenModel
withSession(session sqlx.Session) NhCastileTokenModel
WithSession(session sqlx.Session) NhCastileTokenModel
UpdateTransferIncrease(ctx context.Context, reduce uint, id uint) error
}
customNhCastileTokenModel struct {
@@ -24,6 +29,12 @@ func NewNhCastileTokenModel(conn sqlx.SqlConn) NhCastileTokenModel {
}
}
func (m *customNhCastileTokenModel) withSession(session sqlx.Session) NhCastileTokenModel {
func (m *customNhCastileTokenModel) WithSession(session sqlx.Session) NhCastileTokenModel {
return NewNhCastileTokenModel(sqlx.NewSqlConnFromSession(session))
}
func (m *customNhCastileTokenModel) UpdateTransferIncrease(ctx context.Context, num uint, id uint) error {
query := fmt.Sprintf("update %s set `transfer` = `transfer` + ? where `id` = ?", m.table)
_, err := m.conn.ExecCtx(ctx, query, num, id)
return err
}

View File

@@ -10,14 +10,15 @@ const (
ErrOverload Reason = 10403 // 请求超载
// ======= 服务器内部错误1000~9999 =======
ErrInternalServer Reason = 1000 // 未知的服务器内部错误
ErrDatabaseOperate Reason = 1001 // 数据库错误
ErrRedisOperate Reason = 1002 // redis错误
ErrEncodePassword Reason = 1003 // 密码加密错误
ErrGenerateUUid Reason = 1004 // 生成uuid错误
ErrGenerateToken Reason = 1005 // 生成token错误
ErrSystemConfig Reason = 1006 // 系统配置错误
GameServerError Reason = 1007 // 游戏服务器错误
ErrInternalServer Reason = 1000 // 未知的服务器内部错误
ErrDatabaseOperate Reason = 1001 // 数据库错误
ErrRedisOperate Reason = 1002 // redis错误
ErrEncodePassword Reason = 1003 // 密码加密错误
ErrGenerateUUid Reason = 1004 // 生成uuid错误
ErrGenerateToken Reason = 1005 // 生成token错误
ErrSystemConfig Reason = 1006 // 系统配置错误
GameServerError Reason = 1007 // 游戏服务器错误
ErrOperationFrequently Reason = 1008 // 游戏服务器错误
// ======= 业务层错误20000~29999 =======
ErrUnknownLogicError Reason = 20000 // 未知的业务错误

View File

@@ -98,6 +98,7 @@ func (s *ServiceContext) GameAction(ctx context.Context, roleId int64, action st
s.ErrLog(ctx, action, addr, serverInfo, request, resp)
return resp, fmt.Errorf("game action msg= %s, data=%v", cast.ToString(resp["msg"]), cast.ToString(resp["data"]))
}
s.ErrLog(ctx, action, addr, serverInfo, request, resp)
return resp, nil
}

View File

@@ -44,6 +44,9 @@ type dbModel struct {
StakePointConfigModel model.NhStakeHomePointConfigModel
StakePointsModel model.NhStakePointsModel
StakePointsLogModel model.NhStakePointsLogModel
CastileTokenModel model.NhCastileTokenModel
CastileTokenLogModel model.NhCastileTokenLogModel
}
func newDBModel(dbConn, gameConn sqlx.SqlConn, configModel model.NhSystemConfigModel) *dbModel {
@@ -82,5 +85,8 @@ func newDBModel(dbConn, gameConn sqlx.SqlConn, configModel model.NhSystemConfigM
MergeServerModel: model.NewMsMergeServersModel(gameConn),
GameServerModel: model.NewMsGameServerModel(gameConn),
ServersModel: model.NewMgServersModel(gameConn),
CastileTokenModel: model.NewNhCastileTokenModel(dbConn),
CastileTokenLogModel: model.NewNhCastileTokenLogModel(dbConn),
}
}

View File

@@ -245,24 +245,20 @@ type TransferCastileToGameListReq struct {
}
type TransferCastileToGameListResp struct {
Total int `json:"total"` // 总数
List []TransferToGameLog `json:"list"` // 列表
Total int `json:"total"` // 总数
List []TransferCastileToGameResp `json:"list"` // 列表
}
type TransferCastileToGameReq struct {
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount,range=[1:]"` // 数量
}
type TransferCastileToGameResp struct {
TransferToGameLog
}
type TransferToGameLog struct {
Id int `json:"id"` // id
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
Status string `json:"elf_name"` // 状态
Id int `json:"id"` // id
RoleID int64 `json:"role_id"` // 角色id
Amount int64 `json:"amount"` // 数量
Status int64 `json:"status"` // 状态
}
type UnStakeNftReq struct {