91 lines
3.3 KiB
Go
91 lines
3.3 KiB
Go
package cardobservation
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/break/junhong_cmp_fiber/pkg/constants"
|
|
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
|
)
|
|
|
|
// NetworkObservation 是领域层接收的标准 Gateway 网络观测。
|
|
type NetworkObservation struct {
|
|
CardID uint
|
|
GatewayStatus string
|
|
GatewayExtend string
|
|
GatewayIMEI string
|
|
Metadata ObservationMetadata
|
|
}
|
|
|
|
// CardNetworkSnapshot 是网络规则需要的最小卡快照。
|
|
type CardNetworkSnapshot struct {
|
|
CardID uint
|
|
NetworkStatus int
|
|
StopReason string
|
|
IsStandalone bool
|
|
EnablePolling bool
|
|
}
|
|
|
|
// NetworkDecision 描述一次网络观测可安全持久化的最终值。
|
|
type NetworkDecision struct {
|
|
StatusKnown bool
|
|
StatusChanged bool
|
|
BeforeStatus int
|
|
AfterStatus int
|
|
GatewayExtend string
|
|
GatewayIMEI string
|
|
UpdateIMEI bool
|
|
StopReason string
|
|
StopReasonChanged bool
|
|
StopPolling bool
|
|
}
|
|
|
|
// ApplyNetwork 应用 Gateway 状态映射、运营商停机原因和独立风险卡规则。
|
|
func ApplyNetwork(snapshot CardNetworkSnapshot, observation NetworkObservation) (NetworkDecision, error) {
|
|
if err := validateObservationMetadata(observation.CardID, observation.Metadata); err != nil {
|
|
return NetworkDecision{}, err
|
|
}
|
|
if snapshot.NetworkStatus != constants.NetworkStatusOffline && snapshot.NetworkStatus != constants.NetworkStatusOnline {
|
|
return NetworkDecision{}, errors.New(errors.CodeInvalidStatus, "卡网络状态无效")
|
|
}
|
|
status, known := MapGatewayNetworkStatus(observation.GatewayStatus, observation.GatewayExtend)
|
|
extend := strings.TrimSpace(observation.GatewayExtend)
|
|
imei := strings.TrimSpace(observation.GatewayIMEI)
|
|
decision := NetworkDecision{
|
|
StatusKnown: known, BeforeStatus: snapshot.NetworkStatus, AfterStatus: snapshot.NetworkStatus,
|
|
GatewayExtend: extend, GatewayIMEI: imei, UpdateIMEI: imei != "", StopReason: snapshot.StopReason,
|
|
StopPolling: snapshot.EnablePolling && ShouldStopPollingForRisk(snapshot.IsStandalone, extend),
|
|
}
|
|
if !known {
|
|
return decision, nil
|
|
}
|
|
decision.AfterStatus = status
|
|
decision.StatusChanged = status != snapshot.NetworkStatus
|
|
if decision.StatusChanged && status == constants.NetworkStatusOffline && snapshot.StopReason == "" &&
|
|
strings.TrimSpace(observation.GatewayStatus) == constants.GatewayCardStatusStopped {
|
|
decision.StopReason = constants.StopReasonCarrierStopped
|
|
decision.StopReasonChanged = true
|
|
}
|
|
return decision, nil
|
|
}
|
|
|
|
// MapGatewayNetworkStatus 将 Gateway 状态稳定映射为本地网络状态。
|
|
func MapGatewayNetworkStatus(cardStatus, extend string) (int, bool) {
|
|
status := strings.TrimSpace(cardStatus)
|
|
ext := strings.TrimSpace(extend)
|
|
switch status {
|
|
case constants.GatewayCardStatusNormal:
|
|
return constants.NetworkStatusOnline, true
|
|
case constants.GatewayCardStatusStopped, constants.GatewayCardStatusReady:
|
|
return constants.NetworkStatusOffline, true
|
|
}
|
|
if ext == constants.GatewayCardExtendPendingActivation {
|
|
return constants.NetworkStatusOffline, true
|
|
}
|
|
return constants.NetworkStatusOffline, false
|
|
}
|
|
|
|
// ShouldStopPollingForRisk 判断独立卡是否命中运营商风险终止状态。
|
|
func ShouldStopPollingForRisk(isStandalone bool, extend string) bool {
|
|
return isStandalone && (extend == constants.GatewayCardExtendRiskStop || extend == constants.GatewayCardExtendCancelled)
|
|
}
|