feat: 分层轮询、重置日前加密与激活前流量结算
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m37s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m37s
- 轮询配置新增套餐状态、资产状态、重置日前窗口与窗口内流量间隔(迁移 248),间隔三态:正数按间隔、0 不检查、空继承 - 配置按 priority, id 排序合并;在库与已销售无套餐未匹配时告警不入队 - 新增优先级整体重排、匹配预览、立即重算到期时间(异步只提前)、分层统计与重置日前加密统计接口 - 已切换日快照计量的卡流量按观测时间归属,激活前用量只记已结算 - 订单购买与实名激活补齐资产级激活锁,激活前对已切换卡结算一次流量,失败只告警不阻塞,结算不触发通道阈值判定
This commit is contained in:
@@ -191,3 +191,91 @@ func (h *PollingConfigHandler) ListEnabled(c *fiber.Ctx) error {
|
||||
|
||||
return response.Success(c, configs)
|
||||
}
|
||||
|
||||
// UpdatePriorities 按给定顺序整体调整轮询配置优先级(仅超级管理员)。
|
||||
// PUT /api/admin/polling-configs/priorities
|
||||
func (h *PollingConfigHandler) UpdatePriorities(c *fiber.Ctx) error {
|
||||
var req dto.UpdatePollingConfigPrioritiesRequest
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||||
}
|
||||
if len(req.OrderedIDs) == 0 {
|
||||
return errors.New(errors.CodeInvalidParam, "轮询配置优先级参数不合法:配置 ID 列表不能为空")
|
||||
}
|
||||
if err := h.service.UpdatePriorities(c.UserContext(), &req); err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, nil)
|
||||
}
|
||||
|
||||
// MatchPreview 预览一张卡的轮询配置匹配结果;GET 只按当前配置,POST 可带未保存修改,均不写数据。
|
||||
// GET /api/admin/polling-configs/match-preview
|
||||
// POST /api/admin/polling-configs/match-preview
|
||||
func (h *PollingConfigHandler) MatchPreview(c *fiber.Ctx) error {
|
||||
var req dto.PollingConfigMatchPreviewRequest
|
||||
if c.Method() == fiber.MethodPost {
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||||
}
|
||||
} else if err := c.QueryParser(&req); err != nil {
|
||||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||||
}
|
||||
if req.ICCID == "" {
|
||||
return errors.New(errors.CodeInvalidParam, "匹配预览参数不合法:ICCID 不能为空")
|
||||
}
|
||||
result, err := h.service.MatchPreview(c.UserContext(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, result)
|
||||
}
|
||||
|
||||
// CreateRecalculateTask 创建"立即重算到期时间"异步任务(仅超级管理员)。
|
||||
// POST /api/admin/polling-configs/recalculate-due
|
||||
func (h *PollingConfigHandler) CreateRecalculateTask(c *fiber.Ctx) error {
|
||||
var req dto.PollingRecalculateDueRequest
|
||||
if len(c.Body()) > 0 {
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return errors.New(errors.CodeInvalidParam, "请求参数解析失败")
|
||||
}
|
||||
}
|
||||
result, err := h.service.CreateRecalculateTask(c.UserContext(), &req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, result)
|
||||
}
|
||||
|
||||
// GetRecalculateTask 查询重算到期时间任务进度。
|
||||
// GET /api/admin/polling-configs/recalculate-due/:task_id
|
||||
func (h *PollingConfigHandler) GetRecalculateTask(c *fiber.Ctx) error {
|
||||
taskID := c.Params("task_id")
|
||||
if taskID == "" {
|
||||
return errors.New(errors.CodeInvalidParam, "重算任务 ID 不能为空")
|
||||
}
|
||||
result, err := h.service.GetRecalculateTask(c.UserContext(), taskID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, result)
|
||||
}
|
||||
|
||||
// TierStats 查询分层轮询统计(结果缓存 5 分钟)。
|
||||
// GET /api/admin/polling-stats/tiers
|
||||
func (h *PollingConfigHandler) TierStats(c *fiber.Ctx) error {
|
||||
result, err := h.service.TierStats(c.UserContext())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, result)
|
||||
}
|
||||
|
||||
// PreResetStats 查询重置日前加密效果统计。
|
||||
// GET /api/admin/polling-stats/pre-reset
|
||||
func (h *PollingConfigHandler) PreResetStats(c *fiber.Ctx) error {
|
||||
result, err := h.service.PreResetStats(c.UserContext())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return response.Success(c, result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user