Files
junhong_cmp_fiber/internal/bootstrap/carrier_check.go
邹进 0d966249b8 feat: 业务事件与读入口在按运营商账户调度时改为请求检查
- 请求检查器按场景配置(tb_polling_check_scene,缓存 30 秒)把卡的检查类型设为立即到期放入账户优先队列,同卡合并、冷却期内不请求、按场景追加延迟确认;设备按有效绑定卡展开
- 业务事件仍在原事务中写 Outbox(提交安全),carrier 模式下 Outbox 消费者把订单支付、套餐激活、自动续费购包、停复机成功事件转为请求检查,不再起三连查观测序列
- 读入口(C 端资产详情、后台资产实时状态、实名链接、设备操作)经模式接缝改为请求检查;设备信息同步保持原观测;OpenAPI 查询仍不触发
- legacy 模式下全部沿用原观测序列
2026-10-25 18:49:36 +09:00

122 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package bootstrap
import (
"context"
"strconv"
"strings"
cardObservationApp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation"
"github.com/break/junhong_cmp_fiber/internal/polling"
"github.com/break/junhong_cmp_fiber/pkg/constants"
)
// carrierAwareSeriesDispatcher 是读入口观测分发的模式接缝:按运营商账户调度时把读入口改为按场景请求检查
// (同卡合并、冷却、受账户限流),不再起"立即、3 分钟、5 分钟"观测序列;旧分片调度时沿用原分发器。
type carrierAwareSeriesDispatcher struct {
legacy cardObservationApp.BestEffortSeriesDispatcher
requester *polling.CheckRequester
}
var _ cardObservationApp.BestEffortSeriesDispatcher = (*carrierAwareSeriesDispatcher)(nil)
// ReadEntryCheckScene 把读入口与设备控制的观测场景映射为请求检查场景;不认识的场景返回空串。
func ReadEntryCheckScene(observationScene string) string {
switch observationScene {
case constants.CardObservationSceneClientAssetRead:
return constants.PollingCheckSceneClientAssetDetail
case constants.CardObservationSceneAdminAssetRead:
return constants.PollingCheckSceneAdminAssetRealtime
case constants.CardObservationSceneClientRealnameLink, constants.CardObservationSceneAdminRealnameLink:
return constants.PollingCheckSceneRealnameLink
case constants.CardObservationSceneBusinessStop, constants.CardObservationSceneBusinessResume:
return constants.PollingCheckSceneStopResumeSucceeded
case constants.CardObservationScenePackageChanged:
return constants.PollingCheckScenePackageActivated
case constants.CardObservationSceneDeviceSwitchCard, constants.CardObservationSceneDeviceSwitchMode,
constants.CardObservationSceneDeviceReboot, constants.CardObservationSceneDeviceReset, constants.CardObservationSceneDeviceSetWiFi:
return constants.PollingCheckSceneDeviceOperation
default:
return ""
}
}
func (d *carrierAwareSeriesDispatcher) active(ctx context.Context) bool {
return d.requester != nil && d.requester.Active(ctx)
}
// Dispatch 读入口单卡(或设备)观测。
func (d *carrierAwareSeriesDispatcher) Dispatch(ctx context.Context, request cardObservationApp.SeriesRequest) {
if !d.active(ctx) {
d.legacy.Dispatch(ctx, request)
return
}
scene := ReadEntryCheckScene(request.Scene)
if scene == "" {
return
}
id, err := strconv.ParseUint(request.ResourceID, 10, 64)
if err != nil || id == 0 {
return
}
if request.ResourceType == constants.CardObservationResourceTypeDevice {
d.requester.RequestDevice(ctx, scene, uint(id))
return
}
d.requester.RequestCards(ctx, scene, []uint{uint(id)}, request.ExpectedValue)
}
// DispatchDeviceCards 设备有效绑定卡观测。
func (d *carrierAwareSeriesDispatcher) DispatchDeviceCards(ctx context.Context, request cardObservationApp.DeviceCardsSeriesRequest) {
if !d.active(ctx) {
d.legacy.DispatchDeviceCards(ctx, request)
return
}
if scene := ReadEntryCheckScene(request.Request.Scene); scene != "" {
d.requester.RequestDevice(ctx, scene, request.DeviceID)
}
}
// DispatchDeviceControl 设备控制成功后的观测:按设备操作场景为设备下各卡请求检查。
func (d *carrierAwareSeriesDispatcher) DispatchDeviceControl(ctx context.Context, request cardObservationApp.DeviceControlSeriesRequest) {
if !d.active(ctx) {
d.legacy.DispatchDeviceControl(ctx, request)
return
}
// 设备信息同步(query_device_info,非运营商上游)保持原观测,只把卡检查改为请求检查。
deviceInfo := request.Request
deviceInfo.ResourceType = constants.CardObservationResourceTypeDevice
deviceInfo.ResourceID = strconv.FormatUint(uint64(request.DeviceID), 10)
deviceInfo.SyncType = constants.CardObservationSyncTypeDeviceInfo
deviceInfo.ExpectedValue = strings.TrimSpace(request.TargetICCID)
d.legacy.Dispatch(ctx, deviceInfo)
cardIDs := append([]uint(nil), request.BoundCardIDs...)
for _, id := range []uint{request.SourceCardID, request.TargetCardID} {
if id != 0 && !containsUint(cardIDs, id) {
cardIDs = append(cardIDs, id)
}
}
if len(cardIDs) == 0 && request.DeviceID != 0 {
d.requester.RequestDevice(ctx, constants.PollingCheckSceneDeviceOperation, request.DeviceID)
return
}
d.requester.RequestCards(ctx, constants.PollingCheckSceneDeviceOperation, cardIDs, "")
}
// DispatchRealnameWithCapability 获取实名链接后的实名观测。
func (d *carrierAwareSeriesDispatcher) DispatchRealnameWithCapability(ctx context.Context, request cardObservationApp.RealnameCapabilitySeriesRequest) {
if !d.active(ctx) {
d.legacy.DispatchRealnameWithCapability(ctx, request)
return
}
d.Dispatch(ctx, request.Request)
}
func containsUint(values []uint, target uint) bool {
for _, value := range values {
if value == target {
return true
}
}
return false
}