邹方成 45815bfb7d chore: 清理无用文件与优化代码结构
refactor(utils): 修复密码哈希比较逻辑错误
feat(user): 新增按状态筛选优惠券接口
docs: 添加虚拟发货与任务中心相关文档
fix(wechat): 修正Code2Session上下文传递问题
test: 补充订单折扣与积分转换测试用例
build: 更新配置文件与构建脚本
style: 清理多余的空行与注释
2025-12-18 17:35:55 +08:00

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 /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 /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 /app/task_center/tasks/{id}/users/{user_id}/claim [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})
}
}