refactor(抽奖记录): 重构抽奖记录列表接口,支持按等级筛选 新增用户昵称、头像及奖品名称、图片等展示字段 优化分页逻辑,默认返回最新100条记录 feat(游戏): 添加扫雷游戏验证和结算接口 新增游戏票据验证和结算相关接口定义及Swagger文档 docs(API): 更新Swagger文档 更新抽奖记录和游戏相关接口的文档描述 style(路由): 添加游戏路由注释 添加扫雷游戏接口路由的占位注释
178 lines
6.1 KiB
Go
178 lines
6.1 KiB
Go
package taskcenter
|
|
|
|
import (
|
|
"bindbox-game/internal/code"
|
|
"bindbox-game/internal/pkg/core"
|
|
"bindbox-game/internal/pkg/validation"
|
|
"encoding/json"
|
|
"net/http"
|
|
"strconv"
|
|
)
|
|
|
|
type listTasksRequest struct {
|
|
Page int `form:"page"`
|
|
PageSize int `form:"page_size"`
|
|
}
|
|
|
|
type taskItem struct {
|
|
ID int64 `json:"id"`
|
|
Name string `json:"name"`
|
|
Description string `json:"description"`
|
|
Status int32 `json:"status"`
|
|
StartTime int64 `json:"start_time"`
|
|
EndTime int64 `json:"end_time"`
|
|
Tiers []taskTierItem `json:"tiers"`
|
|
Rewards []taskRewardItem `json:"rewards"`
|
|
}
|
|
|
|
type taskTierItem struct {
|
|
ID int64 `json:"id"`
|
|
Metric string `json:"metric"`
|
|
Operator string `json:"operator"`
|
|
Threshold int64 `json:"threshold"`
|
|
Window string `json:"window"`
|
|
Repeatable int32 `json:"repeatable"`
|
|
Priority int32 `json:"priority"`
|
|
}
|
|
|
|
type taskRewardItem struct {
|
|
ID int64 `json:"id"`
|
|
TierID int64 `json:"tier_id"`
|
|
RewardType string `json:"reward_type"`
|
|
RewardPayload map[string]any `json:"reward_payload"`
|
|
Quantity int64 `json:"quantity"`
|
|
}
|
|
|
|
type listTasksResponse struct {
|
|
Page int `json:"page"`
|
|
PageSize int `json:"page_size"`
|
|
Total int64 `json:"total"`
|
|
List []taskItem `json:"list"`
|
|
}
|
|
|
|
// @Summary 获取任务列表(App)
|
|
// @Description 获取当前可用的任务列表,支持分页
|
|
// @Tags TaskCenter(App)
|
|
// @Accept x-www-form-urlencoded
|
|
// @Produce json
|
|
// @Param page query int false "页码" default(1)
|
|
// @Param page_size query int false "每页数量" default(20)
|
|
// @Success 200 {object} listTasksResponse "任务列表"
|
|
// @Router /api/app/task-center/tasks [get]
|
|
func (h *handler) ListTasksForApp() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
req := new(listTasksRequest)
|
|
res := new(listTasksResponse)
|
|
if err := ctx.ShouldBindForm(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
items, total, err := h.task.ListTasks(ctx.RequestContext(), struct{ Page, PageSize int }{Page: req.Page, PageSize: req.PageSize})
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
res.Page = req.Page
|
|
res.PageSize = req.PageSize
|
|
res.Total = total
|
|
res.List = make([]taskItem, len(items))
|
|
for i, v := range items {
|
|
ti := taskItem{ID: v.ID, Name: v.Name, Description: v.Description, Status: v.Status, StartTime: v.StartTime, EndTime: v.EndTime}
|
|
if len(v.Tiers) > 0 {
|
|
ti.Tiers = make([]taskTierItem, len(v.Tiers))
|
|
for j, t := range v.Tiers {
|
|
ti.Tiers[j] = taskTierItem{ID: t.ID, Metric: t.Metric, Operator: t.Operator, Threshold: t.Threshold, Window: t.Window, Repeatable: t.Repeatable, Priority: t.Priority}
|
|
}
|
|
}
|
|
if len(v.Rewards) > 0 {
|
|
ti.Rewards = make([]taskRewardItem, len(v.Rewards))
|
|
for j, r := range v.Rewards {
|
|
var pl map[string]any
|
|
_ = json.Unmarshal([]byte(r.RewardPayload), &pl)
|
|
ti.Rewards[j] = taskRewardItem{ID: r.ID, TierID: r.TierID, RewardType: r.RewardType, RewardPayload: pl, Quantity: r.Quantity}
|
|
}
|
|
}
|
|
res.List[i] = ti
|
|
}
|
|
ctx.Payload(res)
|
|
}
|
|
}
|
|
|
|
type taskProgressResponse struct {
|
|
TaskID int64 `json:"task_id"`
|
|
UserID int64 `json:"user_id"`
|
|
OrderCount int64 `json:"order_count"`
|
|
InviteCount int64 `json:"invite_count"`
|
|
FirstOrder bool `json:"first_order"`
|
|
Claimed []int64 `json:"claimed_tiers"`
|
|
}
|
|
|
|
// @Summary 获取用户任务进度(App)
|
|
// @Description 获取指定用户在特定任务上的进度详情
|
|
// @Tags TaskCenter(App)
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "任务ID"
|
|
// @Param user_id path int true "用户ID"
|
|
// @Success 200 {object} taskProgressResponse "任务进度详情"
|
|
// @Router /api/app/task-center/tasks/{id}/progress/{user_id} [get]
|
|
func (h *handler) GetTaskProgressForApp() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
taskID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递任务ID"))
|
|
return
|
|
}
|
|
uid, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
|
return
|
|
}
|
|
up, err := h.task.GetUserProgress(ctx.RequestContext(), uid, taskID)
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(&taskProgressResponse{TaskID: up.TaskID, UserID: up.UserID, OrderCount: up.OrderCount, InviteCount: up.InviteCount, FirstOrder: up.FirstOrder, Claimed: up.ClaimedTiers})
|
|
}
|
|
}
|
|
|
|
type claimTaskRequest struct {
|
|
TierID int64 `json:"tier_id"`
|
|
}
|
|
|
|
// @Summary 领取任务奖励(App)
|
|
// @Description 用户领取指定任务层级的奖励
|
|
// @Tags TaskCenter(App)
|
|
// @Accept json
|
|
// @Produce json
|
|
// @Param id path int true "任务ID"
|
|
// @Param user_id path int true "用户ID"
|
|
// @Param request body claimTaskRequest true "领取请求"
|
|
// @Success 200 {object} map[string]any "领取成功"
|
|
// @Router /api/app/task-center/tasks/{id}/claim/{user_id} [post]
|
|
func (h *handler) ClaimTaskTierForApp() core.HandlerFunc {
|
|
return func(ctx core.Context) {
|
|
taskID, err := strconv.ParseInt(ctx.Param("id"), 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递任务ID"))
|
|
return
|
|
}
|
|
uid, err := strconv.ParseInt(ctx.Param("user_id"), 10, 64)
|
|
if err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, "未传递用户ID"))
|
|
return
|
|
}
|
|
req := new(claimTaskRequest)
|
|
if err := ctx.ShouldBindJSON(req); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ParamBindError, validation.Error(err)))
|
|
return
|
|
}
|
|
if err := h.task.ClaimTier(ctx.RequestContext(), uid, taskID, req.TierID); err != nil {
|
|
ctx.AbortWithError(core.Error(http.StatusBadRequest, code.ServerError, err.Error()))
|
|
return
|
|
}
|
|
ctx.Payload(map[string]any{"ok": true})
|
|
}
|
|
}
|