package admin import ( "github.com/gofiber/fiber/v2" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/model/dto" "github.com/break/junhong_cmp_fiber/internal/service/polling" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/middleware" "github.com/break/junhong_cmp_fiber/pkg/response" ) // PollingManualTriggerHandler 轮询手动触发处理器 type PollingManualTriggerHandler struct { service *polling.ManualTriggerService } // NewPollingManualTriggerHandler 创建轮询手动触发处理器 func NewPollingManualTriggerHandler(service *polling.ManualTriggerService) *PollingManualTriggerHandler { return &PollingManualTriggerHandler{service: service} } // TriggerSingle 单卡手动触发 // @Summary 单卡手动触发 // @Description 触发单张卡的轮询任务 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Param request body dto.TriggerSingleReq true "触发请求" // @Success 200 {object} response.Response // @Router /api/admin/polling-manual-trigger/single [post] func (h *PollingManualTriggerHandler) TriggerSingle(c *fiber.Ctx) error { ctx := c.UserContext() var req dto.TriggerSingleReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return errors.New(errors.CodeUnauthorized) } if err := h.service.TriggerSingle(ctx, req.CardID, req.TaskType, userID); err != nil { return err } return response.Success(c, nil) } // TriggerBatch 批量手动触发 // @Summary 批量手动触发 // @Description 批量触发多张卡的轮询任务 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Param request body dto.TriggerBatchReq true "触发请求" // @Success 200 {object} response.Response{data=dto.ManualTriggerLogResp} // @Router /api/admin/polling-manual-trigger/batch [post] func (h *PollingManualTriggerHandler) TriggerBatch(c *fiber.Ctx) error { ctx := c.UserContext() var req dto.TriggerBatchReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return errors.New(errors.CodeUnauthorized) } log, err := h.service.TriggerBatch(ctx, req.CardIDs, req.TaskType, userID) if err != nil { return err } return response.Success(c, h.toLogResp(log)) } // TriggerByCondition 条件筛选触发 // @Summary 条件筛选触发 // @Description 根据条件筛选卡并触发轮询任务 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Param request body dto.TriggerByConditionReq true "触发请求" // @Success 200 {object} response.Response{data=dto.ManualTriggerLogResp} // @Router /api/admin/polling-manual-trigger/by-condition [post] func (h *PollingManualTriggerHandler) TriggerByCondition(c *fiber.Ctx) error { ctx := c.UserContext() var req dto.TriggerByConditionReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return errors.New(errors.CodeUnauthorized) } filter := &polling.ConditionFilter{ CardStatus: req.CardStatus, CarrierCode: req.CarrierCode, CardType: req.CardType, ShopID: req.ShopID, PackageIDs: req.PackageIDs, EnablePolling: req.EnablePolling, Limit: req.Limit, } log, err := h.service.TriggerByCondition(ctx, filter, req.TaskType, userID) if err != nil { return err } return response.Success(c, h.toLogResp(log)) } // GetStatus 获取触发状态 // @Summary 获取手动触发状态 // @Description 获取当前用户的手动触发状态 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Success 200 {object} response.Response{data=dto.ManualTriggerStatusResp} // @Router /api/admin/polling-manual-trigger/status [get] func (h *PollingManualTriggerHandler) GetStatus(c *fiber.Ctx) error { ctx := c.UserContext() userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return errors.New(errors.CodeUnauthorized) } // 获取正在运行的任务 runningTasks, err := h.service.GetRunningTasks(ctx, userID) if err != nil { return err } items := make([]*dto.ManualTriggerLogResp, 0, len(runningTasks)) for _, log := range runningTasks { items = append(items, h.toLogResp(log)) } // 获取各队列大小 queueSizes := make(map[string]int64) for _, taskType := range []string{ constants.TaskTypePollingRealname, constants.TaskTypePollingCarddata, constants.TaskTypePollingPackage, } { size, _ := h.service.GetQueueSize(ctx, taskType) queueSizes[taskType] = size } return response.Success(c, &dto.ManualTriggerStatusResp{ RunningTasks: items, QueueSizes: queueSizes, }) } // ListHistory 获取触发历史 // @Summary 获取手动触发历史 // @Description 获取手动触发历史记录 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Param task_type query string false "任务类型筛选" // @Param page query int false "页码" // @Param page_size query int false "每页数量" // @Success 200 {object} response.Response{data=dto.ManualTriggerLogListResp} // @Router /api/admin/polling-manual-trigger/history [get] func (h *PollingManualTriggerHandler) ListHistory(c *fiber.Ctx) error { ctx := c.UserContext() var req dto.ListManualTriggerLogReq if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } if req.Page < 1 { req.Page = 1 } if req.PageSize < 1 || req.PageSize > 100 { req.PageSize = 20 } logs, total, err := h.service.ListHistory(ctx, req.Page, req.PageSize, req.TaskType, nil) if err != nil { return err } items := make([]*dto.ManualTriggerLogResp, 0, len(logs)) for _, log := range logs { items = append(items, h.toLogResp(log)) } totalPages := int(total) / req.PageSize if int(total)%req.PageSize > 0 { totalPages++ } return response.Success(c, &dto.ManualTriggerLogListResp{ Items: items, Total: total, Page: req.Page, PageSize: req.PageSize, TotalPages: totalPages, }) } // CancelTrigger 取消触发任务 // @Summary 取消手动触发任务 // @Description 取消正在执行的手动触发任务 // @Tags 轮询管理-手动触发 // @Accept json // @Produce json // @Security BearerAuth // @Param request body dto.CancelTriggerReq true "取消请求" // @Success 200 {object} response.Response // @Router /api/admin/polling-manual-trigger/cancel [post] func (h *PollingManualTriggerHandler) CancelTrigger(c *fiber.Ctx) error { ctx := c.UserContext() var req dto.CancelTriggerReq if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam) } userID := middleware.GetUserIDFromContext(ctx) if userID == 0 { return errors.New(errors.CodeUnauthorized) } if err := h.service.CancelTrigger(ctx, req.TriggerID, userID); err != nil { return err } return response.Success(c, nil) } func (h *PollingManualTriggerHandler) toLogResp(log *model.PollingManualTriggerLog) *dto.ManualTriggerLogResp { return &dto.ManualTriggerLogResp{ ID: log.ID, TaskType: log.TaskType, TaskTypeName: h.getTaskTypeName(log.TaskType), TriggerType: log.TriggerType, TriggerTypeName: h.getTriggerTypeName(log.TriggerType), TotalCount: log.TotalCount, ProcessedCount: log.ProcessedCount, SuccessCount: log.SuccessCount, FailedCount: log.FailedCount, Status: log.Status, StatusName: h.getStatusName(log.Status), TriggeredBy: log.TriggeredBy, TriggeredAt: log.TriggeredAt, CompletedAt: log.CompletedAt, } } func (h *PollingManualTriggerHandler) getTaskTypeName(taskType string) string { switch taskType { case constants.TaskTypePollingRealname: return "实名检查" case constants.TaskTypePollingCarddata: return "流量检查" case constants.TaskTypePollingPackage: return "套餐检查" default: return taskType } } func (h *PollingManualTriggerHandler) getTriggerTypeName(triggerType string) string { switch triggerType { case "single": return "单卡触发" case "batch": return "批量触发" case "by_condition": return "条件筛选" default: return triggerType } } func (h *PollingManualTriggerHandler) getStatusName(status string) string { switch status { case "pending": return "待处理" case "processing": return "处理中" case "completed": return "已完成" case "cancelled": return "已取消" default: return status } }