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"` RewardName string `json:"reward_name"` } 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, RewardName: r.RewardName} } } 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"` OrderAmount int64 `json:"order_amount"` 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, OrderAmount: up.OrderAmount, 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}) } }