email reward
This commit is contained in:
@@ -5,4 +5,6 @@ const (
|
||||
DailyPayConf = "daily_pay_conf"
|
||||
NftStakeTaskDate = "nft_stake_task_date"
|
||||
NftStakeTaskConf = "nft_stake_task_conf"
|
||||
CarvApiKey = "carv_api_key"
|
||||
AdminSecret = "admin_secret"
|
||||
)
|
||||
|
||||
29
internal/handler/admin/add_email_reward_handler.go
Normal file
29
internal/handler/admin/add_email_reward_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/admin"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 每日钱包签到任务
|
||||
func AddEmailRewardHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EmailReward
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := admin.NewAddEmailRewardLogic(r.Context(), svcCtx)
|
||||
err := l.AddEmailReward(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
internal/handler/admin/add_emial_reward_handler.go
Normal file
29
internal/handler/admin/add_emial_reward_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/admin"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 每日钱包签到任务
|
||||
func AddEmialRewardHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EmailReward
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := admin.NewAddEmialRewardLogic(r.Context(), svcCtx)
|
||||
err := l.AddEmialReward(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
22
internal/handler/admin/send_email_reward_handler.go
Normal file
22
internal/handler/admin/send_email_reward_handler.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/admin"
|
||||
"nova_task/internal/svc"
|
||||
)
|
||||
|
||||
// 执行发放奖励操作
|
||||
func SendEmailRewardHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := admin.NewSendEmailRewardLogic(r.Context(), svcCtx)
|
||||
err := l.SendEmailReward()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.Ok(w)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
internal/handler/carv/bind_wallet_handler.go
Normal file
29
internal/handler/carv/bind_wallet_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/carv"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 注册绑定钱包任务
|
||||
func BindWalletHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EmailKey
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := carv.NewBindWalletLogic(r.Context(), svcCtx)
|
||||
resp, err := l.BindWallet(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
internal/handler/carv/download_and_bind_role_handler.go
Normal file
29
internal/handler/carv/download_and_bind_role_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/carv"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 下载并绑定Castile游戏角色
|
||||
func DownloadAndBindRoleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EmailKey
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := carv.NewDownloadAndBindRoleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.DownloadAndBindRole(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
internal/handler/carv/unlock_chapter_handler.go
Normal file
29
internal/handler/carv/unlock_chapter_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/carv"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 游戏主线解锁第x章节
|
||||
func UnlockChapterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UnlockChapterReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := carv.NewUnlockChapterLogic(r.Context(), svcCtx)
|
||||
resp, err := l.UnlockChapter(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
internal/handler/carv/wallet_check_in_handler.go
Normal file
29
internal/handler/carv/wallet_check_in_handler.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
"nova_task/internal/logic/carv"
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
)
|
||||
|
||||
// 每日钱包签到任务
|
||||
func WalletCheckInHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.EmailKey
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := carv.NewWalletCheckInLogic(r.Context(), svcCtx)
|
||||
resp, err := l.WalletCheckIn(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ package handler
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
admin "nova_task/internal/handler/admin"
|
||||
carv "nova_task/internal/handler/carv"
|
||||
task "nova_task/internal/handler/task"
|
||||
"nova_task/internal/svc"
|
||||
|
||||
@@ -13,6 +15,60 @@ import (
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.AdminSecretCheck},
|
||||
[]rest.Route{
|
||||
{
|
||||
// 每日钱包签到任务
|
||||
Method: http.MethodPost,
|
||||
Path: "/email_reward",
|
||||
Handler: admin.AddEmailRewardHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 执行发放奖励操作
|
||||
Method: http.MethodGet,
|
||||
Path: "/email_reward",
|
||||
Handler: admin.SendEmailRewardHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/gapi/admin"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
rest.WithMiddlewares(
|
||||
[]rest.Middleware{serverCtx.ApiKeyCheck},
|
||||
[]rest.Route{
|
||||
{
|
||||
// 下载并绑定Castile游戏角色
|
||||
Method: http.MethodGet,
|
||||
Path: "/bind_role",
|
||||
Handler: carv.DownloadAndBindRoleHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 注册绑定钱包任务
|
||||
Method: http.MethodGet,
|
||||
Path: "/bind_wallet",
|
||||
Handler: carv.BindWalletHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 每日钱包签到任务
|
||||
Method: http.MethodGet,
|
||||
Path: "/check_in_wallet",
|
||||
Handler: carv.WalletCheckInHandler(serverCtx),
|
||||
},
|
||||
{
|
||||
// 游戏主线解锁第x章节
|
||||
Method: http.MethodGet,
|
||||
Path: "/unlock_chapter",
|
||||
Handler: carv.UnlockChapterHandler(serverCtx),
|
||||
},
|
||||
}...,
|
||||
),
|
||||
rest.WithPrefix("/gapi/carv"),
|
||||
)
|
||||
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
|
||||
@@ -108,6 +108,15 @@ func (c *Cron) Run() {
|
||||
if err != nil {
|
||||
logx.Errorw("delete nft holder error", logx.Field("error", err), logx.Field("address", nft.Address), logx.Field("token", nft.TokenId))
|
||||
}
|
||||
uid, err := c.svcCtx.WalletModel.FindUidByAddress(c.ctx, nft.Address)
|
||||
if err != nil {
|
||||
logx.Errorw("find uid by address error", logx.Field("error", err), logx.Field("address", nft.Address))
|
||||
continue
|
||||
}
|
||||
err = c.svcCtx.StakeNftModel.UnStakeNft(c.ctx, uid, nft.TokenId, true)
|
||||
if err != nil {
|
||||
logx.Errorw("un stake nft error", logx.Field("error", err), logx.Field("address", nft.Address), logx.Field("token", nft.TokenId))
|
||||
}
|
||||
}
|
||||
err = c.svcCtx.NftHolderModel.DeleteOtherUpdateSeq(c.ctx, updateSeq)
|
||||
if err != nil {
|
||||
|
||||
42
internal/logic/admin/add_email_reward_logic.go
Normal file
42
internal/logic/admin/add_email_reward_logic.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/shopspring/decimal"
|
||||
"nova_task/internal/model"
|
||||
"nova_task/internal/pkg/errs"
|
||||
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type AddEmailRewardLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 每日钱包签到任务
|
||||
func NewAddEmailRewardLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddEmailRewardLogic {
|
||||
return &AddEmailRewardLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *AddEmailRewardLogic) AddEmailReward(req *types.EmailReward) error {
|
||||
_, err := l.svcCtx.EmailRewardModel.Insert(l.ctx, &model.NhEmailReward{
|
||||
Email: req.Email,
|
||||
RewardType: req.RewardType,
|
||||
Value: decimal.NewFromFloat(req.Value),
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("add email reward failed", logx.Field("err", err), logx.Field("email", req.Email))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
}
|
||||
|
||||
return errs.Success()
|
||||
}
|
||||
84
internal/logic/admin/send_email_reward_logic.go
Normal file
84
internal/logic/admin/send_email_reward_logic.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/zeromicro/go-zero/core/threading"
|
||||
"nova_task/internal/model"
|
||||
"nova_task/internal/pkg/errs"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"nova_task/internal/svc"
|
||||
)
|
||||
|
||||
type SendEmailRewardLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 执行发放奖励操作
|
||||
func NewSendEmailRewardLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendEmailRewardLogic {
|
||||
return &SendEmailRewardLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *SendEmailRewardLogic) SendEmailReward() error {
|
||||
rewards, err := l.svcCtx.EmailRewardModel.AllRequireSend(l.ctx)
|
||||
if err != nil {
|
||||
l.Errorw("get email reward failed", logx.Field("err", err))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
}
|
||||
|
||||
if len(rewards) <= 0 {
|
||||
return errs.Success()
|
||||
}
|
||||
|
||||
threading.GoSafe(func() {
|
||||
ctx := context.Background()
|
||||
for _, rw := range rewards {
|
||||
u, err := l.svcCtx.UserModel.FindOneByEmail(ctx, rw.Email)
|
||||
if err != nil {
|
||||
l.Errorw("find user failed", logx.Field("err", err), logx.Field("email", rw.Email))
|
||||
continue
|
||||
}
|
||||
|
||||
err = l.svcCtx.EmailRewardModel.SetSent(ctx, rw.Id, u.Id)
|
||||
if err != nil {
|
||||
l.Errorw("set sent failed", logx.Field("err", err), logx.Field("id", rw.Id), logx.Field("uid", u.Id))
|
||||
continue
|
||||
}
|
||||
|
||||
// points,elite_points,castile,keys
|
||||
switch strings.ToLower(rw.RewardType) {
|
||||
case "points":
|
||||
err = l.svcCtx.TaskAssetModel.AddPoint(ctx, u.Id, rw.Value)
|
||||
case "elite_points":
|
||||
err = l.svcCtx.TaskAssetModel.AddElitePoints(ctx, u.Id, rw.Value)
|
||||
case "castile":
|
||||
err = l.svcCtx.TaskAssetModel.AddCastile(ctx, u.Id, rw.Value)
|
||||
case "keys":
|
||||
err = l.svcCtx.TaskAssetModel.AddKeys(ctx, u.Id, int(rw.Value.IntPart()))
|
||||
}
|
||||
if err != nil {
|
||||
l.Errorw("add asset failed", logx.Field("err", err), logx.Field("uid", u.Id), logx.Field("rewardType", rw.RewardType), logx.Field("value", rw.Value))
|
||||
}
|
||||
_, err = l.svcCtx.TaskAssetRecordModel.Insert(ctx, &model.NhTaskAssetRecord{
|
||||
Uid: int(u.Id),
|
||||
AssetField: rw.RewardType,
|
||||
Count: rw.Value.InexactFloat64(),
|
||||
Remark: rw.Remark,
|
||||
CreateTime: int(time.Now().Unix()),
|
||||
})
|
||||
if err != nil {
|
||||
l.Errorw("insert task asset record failed", logx.Field("err", err), logx.Field("uid", u.Id), logx.Field("rewardType", rw.RewardType), logx.Field("value", rw.Value))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
31
internal/logic/carv/bind_wallet_logic.go
Normal file
31
internal/logic/carv/bind_wallet_logic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type BindWalletLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 注册绑定钱包任务
|
||||
func NewBindWalletLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BindWalletLogic {
|
||||
return &BindWalletLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *BindWalletLogic) BindWallet(req *types.EmailKey) (resp *types.CarvResult, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
31
internal/logic/carv/download_and_bind_role_logic.go
Normal file
31
internal/logic/carv/download_and_bind_role_logic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DownloadAndBindRoleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 下载并绑定Castile游戏角色
|
||||
func NewDownloadAndBindRoleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DownloadAndBindRoleLogic {
|
||||
return &DownloadAndBindRoleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DownloadAndBindRoleLogic) DownloadAndBindRole(req *types.EmailKey) (resp *types.CarvResult, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
31
internal/logic/carv/unlock_chapter_logic.go
Normal file
31
internal/logic/carv/unlock_chapter_logic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UnlockChapterLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 游戏主线解锁第x章节
|
||||
func NewUnlockChapterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UnlockChapterLogic {
|
||||
return &UnlockChapterLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UnlockChapterLogic) UnlockChapter(req *types.UnlockChapterReq) (resp *types.CarvResult, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
31
internal/logic/carv/wallet_check_in_logic.go
Normal file
31
internal/logic/carv/wallet_check_in_logic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package carv
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"nova_task/internal/svc"
|
||||
"nova_task/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type WalletCheckInLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 每日钱包签到任务
|
||||
func NewWalletCheckInLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WalletCheckInLogic {
|
||||
return &WalletCheckInLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *WalletCheckInLogic) WalletCheckIn(req *types.EmailKey) (resp *types.CarvResult, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -29,13 +29,24 @@ func NewStakeNftLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StakeNft
|
||||
|
||||
func (l *StakeNftLogic) StakeNft(req *types.StakeNftList) error {
|
||||
uid := utils.GetUidUint(l.ctx)
|
||||
err := l.svcCtx.StakeNftModel.StakeNft(l.ctx, uid, req.RoleId, req.TokenIds)
|
||||
if err != nil {
|
||||
l.Errorw("stake nft failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenIds", req.TokenIds))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
}
|
||||
|
||||
for _, tokenId := range req.TokenIds {
|
||||
tkHolder, err := l.svcCtx.NftHolderModel.FindOneByTokenId(l.ctx, tokenId)
|
||||
if err != nil {
|
||||
if errors.Is(err, model.ErrNotFound) {
|
||||
l.Errorw("find nft holder not exist", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenId", tokenId))
|
||||
continue
|
||||
}
|
||||
l.Errorw("find nft holder failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenId", tokenId))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
}
|
||||
l.svcCtx.WalletModel.FindUidByAddress(l.ctx, tkHolder.Address)
|
||||
err = l.svcCtx.StakeNftModel.StakeNft(l.ctx, uid, req.RoleId, tokenId)
|
||||
if err != nil {
|
||||
l.Errorw("stake nft failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenIds", req.TokenIds))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
}
|
||||
|
||||
var sns []int8
|
||||
var propertyId string
|
||||
if utils.IsBigTarot(tokenId) {
|
||||
@@ -50,7 +61,7 @@ func (l *StakeNftLogic) StakeNft(req *types.StakeNftList) error {
|
||||
Uid: uid,
|
||||
RoleId: int64(req.RoleId),
|
||||
TokenId: cast.ToUint(tokenId),
|
||||
PropertyId: "",
|
||||
PropertyId: propertyId,
|
||||
Sn: sn,
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -27,7 +27,7 @@ func NewUnStakeNftLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UnStak
|
||||
|
||||
func (l *UnStakeNftLogic) UnStakeNft(req *types.UnStakeNftReq) error {
|
||||
uid := utils.GetUidUint(l.ctx)
|
||||
err := l.svcCtx.StakeNftModel.UnStakeNft(l.ctx, uid, req.TokenId)
|
||||
err := l.svcCtx.StakeNftModel.UnStakeNft(l.ctx, uid, req.TokenId, false)
|
||||
if err != nil {
|
||||
l.Errorw("unstake nft failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenIds", req.TokenId))
|
||||
return errs.New(errs.ErrDatabaseOperate, err)
|
||||
|
||||
33
internal/middleware/adminsecretcheck_middleware.go
Normal file
33
internal/middleware/adminsecretcheck_middleware.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"nova_task/internal/model"
|
||||
)
|
||||
|
||||
type AdminSecretCheckMiddleware struct {
|
||||
conf model.NhSystemConfigModel
|
||||
}
|
||||
|
||||
func NewAdminSecretCheckMiddleware(conf model.NhSystemConfigModel) *AdminSecretCheckMiddleware {
|
||||
return &AdminSecretCheckMiddleware{conf: conf}
|
||||
}
|
||||
|
||||
func (m *AdminSecretCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if key, err := m.conf.GetAdminSecret(r.Context()); err != nil {
|
||||
if !errors.Is(err, model.ErrNotFound) {
|
||||
http.Error(w, "system error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
apiKey := r.Header.Get("x-admin-secret")
|
||||
if apiKey != key {
|
||||
http.Error(w, "Invalid API key", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
34
internal/middleware/apikeycheck_middleware.go
Normal file
34
internal/middleware/apikeycheck_middleware.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"nova_task/internal/model"
|
||||
)
|
||||
|
||||
type ApiKeyCheckMiddleware struct {
|
||||
conf model.NhSystemConfigModel
|
||||
}
|
||||
|
||||
func NewApiKeyCheckMiddleware(conf model.NhSystemConfigModel) *ApiKeyCheckMiddleware {
|
||||
return &ApiKeyCheckMiddleware{conf: conf}
|
||||
}
|
||||
|
||||
func (m *ApiKeyCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if key, err := m.conf.GetCarvApiKey(r.Context()); err != nil {
|
||||
if !errors.Is(err, model.ErrNotFound) {
|
||||
http.Error(w, "system error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
apiKey := r.Header.Get("x-api-key")
|
||||
if apiKey != key {
|
||||
http.Error(w, "Invalid API key", http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
next(w, r)
|
||||
}
|
||||
}
|
||||
63
internal/model/nh_email_reward_model.go
Executable file
63
internal/model/nh_email_reward_model.go
Executable file
@@ -0,0 +1,63 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"time"
|
||||
)
|
||||
|
||||
var _ NhEmailRewardModel = (*customNhEmailRewardModel)(nil)
|
||||
|
||||
type (
|
||||
// NhEmailRewardModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customNhEmailRewardModel.
|
||||
NhEmailRewardModel interface {
|
||||
nhEmailRewardModel
|
||||
withSession(session sqlx.Session) NhEmailRewardModel
|
||||
AllRequireSend(ctx context.Context) ([]NhEmailReward, error)
|
||||
SetSent(ctx context.Context, id, uid uint) error
|
||||
}
|
||||
|
||||
customNhEmailRewardModel struct {
|
||||
*defaultNhEmailRewardModel
|
||||
}
|
||||
)
|
||||
|
||||
func (m *customNhEmailRewardModel) SetSent(ctx context.Context, id, uid uint) error {
|
||||
upate := fmt.Sprintf("update %s set `uid` = ?, `sent_at` = ? where `id` = ? and `sent_at` = 0", m.table)
|
||||
result, err := m.conn.ExecCtx(ctx, upate, uid, time.Now().Unix(), id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if rows == 0 {
|
||||
return ErrNoRowUpdate
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *customNhEmailRewardModel) AllRequireSend(ctx context.Context) ([]NhEmailReward, error) {
|
||||
query := fmt.Sprintf("select %s from %s where `sent_at` = 0", nhEmailRewardRows, m.table)
|
||||
var result []NhEmailReward
|
||||
err := m.conn.QueryRowsCtx(ctx, &result, query)
|
||||
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewNhEmailRewardModel returns a model for the database table.
|
||||
func NewNhEmailRewardModel(conn sqlx.SqlConn) NhEmailRewardModel {
|
||||
return &customNhEmailRewardModel{
|
||||
defaultNhEmailRewardModel: newNhEmailRewardModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customNhEmailRewardModel) withSession(session sqlx.Session) NhEmailRewardModel {
|
||||
return NewNhEmailRewardModel(sqlx.NewSqlConnFromSession(session))
|
||||
}
|
||||
95
internal/model/nh_email_reward_model_gen.go
Executable file
95
internal/model/nh_email_reward_model_gen.go
Executable file
@@ -0,0 +1,95 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// versions:
|
||||
// goctl version: 1.7.3
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
var (
|
||||
nhEmailRewardFieldNames = builder.RawFieldNames(&NhEmailReward{})
|
||||
nhEmailRewardRows = strings.Join(nhEmailRewardFieldNames, ",")
|
||||
nhEmailRewardRowsExpectAutoSet = strings.Join(stringx.Remove(nhEmailRewardFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
nhEmailRewardRowsWithPlaceHolder = strings.Join(stringx.Remove(nhEmailRewardFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||
)
|
||||
|
||||
type (
|
||||
nhEmailRewardModel interface {
|
||||
Insert(ctx context.Context, data *NhEmailReward) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id uint) (*NhEmailReward, error)
|
||||
Update(ctx context.Context, data *NhEmailReward) error
|
||||
Delete(ctx context.Context, id uint) error
|
||||
}
|
||||
|
||||
defaultNhEmailRewardModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
NhEmailReward struct {
|
||||
Id uint `db:"id"`
|
||||
Email string `db:"email"` // 邮箱
|
||||
Uid uint `db:"uid"` // 用户id
|
||||
RewardType string `db:"reward_type"` // 奖励类型:[points,elite_points,castile,keys]
|
||||
Value decimal.Decimal `db:"value"` // 需要发送的积分
|
||||
Remark string `db:"remark"` // 备注
|
||||
SentAt int `db:"sent_at"` // 发放时间戳
|
||||
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `db:"updated_at"` // 修改时间
|
||||
}
|
||||
)
|
||||
|
||||
func newNhEmailRewardModel(conn sqlx.SqlConn) *defaultNhEmailRewardModel {
|
||||
return &defaultNhEmailRewardModel{
|
||||
conn: conn,
|
||||
table: "`nh_email_reward`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhEmailRewardModel) Delete(ctx context.Context, id uint) error {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultNhEmailRewardModel) FindOne(ctx context.Context, id uint) (*NhEmailReward, error) {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhEmailRewardRows, m.table)
|
||||
var resp NhEmailReward
|
||||
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlx.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhEmailRewardModel) Insert(ctx context.Context, data *NhEmailReward) (sql.Result, error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, nhEmailRewardRowsExpectAutoSet)
|
||||
ret, err := m.conn.ExecCtx(ctx, query, data.Email, data.Uid, data.RewardType, data.Value, data.Remark, data.SentAt)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (m *defaultNhEmailRewardModel) Update(ctx context.Context, data *NhEmailReward) error {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhEmailRewardRowsWithPlaceHolder)
|
||||
_, err := m.conn.ExecCtx(ctx, query, data.Email, data.Uid, data.RewardType, data.Value, data.Remark, data.SentAt, data.Id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultNhEmailRewardModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
44
internal/model/nh_nft_stake_model.go
Executable file
44
internal/model/nh_nft_stake_model.go
Executable file
@@ -0,0 +1,44 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
var _ NhNftStakeModel = (*customNhNftStakeModel)(nil)
|
||||
|
||||
type (
|
||||
// NhNftStakeModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customNhNftStakeModel.
|
||||
NhNftStakeModel interface {
|
||||
nhNftStakeModel
|
||||
withSession(session sqlx.Session) NhNftStakeModel
|
||||
AllStakeNft(ctx context.Context) ([]NhNftStake, error)
|
||||
}
|
||||
|
||||
customNhNftStakeModel struct {
|
||||
*defaultNhNftStakeModel
|
||||
}
|
||||
)
|
||||
|
||||
func (m *customNhNftStakeModel) AllStakeNft(ctx context.Context) ([]NhNftStake, error) {
|
||||
query := "SELECT * FROM `nh_nft_stake` WHERE `status` = 'staked'"
|
||||
var result []NhNftStake
|
||||
err := m.conn.QueryRowsCtx(ctx, &result, query)
|
||||
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// NewNhNftStakeModel returns a model for the database table.
|
||||
func NewNhNftStakeModel(conn sqlx.SqlConn) NhNftStakeModel {
|
||||
return &customNhNftStakeModel{
|
||||
defaultNhNftStakeModel: newNhNftStakeModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
func (m *customNhNftStakeModel) withSession(session sqlx.Session) NhNftStakeModel {
|
||||
return NewNhNftStakeModel(sqlx.NewSqlConnFromSession(session))
|
||||
}
|
||||
139
internal/model/nh_nft_stake_model_gen.go
Executable file
139
internal/model/nh_nft_stake_model_gen.go
Executable file
@@ -0,0 +1,139 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// versions:
|
||||
// goctl version: 1.7.3
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"github.com/zeromicro/go-zero/core/stringx"
|
||||
)
|
||||
|
||||
var (
|
||||
nhNftStakeFieldNames = builder.RawFieldNames(&NhNftStake{})
|
||||
nhNftStakeRows = strings.Join(nhNftStakeFieldNames, ",")
|
||||
nhNftStakeRowsExpectAutoSet = strings.Join(stringx.Remove(nhNftStakeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||
nhNftStakeRowsWithPlaceHolder = strings.Join(stringx.Remove(nhNftStakeFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||
)
|
||||
|
||||
type (
|
||||
nhNftStakeModel interface {
|
||||
Insert(ctx context.Context, data *NhNftStake) (sql.Result, error)
|
||||
FindOne(ctx context.Context, id uint) (*NhNftStake, error)
|
||||
FindOneByStakeHashTokenId(ctx context.Context, stakeHash string, tokenId uint) (*NhNftStake, error)
|
||||
FindOneByUnstakeHashTokenId(ctx context.Context, unstakeHash string, tokenId uint) (*NhNftStake, error)
|
||||
Update(ctx context.Context, data *NhNftStake) error
|
||||
Delete(ctx context.Context, id uint) error
|
||||
}
|
||||
|
||||
defaultNhNftStakeModel struct {
|
||||
conn sqlx.SqlConn
|
||||
table string
|
||||
}
|
||||
|
||||
NhNftStake struct {
|
||||
Id uint `db:"id"`
|
||||
UserId uint `db:"user_id"` // 用户ID
|
||||
RoleId uint64 `db:"role_id"` // 角色ID
|
||||
Email string `db:"email"` // email
|
||||
UserAddress string `db:"user_address"` // 用户地址
|
||||
NftAddress string `db:"nft_address"` // nft合约地址
|
||||
TokenId uint `db:"token_id"` // NFT tokenid
|
||||
TarotType int8 `db:"tarot_type"` // 塔罗类型:1=大塔罗,2=小塔罗
|
||||
LockedGoodsId uint `db:"locked_goods_id"` // 提取前锁定游戏内的道具ID
|
||||
StakeHash string `db:"stake_hash"` // 质押hash
|
||||
UnstakeHash string `db:"unstake_hash"` // 提取hash
|
||||
Status string `db:"status"` // 质押状态:pending待质押,staked已质押,unstaking提取中,unstaked已提取
|
||||
StakeTime sql.NullTime `db:"stake_time"` // 质押时间
|
||||
UnstakeTime sql.NullTime `db:"unstake_time"` // 提取时间
|
||||
Remark sql.NullString `db:"remark"` // 备注
|
||||
CallbackStatus int8 `db:"callback_status"` // 质押成功通知状态:0未通知,1已通知,2通知异常
|
||||
CallbackNum int `db:"callback_num"` // 质押成功发送通知次数
|
||||
CallbackAt sql.NullTime `db:"callback_at"` // 质押通知最新时间
|
||||
CallbackRemark string `db:"callback_remark"` // 质押通知回调备注
|
||||
CallbackStatus2 int8 `db:"callback_status2"` // 提取成功通知状态:0未通知,1已通知,2通知异常
|
||||
CallbackNum2 int `db:"callback_num2"` // 提取成功发送通知次数
|
||||
CallbackAt2 sql.NullTime `db:"callback_at2"` // 提取发送通知最新时间
|
||||
CallbackRemark2 string `db:"callback_remark2"` // 提取通知回调备注
|
||||
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `db:"updated_at"` // 修改时间
|
||||
}
|
||||
)
|
||||
|
||||
func newNhNftStakeModel(conn sqlx.SqlConn) *defaultNhNftStakeModel {
|
||||
return &defaultNhNftStakeModel{
|
||||
conn: conn,
|
||||
table: "`nh_nft_stake`",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) Delete(ctx context.Context, id uint) error {
|
||||
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) FindOne(ctx context.Context, id uint) (*NhNftStake, error) {
|
||||
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhNftStakeRows, m.table)
|
||||
var resp NhNftStake
|
||||
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlx.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) FindOneByStakeHashTokenId(ctx context.Context, stakeHash string, tokenId uint) (*NhNftStake, error) {
|
||||
var resp NhNftStake
|
||||
query := fmt.Sprintf("select %s from %s where `stake_hash` = ? and `token_id` = ? limit 1", nhNftStakeRows, m.table)
|
||||
err := m.conn.QueryRowCtx(ctx, &resp, query, stakeHash, tokenId)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlx.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) FindOneByUnstakeHashTokenId(ctx context.Context, unstakeHash string, tokenId uint) (*NhNftStake, error) {
|
||||
var resp NhNftStake
|
||||
query := fmt.Sprintf("select %s from %s where `unstake_hash` = ? and `token_id` = ? limit 1", nhNftStakeRows, m.table)
|
||||
err := m.conn.QueryRowCtx(ctx, &resp, query, unstakeHash, tokenId)
|
||||
switch err {
|
||||
case nil:
|
||||
return &resp, nil
|
||||
case sqlx.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) Insert(ctx context.Context, data *NhNftStake) (sql.Result, error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhNftStakeRowsExpectAutoSet)
|
||||
ret, err := m.conn.ExecCtx(ctx, query, data.UserId, data.RoleId, data.Email, data.UserAddress, data.NftAddress, data.TokenId, data.TarotType, data.LockedGoodsId, data.StakeHash, data.UnstakeHash, data.Status, data.StakeTime, data.UnstakeTime, data.Remark, data.CallbackStatus, data.CallbackNum, data.CallbackAt, data.CallbackRemark, data.CallbackStatus2, data.CallbackNum2, data.CallbackAt2, data.CallbackRemark2)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) Update(ctx context.Context, newData *NhNftStake) error {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhNftStakeRowsWithPlaceHolder)
|
||||
_, err := m.conn.ExecCtx(ctx, query, newData.UserId, newData.RoleId, newData.Email, newData.UserAddress, newData.NftAddress, newData.TokenId, newData.TarotType, newData.LockedGoodsId, newData.StakeHash, newData.UnstakeHash, newData.Status, newData.StakeTime, newData.UnstakeTime, newData.Remark, newData.CallbackStatus, newData.CallbackNum, newData.CallbackAt, newData.CallbackRemark, newData.CallbackStatus2, newData.CallbackNum2, newData.CallbackAt2, newData.CallbackRemark2, newData.Id)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultNhNftStakeModel) tableName() string {
|
||||
return m.table
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package model
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"nova_task/internal/consts"
|
||||
@@ -18,6 +19,8 @@ type (
|
||||
nhSystemConfigModel
|
||||
GetNftStakeTaskOpenDate(ctx context.Context) (start, end time.Time, err error)
|
||||
GetNftStakeTaskConf(ctx context.Context) (conf NftStakeTaskConf, err error)
|
||||
GetCarvApiKey(ctx context.Context) (apiKey string, err error)
|
||||
GetAdminSecret(ctx context.Context) (secret string, err error)
|
||||
}
|
||||
|
||||
customNhSystemConfigModel struct {
|
||||
@@ -25,6 +28,28 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func (m *customNhSystemConfigModel) GetAdminSecret(ctx context.Context) (secret string, err error) {
|
||||
cf, err := m.FindOneByName(ctx, consts.CarvApiKey)
|
||||
if err != nil {
|
||||
if !errors.Is(err, sqlx.ErrNotFound) {
|
||||
return "", err
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
return cf.Value, nil
|
||||
}
|
||||
|
||||
func (m *customNhSystemConfigModel) GetCarvApiKey(ctx context.Context) (string, error) {
|
||||
cf, err := m.FindOneByName(ctx, consts.CarvApiKey)
|
||||
if err != nil {
|
||||
if !errors.Is(err, sqlx.ErrNotFound) {
|
||||
return "", err
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
return cf.Value, nil
|
||||
}
|
||||
|
||||
// NewNhSystemConfigModel returns a model for the database table.
|
||||
func NewNhSystemConfigModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) NhSystemConfigModel {
|
||||
return &customNhSystemConfigModel{
|
||||
|
||||
@@ -16,8 +16,10 @@ type (
|
||||
NhTaskAssetModel interface {
|
||||
nhTaskAssetModel
|
||||
WithSession(session sqlx.Session) NhTaskAssetModel
|
||||
AddPoint(ctx context.Context, uid int, points int) error
|
||||
AddPoint(ctx context.Context, uid uint, points decimal.Decimal) error
|
||||
AddCastile(ctx context.Context, uid uint, castile decimal.Decimal) error
|
||||
AddElitePoints(ctx context.Context, uid uint, points decimal.Decimal) error
|
||||
AddKeys(ctx context.Context, uid uint, keys int) error
|
||||
}
|
||||
|
||||
customNhTaskAssetModel struct {
|
||||
@@ -25,6 +27,18 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
func (m *customNhTaskAssetModel) AddKeys(ctx context.Context, uid uint, keys int) error {
|
||||
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `keys`, `create_time`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `keys` = `keys` + ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, keys, time.Now().Unix(), keys)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customNhTaskAssetModel) AddElitePoints(ctx context.Context, uid uint, elitePoints decimal.Decimal) error {
|
||||
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `elite_points`, `create_time`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `elite_points` = `elite_points` + ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, elitePoints, time.Now().Unix(), elitePoints)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customNhTaskAssetModel) AddCastile(ctx context.Context, uid uint, castile decimal.Decimal) error {
|
||||
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `castile`, `create_time`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `castile` = `castile` + ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, castile, time.Now().Unix(), castile)
|
||||
@@ -42,7 +56,7 @@ func (m *customNhTaskAssetModel) WithSession(session sqlx.Session) NhTaskAssetMo
|
||||
return NewNhTaskAssetModel(sqlx.NewSqlConnFromSession(session))
|
||||
}
|
||||
|
||||
func (m *customNhTaskAssetModel) AddPoint(ctx context.Context, uid int, points int) error {
|
||||
func (m *customNhTaskAssetModel) AddPoint(ctx context.Context, uid uint, points decimal.Decimal) error {
|
||||
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `points`, `create_time`) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE `points` = `points` + ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, points, time.Now().Unix(), points)
|
||||
return err
|
||||
|
||||
@@ -40,11 +40,8 @@ type (
|
||||
Id uint `db:"id"`
|
||||
Uid uint `db:"uid"` // 用户钱包
|
||||
RoleId uint64 `db:"role_id"` // 角色id
|
||||
Address string `db:"address"` // 钱包地址
|
||||
TokenId string `db:"token_id"` // token id
|
||||
AwardSeq int `db:"award_seq"` // 派奖序列号
|
||||
Balance int `db:"balance"` // 余额
|
||||
Stake int8 `db:"stake"` // 状态:1质押中, 0未质押
|
||||
Operate int8 `db:"operate"` // 状态:1质押, 2取消质押, 3转出
|
||||
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||
UpdatedAt time.Time `db:"updated_at"` // 修改时间
|
||||
}
|
||||
@@ -78,14 +75,14 @@ func (m *defaultNhTaskNftStakeLogModel) FindOne(ctx context.Context, id uint) (*
|
||||
}
|
||||
|
||||
func (m *defaultNhTaskNftStakeLogModel) Insert(ctx context.Context, data *NhTaskNftStakeLog) (sql.Result, error) {
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskNftStakeLogRowsExpectAutoSet)
|
||||
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.Address, data.TokenId, data.AwardSeq, data.Balance, data.Stake)
|
||||
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?)", m.table, nhTaskNftStakeLogRowsExpectAutoSet)
|
||||
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.TokenId, data.Operate)
|
||||
return ret, err
|
||||
}
|
||||
|
||||
func (m *defaultNhTaskNftStakeLogModel) Update(ctx context.Context, data *NhTaskNftStakeLog) error {
|
||||
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskNftStakeLogRowsWithPlaceHolder)
|
||||
_, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.Address, data.TokenId, data.AwardSeq, data.Balance, data.Stake, data.Id)
|
||||
_, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.TokenId, data.Operate, data.Id)
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
)
|
||||
|
||||
@@ -15,14 +16,15 @@ type (
|
||||
NhTaskNftStakeModel interface {
|
||||
nhTaskNftStakeModel
|
||||
withSession(session sqlx.Session) NhTaskNftStakeModel
|
||||
StakeNft(ctx context.Context, uid uint, roleId uint64, tokens []string) error
|
||||
UnStakeNft(ctx context.Context, uid uint, token string) error
|
||||
StakeNft(ctx context.Context, uid uint, roleId uint64, tokenId string) error
|
||||
UnStakeNft(ctx context.Context, uid uint, token string, isTransferOut bool) error
|
||||
FindByUid(ctx context.Context, uid uint) ([]NhTaskNftStake, error)
|
||||
AllStakeNft(ctx context.Context) ([]NhTaskNftStake, error)
|
||||
}
|
||||
|
||||
customNhTaskNftStakeModel struct {
|
||||
*defaultNhTaskNftStakeModel
|
||||
log NhTaskNftStakeLogModel
|
||||
}
|
||||
)
|
||||
|
||||
@@ -46,19 +48,46 @@ func (m *customNhTaskNftStakeModel) FindByUid(ctx context.Context, uid uint) ([]
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func (m *customNhTaskNftStakeModel) UnStakeNft(ctx context.Context, uid uint, token string) error {
|
||||
func (m *customNhTaskNftStakeModel) UnStakeNft(ctx context.Context, uid uint, token string, isTransferOut bool) error {
|
||||
update := fmt.Sprintf("UPDATE %s SET `state` = 0 WHERE `uid` = ? AND `token_id` = ?", m.table)
|
||||
_, err := m.conn.ExecCtx(ctx, update, uid, token)
|
||||
result, err := m.conn.ExecCtx(ctx, update, uid, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
row, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if row > 0 {
|
||||
var operate int8
|
||||
if isTransferOut {
|
||||
operate = 3
|
||||
} else {
|
||||
operate = 2
|
||||
}
|
||||
_, err = m.log.Insert(ctx, &NhTaskNftStakeLog{
|
||||
Uid: uid,
|
||||
TokenId: token,
|
||||
Operate: operate,
|
||||
})
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *customNhTaskNftStakeModel) StakeNft(ctx context.Context, uid uint, roleId uint64, tokens []string) error {
|
||||
func (m *customNhTaskNftStakeModel) StakeNft(ctx context.Context, uid uint, roleId uint64, tokenId string) error {
|
||||
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `token_id`, `role_id`, `state`) VALUES (?, ?, ?, 1) ON DUPLICATE KEY UPDATE `role_id` = ?, `state` = 1", m.table)
|
||||
for _, token := range tokens {
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, token, roleId, roleId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, tokenId, roleId, roleId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = m.log.Insert(ctx, &NhTaskNftStakeLog{
|
||||
Uid: uid,
|
||||
RoleId: roleId,
|
||||
TokenId: tokenId,
|
||||
Operate: 1,
|
||||
})
|
||||
if err != nil {
|
||||
logx.Errorw("insert stake log failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("tokenId", token), logx.Field("role", roleId))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -67,6 +96,7 @@ func (m *customNhTaskNftStakeModel) StakeNft(ctx context.Context, uid uint, role
|
||||
func NewNhTaskNftStakeModel(conn sqlx.SqlConn) NhTaskNftStakeModel {
|
||||
return &customNhTaskNftStakeModel{
|
||||
defaultNhTaskNftStakeModel: newNhTaskNftStakeModel(conn),
|
||||
log: NewNhTaskNftStakeLogModel(conn),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ import (
|
||||
"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/middleware"
|
||||
"nova_task/internal/model"
|
||||
)
|
||||
|
||||
@@ -26,10 +28,15 @@ type ServiceContext struct {
|
||||
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
|
||||
|
||||
ApiKeyCheck rest.Middleware
|
||||
AdminSecretCheck rest.Middleware
|
||||
|
||||
Earn *ea.Client
|
||||
DBConn sqlx.SqlConn
|
||||
@@ -38,6 +45,7 @@ type ServiceContext struct {
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
dbConn := c.MySql.Conn()
|
||||
configModel := model.NewNhSystemConfigModel(dbConn, c.Cache)
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
|
||||
@@ -51,14 +59,18 @@ func NewServiceContext(c config.Config) *ServiceContext {
|
||||
UserModel: model.NewNhUserModel(dbConn),
|
||||
TouristBindModel: model.NewNhTouristBindModel(dbConn),
|
||||
WalletModel: model.NewNhWalletModel(dbConn),
|
||||
ConfigModel: model.NewNhSystemConfigModel(dbConn, c.Cache),
|
||||
ConfigModel: configModel,
|
||||
NftHolderModel: model.NewNhNftHolderModel(dbConn),
|
||||
NftHolderChangeLogModel: model.NewNhNftHolderChangeLogModel(dbConn),
|
||||
StakeNftModel: model.NewNhTaskNftStakeModel(dbConn),
|
||||
StakeNftLogModel: model.NewNhTaskNftStakeLogModel(dbConn),
|
||||
OldStakeNftModel: model.NewNhNftStakeModel(dbConn),
|
||||
StakeRewardModel: model.NewNhTaskNftStakeRewardModel(dbConn),
|
||||
GamePitModel: model.NewNhGamePitModel(dbConn),
|
||||
StakePropertyModel: model.NewNhNftStakePropertyModel(dbConn),
|
||||
EmailRewardModel: model.NewNhEmailRewardModel(dbConn),
|
||||
|
||||
ApiKeyCheck: middleware.NewApiKeyCheckMiddleware(configModel).Handle,
|
||||
AdminSecretCheck: middleware.NewAdminSecretCheckMiddleware(configModel).Handle,
|
||||
|
||||
Earn: c.Earn.BuildEarnClient(),
|
||||
DBConn: dbConn,
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
|
||||
package types
|
||||
|
||||
type CarvResult struct {
|
||||
Result *Result `json:"result"`
|
||||
Error *Error `json:"error"`
|
||||
}
|
||||
|
||||
type Community struct {
|
||||
Id uint `json:"id"` // 社区ID
|
||||
Title string `json:"title"` // 社区标题
|
||||
@@ -12,6 +17,22 @@ type Community struct {
|
||||
EndAt int64 `json:"end_at"` // 结束时间
|
||||
}
|
||||
|
||||
type EmailKey struct {
|
||||
Email string `form:"email"`
|
||||
ApiKey string `Header:"x-api-key"`
|
||||
}
|
||||
|
||||
type EmailReward struct {
|
||||
Email string `json:"email"`
|
||||
RewardType string `json:"reward_type"`
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
type Error struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type GetCommunityListResp struct {
|
||||
CommunityList []Community `json:"community_list"` // 社区列表
|
||||
}
|
||||
@@ -32,9 +53,13 @@ type GetTaskRewardResp struct {
|
||||
Points int `json:"points"` // 积分
|
||||
}
|
||||
|
||||
type Result struct {
|
||||
IsValid bool `json:"isValid"`
|
||||
}
|
||||
|
||||
type StakeNftList struct {
|
||||
RoleId uint64 `json:"role_id"` // 角色id
|
||||
TokenIds []string `json:"token_ids"` // nft列表
|
||||
RoleId uint64 `json:"role_id,optional"` // 角色id
|
||||
TokenIds []string `json:"token_ids"` // nft列表
|
||||
}
|
||||
|
||||
type StakeTaskDetail struct {
|
||||
@@ -73,6 +98,12 @@ type UnStakeNftReq struct {
|
||||
TokenId string `json:"token_id"` // nftID
|
||||
}
|
||||
|
||||
type UnlockChapterReq struct {
|
||||
Email string `form:"email"`
|
||||
Chapter int `form:"chapter"`
|
||||
ApiKey string `Header:"x-api-key"`
|
||||
}
|
||||
|
||||
type UserNft struct {
|
||||
TokenId string `json:"token_id"` // nftID
|
||||
Image string `json:"image"` // nft图片
|
||||
|
||||
Reference in New Issue
Block a user