nft task reward

This commit is contained in:
lianghuanjie
2024-12-31 20:39:02 +08:00
parent 029289e84c
commit ea86ab71e8
20 changed files with 945 additions and 170 deletions

View File

@@ -6,13 +6,20 @@ import (
"github.com/zeromicro/go-zero/rest/httpx"
"nova_task/internal/logic/task"
"nova_task/internal/svc"
"nova_task/internal/types"
)
// 拉取玩家持有的nft列表
func GetNftListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.GetNftListReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := task.NewGetNftListLogic(r.Context(), svcCtx)
resp, err := l.GetNftList()
resp, err := l.GetNftList(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {

View File

@@ -43,7 +43,7 @@ func (c *Cron) Run() {
for _, tk := range o.TokenBalances {
balance := cast.ToInt(tk.Balance)
logx.Debugw("owner token", logx.Field("address", o.OwnerAddress), logx.Field("token", tk.TokenID), logx.Field("balance", tk.Balance))
nft, err := c.svcCtx.NftHolderModel.FindOneByAddressTokenId(c.ctx, o.OwnerAddress, tk.TokenID)
nft, err := c.svcCtx.NftHolderModel.FindOneByTokenId(c.ctx, tk.TokenID)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
nft = &model.NhNftHolder{

View File

@@ -3,7 +3,10 @@ package stake_settle
import (
"context"
"github.com/robfig/cron/v3"
"github.com/shopspring/decimal"
"github.com/spf13/cast"
"github.com/zeromicro/go-zero/core/logx"
"nova_task/internal/pkg/utils"
"nova_task/internal/svc"
"time"
)
@@ -37,16 +40,63 @@ func (c *Cron) Run() {
return
}
taskConf, err := c.svcCtx.ConfigModel.GetNftStakeTaskConf(c.ctx)
if err != nil {
logx.Errorw("get nft stake task conf failed", logx.Field("err", err))
return
}
stakes, err := c.svcCtx.StakeNftModel.AllStakeNft(c.ctx)
if err != nil {
logx.Errorw("get all stake nft failed", logx.Field("err", err))
return
}
uid2tokens := map[uint]float64{}
for _, s := range stakes {
if s.State != 1 {
continue
}
nftHolder, err := c.svcCtx.NftHolderModel.FindOneByTokenId(c.ctx, s.TokenId)
if err != nil {
logx.Errorw("find nft holder failed", logx.Field("err", err), logx.Field("tokenId", s.TokenId))
continue
}
uid, err := c.svcCtx.WalletModel.FindUidByAddress(c.ctx, nftHolder.Address)
if err != nil {
logx.Errorw("find uid by address failed", logx.Field("err", err), logx.Field("address", nftHolder.Address))
continue
}
if uid != s.Uid {
logx.Errorw("uid not match", logx.Field("uid", s.Uid), logx.Field("nftHolderUid", uid))
continue
}
if utils.IsBigTarot(s.TokenId) {
uid2tokens[s.Uid] += float64(taskConf.GreatTarot)
} else {
uid2tokens[s.Uid] += float64(taskConf.LittleTarot)
}
}
awardSeq := cast.ToInt(time.Now().AddDate(0, 0, -1).Format("20060102"))
for uid, tokens := range uid2tokens {
coefficient, err := c.svcCtx.StakeRewardModel.GetRandomCoefficientByUid(c.ctx, uid, awardSeq, taskConf.MinCoefficient, taskConf.MaxCoefficient)
if err != nil {
logx.Errorw("get random coefficient failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("awardSeq", awardSeq))
continue
}
tokensDecimal := decimal.NewFromFloat(tokens)
reward := tokensDecimal.Mul(decimal.NewFromFloat(coefficient))
err = c.svcCtx.StakeRewardModel.SetReward(c.ctx, uid, awardSeq, taskConf.OccupyPercent, tokensDecimal, reward)
if err != nil {
logx.Errorw("set reward failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("awardSeq", awardSeq), logx.Field("coefficient", coefficient), logx.Field("tokens", tokens), logx.Field("reward", reward))
continue
}
// todo: 增加资产
//c.svcCtx.TaskAssetModel.AddUserPoint()
}
logx.Debugw("run settle cron task")

View File

@@ -2,8 +2,6 @@ package task
import (
"context"
"errors"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"nova_task/internal/pkg/utils"
"nova_task/internal/svc"
@@ -19,7 +17,7 @@ type GetNftListLogic struct {
svcCtx *svc.ServiceContext
}
// 拉取玩家持有的nft列表
// NewGetNftListLogic 拉取玩家持有的nft列表
func NewGetNftListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNftListLogic {
return &GetNftListLogic{
Logger: logx.WithContext(ctx),
@@ -28,20 +26,20 @@ func NewGetNftListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetNft
}
}
func (l *GetNftListLogic) GetNftList() (*types.UserNftList, error) {
func (l *GetNftListLogic) GetNftList(req *types.GetNftListReq) (*types.UserNftList, error) {
uid := utils.GetUidUint(l.ctx)
address, err := l.svcCtx.WalletModel.FindAddressByUid(l.ctx, uid)
if err != nil {
if errors.Is(err, model.ErrNotFound) {
return nil, errs.New(errs.ErrNotBindWallet, "")
}
l.Errorw("find address by uid failed", logx.Field("err", err), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
//address, err := l.svcCtx.WalletModel.FindAddressByUid(l.ctx, uid)
//if err != nil {
// if errors.Is(err, model.ErrNotFound) {
// return nil, errs.New(errs.ErrNotBindWallet, "")
// }
// l.Errorw("find address by uid failed", logx.Field("err", err), logx.Field("uid", uid))
// return nil, errs.New(errs.ErrDatabaseOperate, err)
//}
tokens, err := l.svcCtx.NftHolderModel.FindTokensByAddress(l.ctx, address)
tokens, err := l.svcCtx.NftHolderModel.FindTokensByAddress(l.ctx, req.WalletAddress)
if err != nil {
l.Errorw("find tokens by address failed", logx.Field("err", err), logx.Field("address", address), logx.Field("uid", uid))
l.Errorw("find tokens by address failed", logx.Field("err", err), logx.Field("address", req.WalletAddress), logx.Field("uid", uid))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
@@ -49,17 +47,21 @@ func (l *GetNftListLogic) GetNftList() (*types.UserNftList, error) {
for _, token := range tokens {
var hasStake bool
var stakeAt string
var roleId uint64
nft, err := l.svcCtx.StakeNftModel.FindOneByUidTokenId(l.ctx, uid, token)
if err == nil {
hasStake = nft.State == 1
if hasStake {
stakeAt = nft.UpdatedAt.Format(time.DateOnly)
roleId = nft.RoleId
}
}
nftList = append(nftList, types.UserNft{
TokenId: token,
Image: utils.TarotImg(token),
HasStake: hasStake,
StakeAt: stakeAt,
RoleId: roleId,
})
}

View File

@@ -3,6 +3,7 @@ package task
import (
"context"
"errors"
"github.com/spf13/cast"
"nova_task/internal/model"
"nova_task/internal/pkg/errs"
"nova_task/internal/pkg/utils"
@@ -76,6 +77,15 @@ func (l *GetStakeTaskDetailLogic) GetStakeTaskDetail() (*types.StakeTaskDetail,
canReceiveTokens = produceTokensToday
}
awardSeq := cast.ToInt(time.Now().Format("20060102"))
coefficient, err := l.svcCtx.StakeRewardModel.GetRandomCoefficientByUid(l.ctx, uid, awardSeq, taskConf.MinCoefficient, taskConf.MaxCoefficient)
if err != nil {
l.Errorw("get random coefficient failed", logx.Field("err", err), logx.Field("uid", uid), logx.Field("awardSeq", awardSeq))
return nil, errs.New(errs.ErrDatabaseOperate, err)
}
canReceiveTokens *= coefficient
return &types.StakeTaskDetail{
StartDate: start.Format(time.DateOnly),
EndDate: end.Format(time.DateOnly),

View File

@@ -26,7 +26,7 @@ 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.TokenIds)
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)

View File

@@ -27,7 +27,7 @@ type (
nhNftHolderModel interface {
Insert(ctx context.Context, data *NhNftHolder) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhNftHolder, error)
FindOneByAddressTokenId(ctx context.Context, address string, tokenId string) (*NhNftHolder, error)
FindOneByTokenId(ctx context.Context, tokenId string) (*NhNftHolder, error)
Update(ctx context.Context, data *NhNftHolder) error
Delete(ctx context.Context, id uint) error
}
@@ -75,10 +75,10 @@ func (m *defaultNhNftHolderModel) FindOne(ctx context.Context, id uint) (*NhNftH
}
}
func (m *defaultNhNftHolderModel) FindOneByAddressTokenId(ctx context.Context, address string, tokenId string) (*NhNftHolder, error) {
func (m *defaultNhNftHolderModel) FindOneByTokenId(ctx context.Context, tokenId string) (*NhNftHolder, error) {
var resp NhNftHolder
query := fmt.Sprintf("select %s from %s where `address` = ? and `token_id` = ? limit 1", nhNftHolderRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, address, tokenId)
query := fmt.Sprintf("select %s from %s where `token_id` = ? limit 1", nhNftHolderRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, tokenId)
switch err {
case nil:
return &resp, nil

View File

@@ -39,6 +39,7 @@ type (
NhTaskNftStakeLog struct {
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"` // 派奖序列号
@@ -77,14 +78,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.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.Address, data.TokenId, data.AwardSeq, data.Balance, data.Stake)
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.Address, data.TokenId, data.AwardSeq, data.Balance, data.Stake, data.Id)
_, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.Address, data.TokenId, data.AwardSeq, data.Balance, data.Stake, data.Id)
return err
}

View File

@@ -15,7 +15,7 @@ type (
NhTaskNftStakeModel interface {
nhTaskNftStakeModel
withSession(session sqlx.Session) NhTaskNftStakeModel
StakeNft(ctx context.Context, uid uint, tokens []string) error
StakeNft(ctx context.Context, uid uint, roleId uint64, tokens []string) error
UnStakeNft(ctx context.Context, uid uint, token string) error
FindByUid(ctx context.Context, uid uint) ([]NhTaskNftStake, error)
AllStakeNft(ctx context.Context) ([]NhTaskNftStake, error)
@@ -52,10 +52,10 @@ func (m *customNhTaskNftStakeModel) UnStakeNft(ctx context.Context, uid uint, to
return err
}
func (m *customNhTaskNftStakeModel) StakeNft(ctx context.Context, uid uint, tokens []string) error {
insertOrUpdate := fmt.Sprintf("INSERT INTO %s (`uid`, `token_id`, `state`) VALUES (?, ?, 1) ON DUPLICATE KEY UPDATE `state` = 1", m.table)
func (m *customNhTaskNftStakeModel) StakeNft(ctx context.Context, uid uint, roleId uint64, tokens []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)
_, err := m.conn.ExecCtx(ctx, insertOrUpdate, uid, token, roleId, roleId)
if err != nil {
return err
}

View File

@@ -40,6 +40,7 @@ type (
NhTaskNftStake struct {
Id uint `db:"id"`
Uid uint `db:"uid"` // 用户钱包
RoleId uint64 `db:"role_id"` // 角色id
TokenId string `db:"token_id"` // token id
State int8 `db:"state"` // 状态1质押中 0已取消质押
CreatedAt time.Time `db:"created_at"` // 创建时间
@@ -89,14 +90,14 @@ func (m *defaultNhTaskNftStakeModel) FindOneByUidTokenId(ctx context.Context, ui
}
func (m *defaultNhTaskNftStakeModel) Insert(ctx context.Context, data *NhTaskNftStake) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?)", m.table, nhTaskNftStakeRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.TokenId, data.State)
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?)", m.table, nhTaskNftStakeRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.RoleId, data.TokenId, data.State)
return ret, err
}
func (m *defaultNhTaskNftStakeModel) Update(ctx context.Context, newData *NhTaskNftStake) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskNftStakeRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, newData.Uid, newData.TokenId, newData.State, newData.Id)
_, err := m.conn.ExecCtx(ctx, query, newData.Uid, newData.RoleId, newData.TokenId, newData.State, newData.Id)
return err
}

View File

@@ -1,6 +1,13 @@
package model
import "github.com/zeromicro/go-zero/core/stores/sqlx"
import (
"context"
"errors"
"fmt"
"github.com/shopspring/decimal"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"math/rand"
)
var _ NhTaskNftStakeRewardModel = (*customNhTaskNftStakeRewardModel)(nil)
@@ -10,6 +17,8 @@ type (
NhTaskNftStakeRewardModel interface {
nhTaskNftStakeRewardModel
withSession(session sqlx.Session) NhTaskNftStakeRewardModel
GetRandomCoefficientByUid(ctx context.Context, uid uint, awardSeq int, min, max float64) (float64, error)
SetReward(ctx context.Context, uid uint, awardSeq, occupyPercent int, pledgeOutput, reward decimal.Decimal) error
}
customNhTaskNftStakeRewardModel struct {
@@ -17,6 +26,43 @@ type (
}
)
func (m *customNhTaskNftStakeRewardModel) SetReward(ctx context.Context, uid uint, awardSeq, occupyPercent int, pledgeOutput, reward decimal.Decimal) error {
update := fmt.Sprintf("UPDATE %s SET `occupy_percent` = ?, `pledge_output` = ?, `reward` = ? WHERE `uid` = ? AND `award_seq` = ?", m.table)
result, err := m.conn.ExecCtx(ctx, update, occupyPercent, pledgeOutput, reward, uid, awardSeq)
if err != nil {
return err
}
rowsAffected, err := result.RowsAffected()
if err != nil {
return err
}
if rowsAffected == 0 {
return ErrNoRowUpdate
}
return nil
}
func (m *customNhTaskNftStakeRewardModel) GetRandomCoefficientByUid(ctx context.Context, uid uint, awardSeq int, min, max float64) (float64, error) {
query := fmt.Sprintf("SELECT `random_coefficient` FROM %s WHERE `uid` = ? AND `award_seq` = ?", m.table)
var randomCoefficient float64
err := m.conn.QueryRowCtx(ctx, &randomCoefficient, query, uid, awardSeq)
if err == nil {
return randomCoefficient, nil
}
if !errors.Is(err, sqlx.ErrNotFound) {
return 0, err
}
randomCoefficient = float64(int(min*100)+rand.Intn(int(max*100-min*100))) / 100
_, err = m.Insert(ctx, &NhTaskNftStakeReward{
Uid: uid,
AwardSeq: awardSeq,
RandomCoefficient: randomCoefficient,
})
return randomCoefficient, err
}
// NewNhTaskNftStakeRewardModel returns a model for the database table.
func NewNhTaskNftStakeRewardModel(conn sqlx.SqlConn) NhTaskNftStakeRewardModel {
return &customNhTaskNftStakeRewardModel{

View File

@@ -29,6 +29,7 @@ type (
nhTaskNftStakeRewardModel interface {
Insert(ctx context.Context, data *NhTaskNftStakeReward) (sql.Result, error)
FindOne(ctx context.Context, id uint) (*NhTaskNftStakeReward, error)
FindOneByUidAwardSeq(ctx context.Context, uid uint, awardSeq int) (*NhTaskNftStakeReward, error)
Update(ctx context.Context, data *NhTaskNftStakeReward) error
Delete(ctx context.Context, id uint) error
}
@@ -39,15 +40,16 @@ type (
}
NhTaskNftStakeReward struct {
Id uint `db:"id"`
Uid uint `db:"uid"` // 用户钱包
AwardSeq int `db:"award_seq"` // 派奖序列号
PledgeOutput decimal.NullDecimal `db:"pledge_output"` // 质押产出代币
RandomCoefficient float64 `db:"random_coefficient"` // 随机系数
OccupyPercent int `db:"occupy_percent"` // 占领百分比
Reward decimal.NullDecimal `db:"reward"` // 奖励金额
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
Id uint `db:"id"`
Uid uint `db:"uid"` // 用户钱包
AwardSeq int `db:"award_seq"` // 派奖序列号
PledgeOutput decimal.Decimal `db:"pledge_output"` // 质押产出代币
RandomCoefficient float64 `db:"random_coefficient"` // 随机系数
OccupyPercent int `db:"occupy_percent"` // 占领百分比
Reward decimal.Decimal `db:"reward"` // 奖励金额
Sent int8 `db:"sent"` // 是否已发放
CreatedAt time.Time `db:"created_at"` // 创建时间
UpdatedAt time.Time `db:"updated_at"` // 修改时间
}
)
@@ -78,15 +80,29 @@ func (m *defaultNhTaskNftStakeRewardModel) FindOne(ctx context.Context, id uint)
}
}
func (m *defaultNhTaskNftStakeRewardModel) FindOneByUidAwardSeq(ctx context.Context, uid uint, awardSeq int) (*NhTaskNftStakeReward, error) {
var resp NhTaskNftStakeReward
query := fmt.Sprintf("select %s from %s where `uid` = ? and `award_seq` = ? limit 1", nhTaskNftStakeRewardRows, m.table)
err := m.conn.QueryRowCtx(ctx, &resp, query, uid, awardSeq)
switch err {
case nil:
return &resp, nil
case sqlx.ErrNotFound:
return nil, ErrNotFound
default:
return nil, err
}
}
func (m *defaultNhTaskNftStakeRewardModel) Insert(ctx context.Context, data *NhTaskNftStakeReward) (sql.Result, error) {
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, nhTaskNftStakeRewardRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.AwardSeq, data.PledgeOutput, data.RandomCoefficient, data.OccupyPercent, data.Reward)
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskNftStakeRewardRowsExpectAutoSet)
ret, err := m.conn.ExecCtx(ctx, query, data.Uid, data.AwardSeq, data.PledgeOutput, data.RandomCoefficient, data.OccupyPercent, data.Reward, data.Sent)
return ret, err
}
func (m *defaultNhTaskNftStakeRewardModel) Update(ctx context.Context, data *NhTaskNftStakeReward) error {
func (m *defaultNhTaskNftStakeRewardModel) Update(ctx context.Context, newData *NhTaskNftStakeReward) error {
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskNftStakeRewardRowsWithPlaceHolder)
_, err := m.conn.ExecCtx(ctx, query, data.Uid, data.AwardSeq, data.PledgeOutput, data.RandomCoefficient, data.OccupyPercent, data.Reward, data.Id)
_, err := m.conn.ExecCtx(ctx, query, newData.Uid, newData.AwardSeq, newData.PledgeOutput, newData.RandomCoefficient, newData.OccupyPercent, newData.Reward, newData.Sent, newData.Id)
return err
}

View File

@@ -1,38 +0,0 @@
package utils
var bitTarot = map[string]bool{
"288": true,
"297": true,
"298": true,
"300": true,
"308": true,
"311": true,
"333": true,
"336": true,
"349": true,
"357": true,
"366": true,
"367": true,
"388": true,
"396": true,
"406": true,
"409": true,
"418": true,
"419": true,
"436": true,
"456": true,
"503": true,
"564": true,
"58": true,
"26": true,
"82": true,
"152": true,
"186": true,
"379": true,
"500": true,
"523": true,
}
func IsBigTarot(tarotId string) bool {
return bitTarot[tarotId]
}

621
internal/pkg/utils/tarot.go Normal file
View File

@@ -0,0 +1,621 @@
package utils
var (
bigTarot = map[string]string{
"288": "Card_Tower.png",
"297": "Card_Justice.png",
"298": "Card_Thehangedman.png",
"300": "Card_Magician.png",
"308": "Card_Emperor.png",
"311": "Card_Judgement.png",
"333": "Card_Temperance.png",
"336": "Card_Chariot.png",
"349": "Card_Wheel.png",
"357": "Card_Empress.png",
"366": "Card_Star.png",
"367": "Card_Vault.png",
"388": "Card_Judgement.png",
"396": "Card_Lover.png",
"406": "Card_Moon.png",
"409": "Card_Sun.png",
"418": "Card_Moon.png",
"419": "Card_World.png",
"436": "Card_Hierophant.png",
"456": "Card_Death.png",
"503": "Card_Devil.png",
"564": "Card_World.png",
"58": "Card_Priestess.png",
"26": "Card_Devil.png",
"82": "Card_Star.png",
"152": "Card_Hermit.png",
"186": "Card_Sun.png",
"379": "Card_Strength.png",
"500": "Card_Tower.png",
"523": "Card_Fools.png",
}
smallTarot = map[string]string{
"1": "Three_Of_Pentacles.png",
"2": "Queen_Of_Wands.png",
"3": "Seven_Of_Wands.png",
"4": "Nine_Of_Pentacles.png",
"5": "Queen_Of_Pentacles.png",
"6": "Eight_Of_Wands.png",
"7": "Ace_Of_Pentacles.png",
"8": "Three_Of_Cups.png",
"9": "Seven_Of_Cups.png",
"10": "Three_Of_Cups.png",
"11": "Ace_Of_Swords.png",
"12": "Ten_Of_Cups.png",
"13": "Eight_Of_Cups.png",
"14": "Ten_Of_Swords.png",
"15": "Nine_Of_Swords.png",
"16": "Page_Of_Pentacles.png",
"17": "Queen_Of_Swords.png",
"18": "Six_Of_Swords.png",
"19": "Three_Of_Wands.png",
"20": "Page_Of_Pentacles.png",
"21": "Queen_Of_Pentacles.png",
"22": "Four_Of_Wands.png",
"23": "Six_Of_Wands.png",
"24": "Queen_Of_Swords.png",
"25": "Eight_Of_Cups.png",
"27": "Three_Of_Wands.png",
"28": "Five_Of_Wands.png",
"29": "Seven_Of_Swords.png",
"30": "Eight_Of_Swords.png",
"31": "Ace_Of_Wands.png",
"32": "King_Of_Wands.png",
"33": "Eight_Of_Wands.png",
"34": "Three_Of_Swords.png",
"35": "Eight_Of_Wands.png",
"36": "Nine_Of_Wands.png",
"37": "Three_Of_Wands.png",
"38": "Two_Of_Cups.png",
"39": "Ten_Of_Cups.png",
"40": "Six_Of_Wands.png",
"41": "Two_Of_Wands.png",
"42": "King_Of_Swords.png",
"43": "Four_Of_Pentacles.png",
"44": "Eight_Of_Pentacles.png",
"45": "Nine_Of_Cups.png",
"46": "Seven_Of_Pentacles.png",
"47": "Nine_Of_Swords.png",
"48": "Four_Of_Wands.png",
"49": "Ten_Of_Wands.png",
"50": "Four_Of_Swords.png",
"51": "Ace_Of_Pentacles.png",
"52": "King_Of_Pentacles.png",
"53": "Five_Of_Cups.png",
"54": "Page_Of_Swords.png",
"55": "Five_Of_Cups.png",
"56": "Nine_Of_Swords.png",
"57": "Three_Of_Wands.png",
"59": "Four_Of_Cups.png",
"60": "Two_Of_Cups.png",
"61": "Two_Of_Wands.png",
"62": "Ace_Of_Cups.png",
"63": "Ten_Of_Wands.png",
"64": "Ace_Of_Pentacles.png",
"65": "Seven_Of_Cups.png",
"66": "Nine_Of_Wands.png",
"67": "Page_Of_Wands.png",
"68": "Two_Of_Cups.png",
"69": "Knight_Of_Cups.png",
"70": "Five_Of_Wands.png",
"71": "Eight_Of_Cups.png",
"72": "Nine_Of_Pentacles.png",
"73": "Nine_Of_Pentacles.png",
"74": "Ace_Of_Wands.png",
"75": "Five_Of_Pentacles.png",
"76": "Eight_Of_Cups.png",
"77": "Knight_Of_Wands.png",
"78": "Eight_Of_Swords.png",
"79": "Ace_Of_Swords.png",
"80": "King_Of_Swords.png",
"81": "Four_Of_Pentacles.png",
"83": "Seven_Of_Cups.png",
"84": "Eight_Of_Pentacles.png",
"85": "Seven_Of_Wands.png",
"86": "Five_Of_Swords.png",
"87": "Five_Of_Swords.png",
"88": "Six_Of_Cups.png",
"89": "Ace_Of_Wands.png",
"90": "King_Of_Wands.png",
"91": "King_Of_Pentacles.png",
"92": "Four_Of_Pentacles.png",
"93": "Six_Of_Cups.png",
"94": "Four_Of_Swords.png",
"95": "Ten_Of_Pentacles.png",
"96": "Four_Of_Cups.png",
"97": "Eight_Of_Pentacles.png",
"98": "Eight_Of_Swords.png",
"99": "Nine_Of_Cups.png",
"100": "Knight_Of_Swords.png",
"101": "Four_Of_Cups.png",
"102": "Eight_Of_Wands.png",
"103": "Two_Of_Swords.png",
"104": "Seven_Of_Swords.png",
"105": "Six_Of_Pentacles.png",
"106": "Two_Of_Swords.png",
"107": "Ace_Of_Cups.png",
"108": "Page_Of_Swords.png",
"109": "Page_Of_Swords.png",
"110": "Queen_Of_Pentacles.png",
"111": "Page_Of_Pentacles.png",
"112": "Two_Of_Pentacles.png",
"113": "King_Of_Pentacles.png",
"114": "Seven_Of_Wands.png",
"115": "Two_Of_Swords.png",
"116": "Eight_Of_Cups.png",
"117": "Queen_Of_Pentacles.png",
"118": "Five_Of_Wands.png",
"119": "Queen_Of_Swords.png",
"120": "Nine_Of_Swords.png",
"121": "King_Of_Swords.png",
"122": "Six_Of_Pentacles.png",
"123": "Six_Of_Cups.png",
"124": "Ace_Of_Cups.png",
"125": "Five_Of_Cups.png",
"126": "Page_Of_Cups.png",
"127": "Eight_Of_Swords.png",
"128": "Six_Of_Wands.png",
"129": "Eight_Of_Swords.png",
"130": "Five_Of_Wands.png",
"131": "Knight_Of_Cups.png",
"132": "Four_Of_Cups.png",
"133": "Three_Of_Wands.png",
"134": "Nine_Of_Swords.png",
"135": "Knight_Of_Pentacles.png",
"136": "Seven_Of_Cups.png",
"137": "Two_Of_Pentacles.png",
"138": "Two_Of_Cups.png",
"139": "Four_Of_Wands.png",
"140": "Nine_Of_Wands.png",
"141": "Seven_Of_Cups.png",
"142": "Knight_Of_Pentacles.png",
"143": "Two_Of_Pentacles.png",
"144": "Eight_Of_Cups.png",
"145": "Two_Of_Wands.png",
"146": "Ace_Of_Cups.png",
"147": "Page_Of_Swords.png",
"148": "Seven_Of_Cups.png",
"149": "Seven_Of_Wands.png",
"150": "King_Of_Cups.png",
"151": "Four_Of_Wands.png",
"153": "Queen_Of_Wands.png",
"154": "King_Of_Wands.png",
"155": "Six_Of_Swords.png",
"156": "Queen_Of_Cups.png",
"157": "Page_Of_Wands.png",
"158": "Six_Of_Cups.png",
"159": "Three_Of_Pentacles.png",
"160": "Six_Of_Cups.png",
"161": "Six_Of_Pentacles.png",
"162": "Five_Of_Cups.png",
"163": "Ten_Of_Pentacles.png",
"164": "Two_Of_Wands.png",
"165": "Ten_Of_Cups.png",
"166": "Two_Of_Wands.png",
"167": "Page_Of_Wands.png",
"168": "Ten_Of_Pentacles.png",
"169": "Two_Of_Cups.png",
"170": "Nine_Of_Swords.png",
"171": "King_Of_Pentacles.png",
"172": "Ten_Of_Wands.png",
"173": "Three_Of_Cups.png",
"174": "Eight_Of_Pentacles.png",
"175": "Two_Of_Swords.png",
"176": "Four_Of_Wands.png",
"177": "Ten_Of_Cups.png",
"178": "Nine_Of_Cups.png",
"179": "Eight_Of_Wands.png",
"180": "Eight_Of_Cups.png",
"181": "Knight_Of_Swords.png",
"182": "Page_Of_Swords.png",
"183": "Knight_Of_Cups.png",
"184": "King_Of_Wands.png",
"185": "Seven_Of_Cups.png",
"187": "Queen_Of_Swords.png",
"188": "King_Of_Cups.png",
"189": "Seven_Of_Pentacles.png",
"190": "Queen_Of_Wands.png",
"191": "King_Of_Swords.png",
"192": "Ten_Of_Pentacles.png",
"193": "Four_Of_Cups.png",
"194": "Five_Of_Pentacles.png",
"195": "Two_Of_Cups.png",
"196": "Four_Of_Wands.png",
"197": "Ace_Of_Pentacles.png",
"198": "Three_Of_Cups.png",
"199": "Six_Of_Pentacles.png",
"200": "Ten_Of_Cups.png",
"201": "Page_Of_Wands.png",
"202": "Ace_Of_Swords.png",
"203": "Knight_Of_Swords.png",
"204": "Knight_Of_Cups.png",
"205": "Eight_Of_Swords.png",
"206": "Four_Of_Cups.png",
"207": "Ten_Of_Swords.png",
"208": "Ace_Of_Pentacles.png",
"209": "Nine_Of_Swords.png",
"210": "Ten_Of_Pentacles.png",
"211": "Five_Of_Wands.png",
"212": "Queen_Of_Swords.png",
"213": "Nine_Of_Pentacles.png",
"214": "Knight_Of_Pentacles.png",
"215": "Queen_Of_Wands.png",
"216": "Eight_Of_Pentacles.png",
"217": "Seven_Of_Swords.png",
"218": "Five_Of_Wands.png",
"219": "Eight_Of_Wands.png",
"220": "Knight_Of_Cups.png",
"221": "Two_Of_Cups.png",
"222": "Page_Of_Pentacles.png",
"223": "King_Of_Wands.png",
"224": "Page_Of_Swords.png",
"225": "Knight_Of_Pentacles.png",
"226": "King_Of_Wands.png",
"227": "Three_Of_Pentacles.png",
"228": "Knight_Of_Swords.png",
"229": "Four_Of_Cups.png",
"230": "Three_Of_Pentacles.png",
"231": "Ace_Of_Wands.png",
"232": "Ace_Of_Cups.png",
"233": "Two_Of_Cups.png",
"234": "Four_Of_Pentacles.png",
"235": "Ace_Of_Cups.png",
"236": "Two_Of_Pentacles.png",
"237": "Five_Of_Swords.png",
"238": "Three_Of_Swords.png",
"239": "Nine_Of_Cups.png",
"240": "Five_Of_Swords.png",
"241": "Nine_Of_Pentacles.png",
"242": "Ten_Of_Swords.png",
"243": "Page_Of_Swords.png",
"244": "Eight_Of_Wands.png",
"245": "Four_Of_Cups.png",
"246": "Four_Of_Wands.png",
"247": "Seven_Of_Wands.png",
"248": "King_Of_Cups.png",
"249": "Page_Of_Swords.png",
"250": "Queen_Of_Wands.png",
"251": "Page_Of_Cups.png",
"252": "Six_Of_Swords.png",
"253": "Page_Of_Pentacles.png",
"254": "Knight_Of_Cups.png",
"255": "Knight_Of_Wands.png",
"256": "King_Of_Pentacles.png",
"257": "Ace_Of_Wands.png",
"258": "Page_Of_Cups.png",
"259": "Three_Of_Cups.png",
"260": "Five_Of_Wands.png",
"261": "Ten_Of_Swords.png",
"262": "Six_Of_Wands.png",
"263": "Six_Of_Swords.png",
"264": "Two_Of_Pentacles.png",
"265": "Queen_Of_Pentacles.png",
"266": "Three_Of_Pentacles.png",
"267": "Six_Of_Pentacles.png",
"268": "Six_Of_Wands.png",
"269": "Knight_Of_Pentacles.png",
"270": "King_Of_Cups.png",
"271": "Six_Of_Wands.png",
"272": "King_Of_Pentacles.png",
"273": "Page_Of_Wands.png",
"274": "Seven_Of_Pentacles.png",
"275": "Knight_Of_Pentacles.png",
"276": "Five_Of_Wands.png",
"277": "Ace_Of_Swords.png",
"278": "Four_Of_Swords.png",
"279": "Two_Of_Wands.png",
"280": "Page_Of_Wands.png",
"281": "Knight_Of_Cups.png",
"282": "Six_Of_Cups.png",
"283": "Eight_Of_Wands.png",
"284": "Two_Of_Pentacles.png",
"285": "Page_Of_Pentacles.png",
"286": "Queen_Of_Wands.png",
"287": "Seven_Of_Swords.png",
"289": "Nine_Of_Cups.png",
"290": "Page_Of_Pentacles.png",
"291": "Seven_Of_Pentacles.png",
"292": "Six_Of_Pentacles.png",
"293": "Ace_Of_Wands.png",
"294": "Knight_Of_Swords.png",
"295": "Four_Of_Cups.png",
"296": "Two_Of_Swords.png",
"299": "Ten_Of_Wands.png",
"301": "Queen_Of_Wands.png",
"302": "Seven_Of_Pentacles.png",
"303": "Ace_Of_Wands.png",
"304": "Seven_Of_Wands.png",
"305": "Eight_Of_Swords.png",
"306": "Seven_Of_Wands.png",
"307": "Three_Of_Swords.png",
"309": "Two_Of_Wands.png",
"310": "Five_Of_Cups.png",
"312": "Three_Of_Swords.png",
"313": "Queen_Of_Cups.png",
"314": "Seven_Of_Pentacles.png",
"315": "Five_Of_Swords.png",
"316": "Ace_Of_Swords.png",
"317": "Ace_Of_Swords.png",
"318": "Five_Of_Swords.png",
"319": "Eight_Of_Pentacles.png",
"320": "Knight_Of_Wands.png",
"321": "Three_Of_Cups.png",
"322": "Five_Of_Pentacles.png",
"323": "Ace_Of_Pentacles.png",
"324": "Four_Of_Wands.png",
"325": "Knight_Of_Wands.png",
"326": "Knight_Of_Swords.png",
"327": "Queen_Of_Pentacles.png",
"328": "Nine_Of_Pentacles.png",
"329": "Queen_Of_Cups.png",
"330": "Nine_Of_Wands.png",
"331": "Queen_Of_Wands.png",
"332": "Three_Of_Swords.png",
"334": "King_Of_Pentacles.png",
"335": "Page_Of_Wands.png",
"337": "King_Of_Swords.png",
"338": "Three_Of_Pentacles.png",
"339": "Five_Of_Swords.png",
"340": "Two_Of_Wands.png",
"341": "Eight_Of_Wands.png",
"342": "Queen_Of_Pentacles.png",
"343": "Seven_Of_Pentacles.png",
"344": "Three_Of_Wands.png",
"345": "Three_Of_Wands.png",
"346": "Three_Of_Wands.png",
"347": "Eight_Of_Cups.png",
"348": "Seven_Of_Cups.png",
"350": "Ace_Of_Pentacles.png",
"351": "Five_Of_Swords.png",
"352": "Two_Of_Pentacles.png",
"353": "Six_Of_Pentacles.png",
"354": "Five_Of_Swords.png",
"355": "Nine_Of_Swords.png",
"356": "King_Of_Pentacles.png",
"358": "Queen_Of_Swords.png",
"359": "Queen_Of_Wands.png",
"360": "Queen_Of_Cups.png",
"361": "Ace_Of_Wands.png",
"362": "Queen_Of_Cups.png",
"363": "Six_Of_Swords.png",
"364": "Ten_Of_Pentacles.png",
"365": "Three_Of_Swords.png",
"368": "Six_Of_Cups.png",
"369": "Nine_Of_Pentacles.png",
"370": "King_Of_Swords.png",
"371": "Four_Of_Pentacles.png",
"372": "Eight_Of_Pentacles.png",
"373": "Page_Of_Wands.png",
"374": "Queen_Of_Swords.png",
"375": "Ace_Of_Cups.png",
"376": "Three_Of_Swords.png",
"377": "Ten_Of_Wands.png",
"378": "Five_Of_Wands.png",
"380": "Eight_Of_Wands.png",
"381": "Five_Of_Cups.png",
"382": "Ace_Of_Pentacles.png",
"383": "King_Of_Swords.png",
"384": "Ace_Of_Wands.png",
"385": "Knight_Of_Pentacles.png",
"386": "Nine_Of_Swords.png",
"387": "Ace_Of_Cups.png",
"389": "Queen_Of_Swords.png",
"390": "King_Of_Wands.png",
"391": "Page_Of_Cups.png",
"392": "Nine_Of_Pentacles.png",
"393": "Six_Of_Wands.png",
"394": "Six_Of_Cups.png",
"395": "Three_Of_Cups.png",
"397": "Queen_Of_Cups.png",
"398": "Ten_Of_Wands.png",
"399": "Ace_Of_Pentacles.png",
"400": "Six_Of_Swords.png",
"401": "Eight_Of_Swords.png",
"402": "Nine_Of_Cups.png",
"403": "Four_Of_Pentacles.png",
"404": "Nine_Of_Wands.png",
"405": "Seven_Of_Cups.png",
"407": "King_Of_Cups.png",
"408": "Three_Of_Pentacles.png",
"410": "Nine_Of_Cups.png",
"411": "King_Of_Swords.png",
"412": "Queen_Of_Pentacles.png",
"413": "Seven_Of_Swords.png",
"414": "Nine_Of_Wands.png",
"415": "Ten_Of_Wands.png",
"416": "Ten_Of_Swords.png",
"417": "Six_Of_Pentacles.png",
"420": "King_Of_Cups.png",
"421": "Ace_Of_Cups.png",
"422": "Eight_Of_Pentacles.png",
"423": "Nine_Of_Wands.png",
"424": "Three_Of_Swords.png",
"425": "Ace_Of_Swords.png",
"426": "Knight_Of_Pentacles.png",
"427": "Five_Of_Swords.png",
"428": "Queen_Of_Cups.png",
"429": "Ten_Of_Cups.png",
"430": "Seven_Of_Cups.png",
"431": "Three_Of_Pentacles.png",
"432": "Eight_Of_Cups.png",
"433": "Ten_Of_Swords.png",
"434": "Six_Of_Swords.png",
"435": "Nine_Of_Wands.png",
"437": "Seven_Of_Swords.png",
"438": "King_Of_Pentacles.png",
"439": "Eight_Of_Wands.png",
"440": "Page_Of_Pentacles.png",
"441": "Two_Of_Pentacles.png",
"442": "Four_Of_Wands.png",
"443": "King_Of_Cups.png",
"444": "Five_Of_Pentacles.png",
"445": "Five_Of_Pentacles.png",
"446": "Nine_Of_Cups.png",
"447": "Ten_Of_Swords.png",
"448": "Four_Of_Swords.png",
"449": "Three_Of_Pentacles.png",
"450": "Knight_Of_Cups.png",
"451": "Ten_Of_Pentacles.png",
"452": "Ten_Of_Swords.png",
"453": "Nine_Of_Wands.png",
"454": "Four_Of_Swords.png",
"455": "Seven_Of_Wands.png",
"457": "Seven_Of_Swords.png",
"458": "Two_Of_Swords.png",
"459": "Seven_Of_Swords.png",
"460": "Four_Of_Pentacles.png",
"461": "Ace_Of_Swords.png",
"462": "Five_Of_Cups.png",
"463": "Ace_Of_Pentacles.png",
"464": "Ten_Of_Wands.png",
"465": "Two_Of_Pentacles.png",
"466": "Two_Of_Swords.png",
"467": "Six_Of_Swords.png",
"468": "Four_Of_Pentacles.png",
"469": "Six_Of_Pentacles.png",
"470": "Page_Of_Cups.png",
"471": "Two_Of_Wands.png",
"472": "Five_Of_Cups.png",
"473": "Three_Of_Wands.png",
"474": "Seven_Of_Wands.png",
"475": "Queen_Of_Cups.png",
"476": "Five_Of_Cups.png",
"477": "Four_Of_Swords.png",
"478": "Two_Of_Swords.png",
"479": "Knight_Of_Wands.png",
"480": "Page_Of_Cups.png",
"481": "Two_Of_Swords.png",
"482": "Ten_Of_Swords.png",
"483": "Three_Of_Swords.png",
"484": "Page_Of_Cups.png",
"485": "Six_Of_Wands.png",
"486": "Knight_Of_Cups.png",
"487": "Knight_Of_Swords.png",
"488": "Page_Of_Pentacles.png",
"489": "Three_Of_Pentacles.png",
"490": "Eight_Of_Swords.png",
"491": "King_Of_Wands.png",
"492": "Six_Of_Cups.png",
"493": "Queen_Of_Pentacles.png",
"494": "Six_Of_Swords.png",
"495": "Six_Of_Pentacles.png",
"496": "Knight_Of_Wands.png",
"497": "King_Of_Swords.png",
"498": "Queen_Of_Cups.png",
"499": "King_Of_Wands.png",
"501": "Knight_Of_Pentacles.png",
"502": "Nine_Of_Pentacles.png",
"504": "Five_Of_Cups.png",
"505": "Ten_Of_Wands.png",
"506": "Ten_Of_Swords.png",
"507": "Five_Of_Pentacles.png",
"508": "Page_Of_Cups.png",
"509": "Two_Of_Wands.png",
"510": "King_Of_Swords.png",
"511": "Six_Of_Swords.png",
"512": "Four_Of_Swords.png",
"513": "Ace_Of_Swords.png",
"514": "Knight_Of_Cups.png",
"515": "Six_Of_Cups.png",
"516": "Five_Of_Pentacles.png",
"517": "King_Of_Cups.png",
"518": "Nine_Of_Pentacles.png",
"519": "Seven_Of_Swords.png",
"520": "Four_Of_Wands.png",
"521": "Queen_Of_Cups.png",
"522": "Six_Of_Wands.png",
"524": "Knight_Of_Wands.png",
"525": "Eight_Of_Pentacles.png",
"526": "Three_Of_Cups.png",
"527": "Ten_Of_Pentacles.png",
"528": "Page_Of_Swords.png",
"529": "Ten_Of_Pentacles.png",
"530": "Knight_Of_Swords.png",
"531": "Five_Of_Pentacles.png",
"532": "Eight_Of_Pentacles.png",
"533": "Three_Of_Cups.png",
"534": "Nine_Of_Cups.png",
"535": "Five_Of_Wands.png",
"536": "Two_Of_Cups.png",
"537": "Four_Of_Swords.png",
"538": "Four_Of_Pentacles.png",
"539": "Ten_Of_Cups.png",
"540": "Nine_Of_Wands.png",
"541": "Four_Of_Pentacles.png",
"542": "Five_Of_Pentacles.png",
"543": "Seven_Of_Pentacles.png",
"544": "Ten_Of_Cups.png",
"545": "Ten_Of_Cups.png",
"546": "Three_Of_Wands.png",
"547": "Nine_Of_Wands.png",
"548": "Two_Of_Wands.png",
"549": "Seven_Of_Wands.png",
"550": "Page_Of_Cups.png",
"551": "Ace_Of_Wands.png",
"552": "Ace_Of_Cups.png",
"553": "Queen_Of_Swords.png",
"554": "Page_Of_Pentacles.png",
"555": "Page_Of_Wands.png",
"556": "Two_Of_Swords.png",
"557": "Six_Of_Wands.png",
"558": "Four_Of_Wands.png",
"559": "Four_Of_Swords.png",
"560": "Three_Of_Cups.png",
"561": "Knight_Of_Wands.png",
"562": "Page_Of_Cups.png",
"563": "King_Of_Wands.png",
"565": "Page_Of_Swords.png",
"566": "King_Of_Cups.png",
"567": "Ten_Of_Wands.png",
"568": "Two_Of_Pentacles.png",
"569": "Ten_Of_Wands.png",
"570": "Eight_Of_Swords.png",
"571": "Page_Of_Wands.png",
"572": "Queen_Of_Pentacles.png",
"573": "Four_Of_Cups.png",
"574": "Two_Of_Cups.png",
"575": "Five_Of_Pentacles.png",
"576": "Three_Of_Swords.png",
"577": "Queen_Of_Wands.png",
"578": "Five_Of_Wands.png",
"579": "Four_Of_Swords.png",
"580": "Knight_Of_Swords.png",
"581": "King_Of_Pentacles.png",
"582": "Ace_Of_Swords.png",
"583": "Six_Of_Wands.png",
"584": "Knight_Of_Swords.png",
"585": "Ten_Of_Pentacles.png",
"586": "Eight_Of_Cups.png",
"587": "Ten_Of_Cups.png",
"588": "Queen_Of_Swords.png",
"589": "Nine_Of_Cups.png",
"590": "Nine_Of_Swords.png",
"591": "Seven_Of_Pentacles.png",
"592": "Seven_Of_Swords.png",
"593": "Knight_Of_Wands.png",
"594": "Three_Of_Wands.png",
"595": "Seven_Of_Wands.png",
"596": "Seven_Of_Pentacles.png",
"597": "Knight_Of_Wands.png",
"598": "Ace_Of_Wands.png",
"599": "King_Of_Cups.png",
"600": "Knight_Of_Pentacles.png",
}
)
func IsBigTarot(tarotId string) bool {
_, ok := bigTarot[tarotId]
return ok
}
func TarotImg(tarotId string) string {
if img, ok := bigTarot[tarotId]; ok {
return img
}
img, _ := smallTarot[tarotId]
return img
}

View File

@@ -16,6 +16,10 @@ type GetCommunityListResp struct {
CommunityList []Community `json:"community_list"` // 社区列表
}
type GetNftListReq struct {
WalletAddress string `form:"wallet_address"`
}
type GetTaskListReq struct {
CommunityId uint `form:"community_id,optional"` // 所属社区ID
}
@@ -29,6 +33,7 @@ type GetTaskRewardResp struct {
}
type StakeNftList struct {
RoleId uint64 `json:"role_id"` // 角色id
TokenIds []string `json:"token_ids"` // nft列表
}
@@ -70,8 +75,10 @@ type UnStakeNftReq struct {
type UserNft struct {
TokenId string `json:"token_id"` // nftID
Image string `json:"image"` // nft图片
HasStake bool `json:"has_stake"` // 是否已质押
StakeAt string `json:"stake_at"` // 质押时间
RoleId uint64 `json:"role_id"` // 角色id
}
type UserNftList struct {