package admin import ( "strings" "github.com/go-playground/validator/v10" "github.com/gofiber/fiber/v2" "github.com/break/junhong_cmp_fiber/internal/model/dto" pollingSvc "github.com/break/junhong_cmp_fiber/internal/service/polling" "github.com/break/junhong_cmp_fiber/pkg/errors" "github.com/break/junhong_cmp_fiber/pkg/response" ) // CarrierSchedulerHandler 按运营商账户调度的后台接口:调度参数、请求检查场景、失败告警、单卡轮询状态、按账户监控。 type CarrierSchedulerHandler struct { service *pollingSvc.CarrierSchedulerService validator *validator.Validate } // NewCarrierSchedulerHandler 创建按运营商账户调度 Handler。 func NewCarrierSchedulerHandler(service *pollingSvc.CarrierSchedulerService, validator *validator.Validate) *CarrierSchedulerHandler { return &CarrierSchedulerHandler{service: service, validator: validator} } func (h *CarrierSchedulerHandler) validate(prefix string, req any) error { if err := h.validator.Struct(req); err != nil { return errors.New(errors.CodeInvalidParam, validationMessage(prefix, req, err)) } return nil } // ListParams 查询运营商账户调度参数列表。GET /api/admin/polling-carrier-params func (h *CarrierSchedulerHandler) ListParams(c *fiber.Ctx) error { result, err := h.service.ListParams(c.UserContext()) if err != nil { return err } return response.Success(c, result) } // GetParam 查询运营商账户调度参数。GET /api/admin/polling-carrier-params/:carrier_id func (h *CarrierSchedulerHandler) GetParam(c *fiber.Ctx) error { carrierID, err := rateLimitPathID(c, "carrier_id", "运营商账户 ID") if err != nil { return err } result, err := h.service.GetParam(c.UserContext(), carrierID) if err != nil { return err } return response.Success(c, result) } // SaveParam 保存运营商账户调度参数。PUT /api/admin/polling-carrier-params/:carrier_id func (h *CarrierSchedulerHandler) SaveParam(c *fiber.Ctx) error { var req dto.SaveCarrierPollingParamRequest if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } carrierID, err := rateLimitPathID(c, "carrier_id", "运营商账户 ID") if err != nil { return err } req.CarrierID = carrierID if err := h.validate("运营商账户调度参数不合法", &req); err != nil { return err } result, err := h.service.SaveParam(c.UserContext(), &req) if err != nil { return err } return response.Success(c, result) } // DeleteParam 删除运营商账户调度参数(恢复全局默认)。DELETE /api/admin/polling-carrier-params/:carrier_id func (h *CarrierSchedulerHandler) DeleteParam(c *fiber.Ctx) error { carrierID, err := rateLimitPathID(c, "carrier_id", "运营商账户 ID") if err != nil { return err } if err := h.service.DeleteParam(c.UserContext(), carrierID); err != nil { return err } return response.Success(c, nil) } // ListScenes 查询请求检查场景。GET /api/admin/polling-check-scenes func (h *CarrierSchedulerHandler) ListScenes(c *fiber.Ctx) error { result, err := h.service.ListScenes(c.UserContext()) if err != nil { return err } return response.Success(c, result) } // UpdateScene 修改请求检查场景。PUT /api/admin/polling-check-scenes/:scene func (h *CarrierSchedulerHandler) UpdateScene(c *fiber.Ctx) error { var req dto.UpdatePollingCheckSceneRequest if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } req.Scene = strings.TrimSpace(c.Params("scene")) if req.Scene == "" { return errors.New(errors.CodeInvalidParam, "无效的场景编码") } if err := h.validate("请求检查场景参数不合法", &req); err != nil { return err } result, err := h.service.UpdateScene(c.UserContext(), &req) if err != nil { return err } return response.Success(c, result) } // ListAlerts 查询卡轮询失败告警列表。GET /api/admin/polling-failure-alerts func (h *CarrierSchedulerHandler) ListAlerts(c *fiber.Ctx) error { var req dto.PollingFailureAlertListRequest if err := c.QueryParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } if err := h.validate("卡轮询失败告警查询参数不合法", &req); err != nil { return err } result, err := h.service.ListAlerts(c.UserContext(), &req) if err != nil { return err } return response.Success(c, result) } // AlertSummary 未处理告警按运营商账户 × 错误类别汇总。GET /api/admin/polling-failure-alerts/summary func (h *CarrierSchedulerHandler) AlertSummary(c *fiber.Ctx) error { result, err := h.service.AlertSummary(c.UserContext()) if err != nil { return err } return response.Success(c, result) } // GetAlert 查询卡轮询失败告警详情。GET /api/admin/polling-failure-alerts/:id func (h *CarrierSchedulerHandler) GetAlert(c *fiber.Ctx) error { id, err := rateLimitPathID(c, "id", "告警 ID") if err != nil { return err } result, err := h.service.GetAlert(c.UserContext(), id) if err != nil { return err } return response.Success(c, result) } // HandleAlert 标记卡轮询失败告警已处理。PUT /api/admin/polling-failure-alerts/:id/status func (h *CarrierSchedulerHandler) HandleAlert(c *fiber.Ctx) error { var req dto.HandlePollingFailureAlertRequest if err := c.BodyParser(&req); err != nil { return errors.New(errors.CodeInvalidParam, "请求参数解析失败") } id, err := rateLimitPathID(c, "id", "告警 ID") if err != nil { return err } req.ID = id if err := h.validate("卡轮询失败告警处理参数不合法", &req); err != nil { return err } if err := h.service.HandleAlert(c.UserContext(), &req); err != nil { return err } return response.Success(c, nil) } // CardState 查询单卡轮询状态。GET /api/admin/iot-cards/:id/polling-state func (h *CarrierSchedulerHandler) CardState(c *fiber.Ctx) error { id, err := rateLimitPathID(c, "id", "卡 ID") if err != nil { return err } result, err := h.service.CardState(c.UserContext(), id) if err != nil { return err } return response.Success(c, result) } // CarrierStats 按运营商账户的轮询队列与执行监控。GET /api/admin/polling-stats/carrier-queues func (h *CarrierSchedulerHandler) CarrierStats(c *fiber.Ctx) error { result, err := h.service.CarrierStats(c.UserContext()) if err != nil { return err } return response.Success(c, result) }