All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m26s
统一停复机规则转正的第一次发布:总开关仍关闭,现有停复机行为不变。 - 新增停复机规则演练:GET /stop-resume-rule/dry-run 按新规则对开机与停机卡只判断不执行,返回运营商账户 × 停机原因 × 判断结果汇总与分页明细,可假设通道实名管控配置;POST /stop-resume-rule/dry-run/export 导出明细(场景 stop_resume_rule_dry_run);仅超级管理员与平台账号 - 风险停机、已销户关闭轮询不再限于独立卡,只关该卡自身轮询,不级联设备 - 错误分类规则增加 auto_disable_polling,仅终态类别可勾选;停复机(含设备停复机)命中该规则时不重试、关闭该卡轮询、回写网关扩展状态并写审计 iot_card.terminal_disable_polling - 迁移 000250 加列与约束,并为"已销户""仅支持风险复机"置位
138 lines
4.8 KiB
Go
138 lines
4.8 KiB
Go
// Package stopresume 定义停复机新规则的纯判断:输入卡与资产的当前事实,输出目标动作,不读写任何外部状态。
|
||
//
|
||
// 新规则(finalize-unified-stop-resume-rule):
|
||
// - 卡或其有效绑定设备暂停轮询时不自动停复机;
|
||
// - 开机卡命中任一停机条件即停机:无套餐、流量用完、通道开启实名管控且卡未实名;
|
||
// - 停机卡同时满足有套餐、流量未用完、实名条件时复机,不看停机原因;持本周期通道阈值锁的卡拒绝复机;
|
||
// - 卡所属通道不存在(无法判断实名管控)时本次不动作。
|
||
package stopresume
|
||
|
||
import "github.com/break/junhong_cmp_fiber/pkg/constants"
|
||
|
||
// 判断结果。
|
||
const (
|
||
ResultWillResume = "will_resume" // 将复机
|
||
ResultWillStop = "will_stop" // 将停机
|
||
ResultNoAction = "no_action" // 不动作
|
||
)
|
||
|
||
// 不动作原因。
|
||
const (
|
||
NoActionPollingSuspended = "polling_suspended" // 卡或所在设备暂停轮询
|
||
NoActionConditionsMet = "conditions_met" // 开机卡满足开机条件
|
||
NoActionNoPackage = "no_package" // 停机卡无套餐(与停机原因同值,共用名称)
|
||
NoActionTrafficExhausted = "traffic_exhausted" // 停机卡流量已用完
|
||
NoActionNotRealname = "not_realname" // 停机卡所属通道开启实名管控且卡未实名
|
||
NoActionThresholdLocked = "threshold_locked" // 停机卡持本周期通道阈值锁
|
||
NoActionCarrierMissing = "carrier_missing" // 卡所属通道不存在,无法判断实名管控
|
||
NoActionUnknownNetwork = "unknown_network" // 卡网络状态既非开机也非停机
|
||
)
|
||
|
||
// Facts 是判断一张卡所需的全部事实;套餐与流量按绑定设备(有有效绑定时)或卡自身计算。
|
||
type Facts struct {
|
||
NetworkStatus int
|
||
PollingSuspended bool // 卡自身或其有效绑定设备暂停轮询
|
||
HasValidPackage bool // 存在生效中的套餐
|
||
TrafficExhausted bool // 生效或已用完的套餐全部达到流量上限
|
||
RealnameVerified bool
|
||
CarrierKnown bool // 卡所属通道存在
|
||
RealnameControl bool // 卡所属通道开启实名管控(可为假设值)
|
||
ThresholdLocked bool // 持本周期通道阈值锁
|
||
CurrentStopReason string
|
||
}
|
||
|
||
// Decision 是一张卡的判断结果。
|
||
type Decision struct {
|
||
Result string // ResultWillResume / ResultWillStop / ResultNoAction
|
||
Reason string // 将停机时为目标停机原因;不动作时为不动作原因;将复机时为空
|
||
StopReason string // 将停机时的目标停机原因
|
||
}
|
||
|
||
// Decide 按新规则判断卡的目标动作。
|
||
func Decide(f Facts) Decision {
|
||
if f.PollingSuspended {
|
||
return noAction(NoActionPollingSuspended)
|
||
}
|
||
if !f.CarrierKnown {
|
||
return noAction(NoActionCarrierMissing)
|
||
}
|
||
realnameOK := !f.RealnameControl || f.RealnameVerified
|
||
switch f.NetworkStatus {
|
||
case constants.NetworkStatusOnline:
|
||
// 停机原因优先级:流量用完 > 无套餐(仅在未用完时判断)> 未实名,与评估主流程一致。
|
||
switch {
|
||
case f.TrafficExhausted:
|
||
return stop(constants.StopReasonTrafficExhausted)
|
||
case !f.HasValidPackage:
|
||
return stop(constants.StopReasonNoPackage)
|
||
case !realnameOK:
|
||
return stop(constants.StopReasonNotRealname)
|
||
default:
|
||
return noAction(NoActionConditionsMet)
|
||
}
|
||
case constants.NetworkStatusOffline:
|
||
switch {
|
||
case !f.HasValidPackage:
|
||
return noAction(NoActionNoPackage)
|
||
case f.TrafficExhausted:
|
||
return noAction(NoActionTrafficExhausted)
|
||
case !realnameOK:
|
||
return noAction(NoActionNotRealname)
|
||
case f.ThresholdLocked:
|
||
return noAction(NoActionThresholdLocked)
|
||
default:
|
||
return Decision{Result: ResultWillResume}
|
||
}
|
||
default:
|
||
return noAction(NoActionUnknownNetwork)
|
||
}
|
||
}
|
||
|
||
func stop(reason string) Decision {
|
||
return Decision{Result: ResultWillStop, Reason: reason, StopReason: reason}
|
||
}
|
||
|
||
func noAction(reason string) Decision {
|
||
return Decision{Result: ResultNoAction, Reason: reason}
|
||
}
|
||
|
||
// ResultName 返回判断结果中文名称。
|
||
func ResultName(result string) string {
|
||
switch result {
|
||
case ResultWillResume:
|
||
return "将复机"
|
||
case ResultWillStop:
|
||
return "将停机"
|
||
case ResultNoAction:
|
||
return "不动作"
|
||
default:
|
||
return result
|
||
}
|
||
}
|
||
|
||
// ReasonName 返回停机原因或不动作原因的中文名称。
|
||
func ReasonName(reason string) string {
|
||
switch reason {
|
||
case "":
|
||
return ""
|
||
case NoActionPollingSuspended:
|
||
return "暂停轮询"
|
||
case NoActionConditionsMet:
|
||
return "满足开机条件"
|
||
case NoActionNoPackage:
|
||
return "无套餐"
|
||
case NoActionTrafficExhausted:
|
||
return "流量已用完"
|
||
case NoActionNotRealname:
|
||
return "未实名(通道开启实名管控)"
|
||
case NoActionThresholdLocked:
|
||
return "持通道阈值锁"
|
||
case NoActionCarrierMissing:
|
||
return "所属通道不存在"
|
||
case NoActionUnknownNetwork:
|
||
return "网络状态未知"
|
||
default:
|
||
return reason
|
||
}
|
||
}
|