Files
novatask/internal/svc/service_context.go
2025-01-13 19:48:14 +08:00

221 lines
7.5 KiB
Go

package svc
import (
"context"
"errors"
"fmt"
ea "github.com/earn-alliance/earnalliance-go"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/zeromicro/go-zero/rest"
"nova_task/internal/config"
"nova_task/internal/consts"
"nova_task/internal/middleware"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"nova_task/internal/types"
"time"
)
type ServiceContext struct {
Config config.Config
TaskModel model.NhTaskModel
taskAssetModel model.NhTaskAssetModel
taskAssetRecordModel model.NhTaskAssetRecordModel
TaskProgressModel model.NhTaskProgressModel
TwitterModel model.NhTwitterModel
PromoteBindModel model.NhPromoteBindModel
TouristBindModel model.NhTouristBindModel
CommunityModel model.NhTaskCommunityModel
UserModel model.NhUserModel
WalletModel model.NhWalletModel
ConfigModel model.NhSystemConfigModel
NftHolderModel model.NhNftHolderModel
NftHolderChangeLogModel model.NhNftHolderChangeLogModel
StakeNftModel model.NhTaskNftStakeModel
OldStakeNftModel model.NhNftStakeModel
StakeNftLogModel model.NhTaskNftStakeLogModel
StakeRewardModel model.NhTaskNftStakeRewardModel
GamePitModel model.NhGamePitModel
StakePropertyModel model.NhNftStakePropertyModel
EmailRewardModel model.NhEmailRewardModel
AmbassadorModel model.NhTaskAmbassadorModel
GameReportModel model.NhGameReportModel
ApiKeyCheck rest.Middleware
AdminSecretCheck rest.Middleware
Game7ApiKeyCheck rest.Middleware
KGeNApiKeyCheck rest.Middleware
Earn *ea.Client
DBConn sqlx.SqlConn
Redis *redis.Redis
}
func NewServiceContext(c config.Config) *ServiceContext {
dbConn := c.MySql.Conn()
configModel := model.NewNhSystemConfigModel(dbConn, c.Cache)
return &ServiceContext{
Config: c,
TaskModel: model.NewNhTaskModel(dbConn),
taskAssetModel: model.NewNhTaskAssetModel(dbConn),
taskAssetRecordModel: model.NewNhTaskAssetRecordModel(dbConn),
TaskProgressModel: model.NewNhTaskProgressModel(dbConn),
TwitterModel: model.NewNhTwitterModel(dbConn),
PromoteBindModel: model.NewNhPromoteBindModel(dbConn),
CommunityModel: model.NewNhTaskCommunityModel(dbConn),
UserModel: model.NewNhUserModel(dbConn),
TouristBindModel: model.NewNhTouristBindModel(dbConn),
WalletModel: model.NewNhWalletModel(dbConn),
ConfigModel: configModel,
NftHolderModel: model.NewNhNftHolderModel(dbConn),
NftHolderChangeLogModel: model.NewNhNftHolderChangeLogModel(dbConn),
StakeNftModel: model.NewNhTaskNftStakeModel(dbConn),
OldStakeNftModel: model.NewNhNftStakeModel(dbConn),
StakeRewardModel: model.NewNhTaskNftStakeRewardModel(dbConn),
GamePitModel: model.NewNhGamePitModel(dbConn),
StakePropertyModel: model.NewNhNftStakePropertyModel(dbConn),
EmailRewardModel: model.NewNhEmailRewardModel(dbConn),
AmbassadorModel: model.NewNhTaskAmbassadorModel(dbConn),
GameReportModel: model.NewNhGameReportModel(dbConn),
ApiKeyCheck: middleware.NewApiKeyCheckMiddleware(configModel).Handle,
AdminSecretCheck: middleware.NewAdminSecretCheckMiddleware(configModel).Handle,
Game7ApiKeyCheck: middleware.NewGame7ApiKeyCheckMiddleware(configModel).Handle,
KGeNApiKeyCheck: middleware.NewKGeNApiKeyCheckMiddleware(configModel).Handle,
Earn: c.Earn.BuildEarnClient(),
DBConn: dbConn,
Redis: redis.MustNewRedis(c.Redis),
}
}
func (s *ServiceContext) Close() {
err := s.Earn.Flush()
if err != nil {
logx.Errorw("flush earn error", logx.Field("err", err))
}
s.Earn.Close()
}
func (s *ServiceContext) IsAmbassador(ctx context.Context, uid uint, stage int8) bool {
u, err := s.UserModel.FindOne(ctx, uid)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
logx.Errorw("find user error", logx.Field("err", err), logx.Field("uid", uid), logx.Field("stage", stage))
}
return false
}
_, err = s.AmbassadorModel.FindOneByEmailStage(ctx, u.Email, stage)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
logx.Errorw("find ambassador error", logx.Field("err", err), logx.Field("uid", uid), logx.Field("stage", stage))
}
return false
}
return true
}
func (s *ServiceContext) HasBindTwitter(ctx context.Context, uid uint) bool {
tw, err := s.TwitterModel.FindOneByUid(ctx, uid)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
logx.Errorw("find twitter error", logx.Field("err", err), logx.Field("uid", uid))
}
return false
}
return tw.TwitterId != ""
}
func (s *ServiceContext) GetUidByEmail(ctx context.Context, email string) (uint, *types.CarvResult) {
u, err := s.UserModel.FindOneByEmail(ctx, email)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
return 0, &types.CarvResult{
Error: &types.Error{
Code: int(errs.ErrDatabaseOperate),
Message: "system error",
},
}
}
return 0, &types.CarvResult{
Error: &types.Error{
Code: int(errs.ErrUserNotFound),
Message: "email not exist",
},
}
}
return u.Id, nil
}
func (s *ServiceContext) AddUserAssetWithSession(ctx context.Context, session sqlx.Session, uid uint, asset consts.AssetType, amount decimal.Decimal, remark string, eventId uint64, provideUid uint, referralReward bool) error {
var assetModel model.NhTaskAssetModel
var recordModel model.NhTaskAssetRecordModel
if session != nil {
assetModel = s.taskAssetModel.WithSession(session)
recordModel = s.taskAssetRecordModel.WithSession(session)
} else {
assetModel = s.taskAssetModel
recordModel = s.taskAssetRecordModel
}
var err error
switch asset {
case consts.AssetType_Points:
err = assetModel.AddPoint(ctx, uid, amount)
case consts.AssetType_Castile:
err = assetModel.AddCastile(ctx, uid, amount)
case consts.AssetType_Elite_Points:
err = assetModel.AddElitePoints(ctx, uid, amount)
case consts.AssetType_Keys:
err = assetModel.AddKeys(ctx, uid, int(amount.IntPart()))
default:
return errors.New("unknown asset type")
}
if err != nil {
return err
}
_, err = recordModel.Insert(ctx, &model.NhTaskAssetRecord{
Uid: int(uid),
EventId: eventId,
AssetField: string(asset),
Count: amount.InexactFloat64(),
Remark: remark,
ProvideUid: provideUid,
CreateTime: int(time.Now().Unix()),
})
if err != nil {
return err
}
if !referralReward {
return nil
}
// 返利给上级
pb, err := s.PromoteBindModel.FindOneByInvitedUid(ctx, uid)
if err != nil {
if !errors.Is(err, model.ErrNotFound) {
logx.Errorw("find promote bind error", logx.Field("err", err), logx.Field("uid", uid))
}
return nil
}
if pb.ShareUid == 0 {
return nil
}
var rate = 5
if s.NftHolderModel.HoldNft(ctx, pb.ShareUid) {
rate = 15
} else if s.AmbassadorModel.IsAmbassador(ctx, pb.ShareUid) {
rate = 10
}
rated := decimal.NewFromFloat(float64(rate) / 100)
rewardAmount := amount.Mul(rated)
return s.AddUserAssetWithSession(ctx, session, pb.ShareUid, asset, rewardAmount, fmt.Sprintf("分享返利,比例%s", rated.String()), 7, uid, false)
}
func (s *ServiceContext) AddUserAsset(ctx context.Context, uid uint, asset consts.AssetType, amount decimal.Decimal, remark string, eventId uint64, provideUid uint, referralReward bool) error {
return s.AddUserAssetWithSession(ctx, nil, uid, asset, amount, remark, eventId, provideUid, referralReward)
}