diff --git a/doc/api/task.api b/doc/api/task.api index a97a916..df37b68 100644 --- a/doc/api/task.api +++ b/doc/api/task.api @@ -44,7 +44,7 @@ service novatask { @handler UnStakeNft post /nft/unstake (UnStakeNftReq) - @doc "软质押任务奖励发放列表" + @doc "质押奖励发放列表" @handler StakeRewardList get /nft/stake_reward returns (StakeRewardList) } @@ -114,6 +114,7 @@ type StakeTaskDetail { ProduceTokensToday float64 `json:"produce_token_today"` // 今日产出代币 GameBonus int `json:"game_bonus"` // 游戏加成比率 CanReceiveTokens float64 `json:"can_receive_tokens"` // 可领取代币数量 + TotalIncomeTokens float64 `json:"total_income_tokens"` // 累计收益 } // UserNft 用户NFT @@ -145,3 +146,12 @@ type UnStakeNftReq { TokenId string `json:"token_id"` // nftID } +type StakeReward { + Date string `json:"date"` // 日期 + Reward float64 `json:"reward"` // 当日发放奖励 +} + +type StakeRewardList { + RewardList []StakeReward `json:"reward_list"` +} + diff --git a/doc/swagger/nova.json b/doc/swagger/nova.json index d3c684c..e9cec91 100644 --- a/doc/swagger/nova.json +++ b/doc/swagger/nova.json @@ -275,6 +275,28 @@ ] } }, + "/gapi/task/v1/nft/stake_reward": { + "get": { + "summary": "质押奖励发放列表", + "operationId": "StakeRewardList", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/StakeRewardList" + } + } + }, + "tags": [ + "task" + ], + "security": [ + { + "apiKey": [] + } + ] + } + }, "/gapi/task/v1/nft/unstake": { "post": { "summary": "取消质押NFT", @@ -682,6 +704,40 @@ "token_ids" ] }, + "StakeReward": { + "type": "object", + "properties": { + "date": { + "type": "string", + "description": " 日期" + }, + "reward": { + "type": "number", + "format": "double", + "description": " 当日发放奖励" + } + }, + "title": "StakeReward", + "required": [ + "date", + "reward" + ] + }, + "StakeRewardList": { + "type": "object", + "properties": { + "reward_list": { + "type": "array", + "items": { + "$ref": "#/definitions/StakeReward" + } + } + }, + "title": "StakeRewardList", + "required": [ + "reward_list" + ] + }, "StakeTaskDetail": { "type": "object", "properties": { @@ -712,6 +768,11 @@ "type": "number", "format": "double", "description": " 可领取代币数量" + }, + "total_income_tokens": { + "type": "number", + "format": "double", + "description": " 累计收益" } }, "title": "StakeTaskDetail", @@ -721,7 +782,8 @@ "count_down", "produce_token_today", "game_bonus", - "can_receive_tokens" + "can_receive_tokens", + "total_income_tokens" ] }, "Task": { diff --git a/internal/handler/routes.go b/internal/handler/routes.go index d732cac..68d8815 100644 --- a/internal/handler/routes.go +++ b/internal/handler/routes.go @@ -107,6 +107,12 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { Path: "/nft/stake", Handler: task.StakeNftHandler(serverCtx), }, + { + // 质押奖励发放列表 + Method: http.MethodGet, + Path: "/nft/stake_reward", + Handler: task.StakeRewardListHandler(serverCtx), + }, { // 取消质押NFT Method: http.MethodPost, diff --git a/internal/handler/task/stake_reward_list_handler.go b/internal/handler/task/stake_reward_list_handler.go new file mode 100644 index 0000000..f2b3d50 --- /dev/null +++ b/internal/handler/task/stake_reward_list_handler.go @@ -0,0 +1,22 @@ +package task + +import ( + "net/http" + + "github.com/zeromicro/go-zero/rest/httpx" + "nova_task/internal/logic/task" + "nova_task/internal/svc" +) + +// 质押奖励发放列表 +func StakeRewardListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + l := task.NewStakeRewardListLogic(r.Context(), svcCtx) + resp, err := l.StakeRewardList() + if err != nil { + httpx.ErrorCtx(r.Context(), w, err) + } else { + httpx.OkJsonCtx(r.Context(), w, resp) + } + } +} diff --git a/internal/logic/task/get_stake_task_detail_logic.go b/internal/logic/task/get_stake_task_detail_logic.go index 4433cb5..b892568 100644 --- a/internal/logic/task/get_stake_task_detail_logic.go +++ b/internal/logic/task/get_stake_task_detail_logic.go @@ -86,6 +86,11 @@ func (l *GetStakeTaskDetailLogic) GetStakeTaskDetail() (*types.StakeTaskDetail, canReceiveTokens *= coefficient + totalIncomeReward, err := l.svcCtx.StakeRewardModel.CountReward(l.ctx, uid) + if err != nil { + l.Errorw("count reward failed", logx.Field("err", err), logx.Field("uid", uid)) + } + return &types.StakeTaskDetail{ StartDate: start.Format(time.DateOnly), EndDate: end.Format(time.DateOnly), @@ -93,5 +98,6 @@ func (l *GetStakeTaskDetailLogic) GetStakeTaskDetail() (*types.StakeTaskDetail, ProduceTokensToday: produceTokensToday, GameBonus: gameBonus, CanReceiveTokens: canReceiveTokens, + TotalIncomeTokens: totalIncomeReward, }, nil } diff --git a/internal/logic/task/stake_reward_list_logic.go b/internal/logic/task/stake_reward_list_logic.go new file mode 100644 index 0000000..04e045e --- /dev/null +++ b/internal/logic/task/stake_reward_list_logic.go @@ -0,0 +1,52 @@ +package task + +import ( + "context" + "github.com/spf13/cast" + "nova_task/internal/pkg/errs" + "nova_task/internal/pkg/utils" + "time" + + "nova_task/internal/svc" + "nova_task/internal/types" + + "github.com/zeromicro/go-zero/core/logx" +) + +type StakeRewardListLogic struct { + logx.Logger + ctx context.Context + svcCtx *svc.ServiceContext +} + +// 质押奖励发放列表 +func NewStakeRewardListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *StakeRewardListLogic { + return &StakeRewardListLogic{ + Logger: logx.WithContext(ctx), + ctx: ctx, + svcCtx: svcCtx, + } +} + +func (l *StakeRewardListLogic) StakeRewardList() (*types.StakeRewardList, error) { + uid := utils.GetUidUint(l.ctx) + rws, err := l.svcCtx.StakeRewardModel.FindRewardsByUid(l.ctx, uid) + if err != nil { + l.Errorw("find rewards by uid failed", logx.Field("err", err)) + return nil, errs.New(errs.ErrDatabaseOperate, err) + } + var rs []types.StakeReward + for _, rw := range rws { + date, err := time.Parse("20060102", cast.ToString(rw.AwardSeq)) + if err != nil { + l.Errorw("parse date failed", logx.Field("err", err), logx.Field("awardSeq", rw.AwardSeq)) + continue + } + rs = append(rs, types.StakeReward{ + Date: date.Format(time.DateOnly), + Reward: rw.Reward.InexactFloat64(), + }) + } + + return &types.StakeRewardList{RewardList: rs}, nil +} diff --git a/internal/model/nh_task_nft_stake_reward_model.go b/internal/model/nh_task_nft_stake_reward_model.go index f2006d8..91c4cbd 100755 --- a/internal/model/nh_task_nft_stake_reward_model.go +++ b/internal/model/nh_task_nft_stake_reward_model.go @@ -19,6 +19,8 @@ type ( 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 + CountReward(ctx context.Context, uid uint) (float64, error) + FindRewardsByUid(ctx context.Context, uid uint) ([]*NhTaskNftStakeReward, error) } customNhTaskNftStakeRewardModel struct { @@ -26,6 +28,23 @@ type ( } ) +func (m *customNhTaskNftStakeRewardModel) CountReward(ctx context.Context, uid uint) (float64, error) { + query := fmt.Sprintf("SELECT SUM(`reward`) FROM %s WHERE `uid` = ? AND `sent` = 1", m.table) + var reward float64 + err := m.conn.QueryRowCtx(ctx, &reward, query, uid) + return reward, err +} + +func (m *customNhTaskNftStakeRewardModel) FindRewardsByUid(ctx context.Context, uid uint) ([]*NhTaskNftStakeReward, error) { + query := fmt.Sprintf("SELECT * FROM %s WHERE `uid` = ? AND `sent` = 1", m.table) + var list []*NhTaskNftStakeReward + err := m.conn.QueryRowsCtx(ctx, &list, query, uid) + if err != nil && !errors.Is(err, sqlx.ErrNotFound) { + return nil, err + } + return list, nil +} + // SetReward 对未发送奖励的用户发送奖励,支持并发,且不会重发 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` = ?, `sent` = 1 WHERE `uid` = ? AND `award_seq` = ? AND `sent` = 0", m.table) diff --git a/internal/types/types.go b/internal/types/types.go index dac3183..336ead3 100644 --- a/internal/types/types.go +++ b/internal/types/types.go @@ -63,6 +63,15 @@ type StakeNftList struct { TokenIds []string `json:"token_ids"` // nft列表 } +type StakeReward struct { + Date string `json:"date"` // 日期 + Reward float64 `json:"reward"` // 当日发放奖励 +} + +type StakeRewardList struct { + RewardList []StakeReward `json:"reward_list"` +} + type StakeTaskDetail struct { StartDate string `json:"start_date"` // 开始日期 EndDate string `json:"end_date"` // 结束日期 @@ -70,6 +79,7 @@ type StakeTaskDetail struct { ProduceTokensToday float64 `json:"produce_token_today"` // 今日产出代币 GameBonus int `json:"game_bonus"` // 游戏加成比率 CanReceiveTokens float64 `json:"can_receive_tokens"` // 可领取代币数量 + TotalIncomeTokens float64 `json:"total_income_tokens"` // 累计收益 } type Task struct {