238 lines
8.9 KiB
Go
238 lines
8.9 KiB
Go
package stakepoint
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"github.com/shopspring/decimal"
|
|
"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"
|
|
"time"
|
|
|
|
"nova_task/internal/svc"
|
|
"nova_task/internal/types"
|
|
|
|
"github.com/zeromicro/go-zero/core/logx"
|
|
)
|
|
|
|
type StakePointLogic struct {
|
|
logx.Logger
|
|
ctx context.Context
|
|
svcCtx *svc.ServiceContext
|
|
}
|
|
|
|
// 质押积分操作
|
|
func NewStakePointLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StakePointLogic {
|
|
return &StakePointLogic{
|
|
Logger: logx.WithContext(ctx),
|
|
ctx: ctx,
|
|
svcCtx: svcCtx,
|
|
}
|
|
}
|
|
|
|
func (l *StakePointLogic) StakePoint(req *types.StakePointReq) error {
|
|
uid := utils.GetUid(l.ctx)
|
|
r, err := l.svcCtx.RoleModel.FindOneByRoleId(l.ctx, req.RoleID)
|
|
if err != nil {
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return 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), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return 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 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), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
if u.Id != uint(uid) {
|
|
return errs.New(errs.ErrRoleNotFound, "role not exist")
|
|
}
|
|
lv, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, uint(req.LevelId))
|
|
if err != nil {
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return errs.New(errs.ErrPointLevelConfigNotFound, "stake point level config not found")
|
|
}
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
clv, err := l.svcCtx.StakePointsModel.FindCurrentLevel(l.ctx, req.RoleID)
|
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
|
l.Errorw("find current level error", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
start := time.Now()
|
|
end := start.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour * 24))).IntPart()))
|
|
switch req.Action {
|
|
case 1:
|
|
if err == nil {
|
|
return errs.New(errs.ErrPointsStakeExist, "stake points exist")
|
|
}
|
|
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-lv.Points)), "stake points", 0, 0, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = l.svcCtx.StakePointsModel.WithSession(session).Insert(l.ctx, &model.NhStakePoints{
|
|
Uid: uint(uid),
|
|
RoleId: uint64(req.RoleID),
|
|
LevelId: lv.Id,
|
|
Level: lv.Level,
|
|
Points: lv.Points,
|
|
StartTime: start,
|
|
EndTime: end,
|
|
Status: model.PointsStakeStatusStaking,
|
|
})
|
|
if err != nil {
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
_, err := l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
|
|
"level": lv.Level,
|
|
"operation": req.Action,
|
|
"start_time": start.Unix(),
|
|
"end_time": end.Unix(),
|
|
"renew_times": 0,
|
|
})
|
|
return err
|
|
})
|
|
if err != nil {
|
|
l.Errorw("积分质押", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return errs.New(errs.ErrInternalServer, err)
|
|
}
|
|
|
|
case 2:
|
|
if err != nil {
|
|
l.Errorw("用户在未质押的情况下进行升级", logx.Field("uid", uid), logx.Field("role_id", req.RoleID))
|
|
return errs.New(errs.ErrPointStakeNotExist, "stake points not exist")
|
|
}
|
|
clvConfig, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, clv.LevelId)
|
|
if err != nil {
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return errs.New(errs.ErrPointLevelConfigNotFound, "current stake point level config not found")
|
|
}
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
if lv.Level <= clvConfig.Level {
|
|
return errs.New(errs.ErrPointsStakeLevelNotAllow, "Upgraded pledge credit bracket must be higher than current bracket")
|
|
}
|
|
// 已续约,不可升级
|
|
if clv.Status != model.PointsStakeStatusStaking {
|
|
return errs.New(errs.ErrPointsStakeHasRenew, "Current stake has renew")
|
|
}
|
|
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
points := lv.Points - clvConfig.Points
|
|
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-points)), "stake points", 0, 0, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
clv.Status = model.PointsStakeStatusUpgraded
|
|
clv.EndTime = start
|
|
spm := l.svcCtx.StakePointsModel.WithSession(session)
|
|
err := spm.Update(ctx, clv)
|
|
if err != nil {
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
end = start.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour*24))).IntPart()) - start.Sub(clv.StartTime))
|
|
_, err = spm.Insert(l.ctx, &model.NhStakePoints{
|
|
Uid: uint(uid),
|
|
RoleId: uint64(req.RoleID),
|
|
LevelId: lv.Id,
|
|
Level: lv.Level,
|
|
Points: lv.Points,
|
|
StartTime: start,
|
|
EndTime: end,
|
|
Status: model.PointsStakeStatusStaking,
|
|
})
|
|
if err != nil {
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
_, err = l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
|
|
"level": lv.Level,
|
|
"operation": req.Action,
|
|
"start_time": start.Unix(),
|
|
"end_time": end.Unix(),
|
|
"renew_times": 0,
|
|
})
|
|
return err
|
|
})
|
|
if err != nil {
|
|
l.Errorw("积分质押升级失败", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return errs.New(errs.ErrInternalServer, err)
|
|
}
|
|
case 3:
|
|
if err != nil {
|
|
l.Errorw("用户在未质押的情况下进行续约", logx.Field("uid", uid), logx.Field("role_id", req.RoleID))
|
|
return errs.New(errs.ErrPointStakeNotExist, "stake points not exist")
|
|
}
|
|
clvConfig, err := l.svcCtx.StakePointConfigModel.FindOne(l.ctx, clv.LevelId)
|
|
if err != nil {
|
|
if errors.Is(err, model.ErrNotFound) {
|
|
return errs.New(errs.ErrPointLevelConfigNotFound, "current stake point level config not found")
|
|
}
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
// 续约等级不能小于当前等级
|
|
if lv.Level < clvConfig.Level {
|
|
return errs.New(errs.ErrPointsStakeLevelNotAllow, "Renewal level cannot be lower than current level")
|
|
}
|
|
// 已续约,不可重复续约
|
|
if clv.Status != model.PointsStakeStatusStaking {
|
|
return errs.New(errs.ErrPointsStakeHasRenew, "Current stake has renew")
|
|
}
|
|
// 判断是否在可续约时间范围内
|
|
if clv.EndTime.Sub(time.Now()) > time.Duration(clvConfig.RenewDays.Mul(decimal.NewFromInt(int64(time.Hour*24))).IntPart()) {
|
|
return errs.New(errs.ErrPointsStakeNotInRenewTime, "Not within the renewal time frame")
|
|
}
|
|
// 判断是否属于续约期内
|
|
err = l.svcCtx.DBConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
|
points := lv.Points - clvConfig.Points
|
|
if points > 0 {
|
|
err = l.svcCtx.AddUserAssetWithSession(ctx, session, uint(uid), req.RoleID, consts.AssetType_Points, "", decimal.NewFromInt(int64(-points)), "stake points", 0, 0, false)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
clv.Status = model.PointsStakeStatusRenew
|
|
spm := l.svcCtx.StakePointsModel.WithSession(session)
|
|
err := spm.Update(ctx, clv)
|
|
if err != nil {
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
end = clv.EndTime.Add(time.Duration(lv.Days.Mul(decimal.NewFromInt(int64(time.Hour * 24))).IntPart()))
|
|
_, err = spm.Insert(l.ctx, &model.NhStakePoints{
|
|
Uid: uint(uid),
|
|
RoleId: uint64(req.RoleID),
|
|
LevelId: lv.Id,
|
|
Level: lv.Level,
|
|
Points: lv.Points,
|
|
StartTime: clv.EndTime,
|
|
EndTime: end,
|
|
Status: model.PointsStakeStatusStaking,
|
|
})
|
|
if err != nil {
|
|
return errs.New(errs.ErrDatabaseOperate, err)
|
|
}
|
|
_, err = l.svcCtx.GameAction(ctx, req.RoleID, consts.GameActionStakePoints, map[string]any{
|
|
"level": lv.Level,
|
|
"operation": req.Action,
|
|
"start_time": start.Unix(),
|
|
"end_time": end.Unix(),
|
|
"renew_times": 0,
|
|
})
|
|
return err
|
|
})
|
|
if err != nil {
|
|
l.Errorw("积分质押续期失败", logx.Field("err", err), logx.Field("role_id", req.RoleID), logx.Field("uid", uid), logx.Field("level_id", req.LevelId), logx.Field("action", req.Action))
|
|
return errs.New(errs.ErrInternalServer, err)
|
|
}
|
|
default:
|
|
return errs.New(errs.ErrInvalidParam, "Invalid action")
|
|
}
|
|
return errs.Success()
|
|
}
|