- /polling-carrier-params 列表(含默认标记与消费能力)、详情、保存(执行上限不得大于订阅进程 max_in_flight 之和)、删除;/polling-check-scenes 列表与修改(检查类型、递增的确认延迟、冷却);/polling-failure-alerts 列表、按账户与错误类别汇总、详情、标记已处理;GET /iot-cards/:id/polling-state 单卡轮询状态;GET /polling-stats/carrier-queues 按账户队列与执行监控 - 读取仅超级管理员与平台账号,修改仅超级管理员(告警处理平台账号可用),均写统一审计;新增审计动作与资源 - carrier 模式下重算到期时间写入卡到期信息与账户队列,只提前不推后
196 lines
6.3 KiB
Go
196 lines
6.3 KiB
Go
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)
|
||
}
|