All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m30s
- 后台设备停复机不再设置 1 小时保护期,也不再因保护期拒绝相反操作;单卡手动停复机去掉保护期检查 - 删除保护期一致性轮询(polling:protect)及其强制停复机方法;调度、初始化、监控、匹配预览不再包含保护期;已入队的旧任务由空处理函数直接确认,下一次发布移除 - 轮询配置接口不再接受与返回 protect_check_interval;并发配置不再返回 protect,查询、更新、重置该类型时拒绝 - 资产详情 device_protect_status 固定返回 none 并标记废弃,兼容老版本客户端 - 删除保护期 Redis key 与时长常量;停机原因 protect_period 保留供历史数据与开放接口映射 - 迁移 000249 只把 protect_check_interval、last_protect_check_at 列注释标记为已废弃,不删列不改数据
245 lines
22 KiB
Go
245 lines
22 KiB
Go
package dto
|
||
|
||
// CreatePollingConfigRequest 创建轮询配置请求
|
||
type CreatePollingConfigRequest struct {
|
||
ConfigName string `json:"config_name" validate:"required,min=1,max=100" required:"true" minLength:"1" maxLength:"100" description:"配置名称"`
|
||
CardCondition string `json:"card_condition" validate:"omitempty,oneof=not_real_name real_name activated suspended" description:"卡状态条件 (not_real_name:未实名, real_name:已实名, activated:已激活, suspended:已停用)"`
|
||
CardCategory string `json:"card_category" validate:"omitempty,oneof=normal industry" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
|
||
CarrierID *uint `json:"carrier_id" validate:"omitempty" description:"运营商ID(可选,精确匹配)"`
|
||
Priority int `json:"priority" validate:"required,min=1,max=1000" required:"true" minimum:"1" maximum:"1000" description:"优先级(数字越小优先级越高)"`
|
||
RealnameCheckInterval *int `json:"realname_check_interval" validate:"omitempty,min=0" minimum:"0" description:"实名检查间隔(秒):正数按间隔(最小30秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
CarddataCheckInterval *int `json:"carddata_check_interval" validate:"omitempty,min=0" minimum:"0" description:"流量检查间隔(秒):正数按间隔(最小60秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
PackageCheckInterval *int `json:"package_check_interval" validate:"omitempty,min=0" minimum:"0" description:"套餐检查间隔(秒):正数按间隔(最小60秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
CardStatusCheckInterval *int `json:"card_status_check_interval" validate:"omitempty,min=0" minimum:"0" description:"卡状态检查间隔(秒):正数按间隔(最小30秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
PackageState *string `json:"package_state" validate:"omitempty,oneof=active depleted pending none" enum:"active,depleted,pending,none" description:"套餐状态匹配 (active:有生效套餐, depleted:套餐已用完, pending:只有待生效套餐, none:无套餐),为空不限"`
|
||
AssetStatus *int `json:"asset_status" validate:"omitempty,oneof=1 2 3 4" enum:"1,2,3,4" description:"资产状态匹配 (1:在库, 2:已销售, 3:已换货, 4:已停用),为空不限"`
|
||
PreResetWindow *int `json:"pre_reset_window" validate:"omitempty,min=60" minimum:"60" description:"重置日前加密窗口长度(秒),与窗口内流量间隔同时配置才生效"`
|
||
PreResetCarddataInterval *int `json:"pre_reset_carddata_interval" validate:"omitempty,min=60" minimum:"60" description:"重置日前窗口内的流量检查间隔(秒),与窗口长度同时配置才生效"`
|
||
Description string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"配置说明"`
|
||
}
|
||
|
||
// UpdatePollingConfigRequest 更新轮询配置请求
|
||
type UpdatePollingConfigRequest struct {
|
||
ConfigName *string `json:"config_name" validate:"omitempty,min=1,max=100" minLength:"1" maxLength:"100" description:"配置名称"`
|
||
CardCondition *string `json:"card_condition" validate:"omitempty,oneof=not_real_name real_name activated suspended" description:"卡状态条件 (not_real_name:未实名, real_name:已实名, activated:已激活, suspended:已停用)"`
|
||
CardCategory *string `json:"card_category" validate:"omitempty,oneof=normal industry" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
|
||
CarrierID *uint `json:"carrier_id" validate:"omitempty" description:"运营商ID(可选,精确匹配)"`
|
||
Priority *int `json:"priority" validate:"omitempty,min=1,max=1000" minimum:"1" maximum:"1000" description:"优先级(数字越小优先级越高)"`
|
||
RealnameCheckInterval *int `json:"realname_check_interval" validate:"omitempty,min=0" minimum:"0" description:"实名检查间隔(秒):正数按间隔(最小30秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
CarddataCheckInterval *int `json:"carddata_check_interval" validate:"omitempty,min=0" minimum:"0" description:"流量检查间隔(秒):正数按间隔(最小60秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
PackageCheckInterval *int `json:"package_check_interval" validate:"omitempty,min=0" minimum:"0" description:"套餐检查间隔(秒):正数按间隔(最小60秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
CardStatusCheckInterval *int `json:"card_status_check_interval" validate:"omitempty,min=0" minimum:"0" description:"卡状态检查间隔(秒):正数按间隔(最小30秒),0 不检查且不再继承,不传或为空继承优先级更低的配置"`
|
||
PackageState *string `json:"package_state" validate:"omitempty,oneof=active depleted pending none" enum:"active,depleted,pending,none" description:"套餐状态匹配 (active:有生效套餐, depleted:套餐已用完, pending:只有待生效套餐, none:无套餐),为空不限"`
|
||
AssetStatus *int `json:"asset_status" validate:"omitempty,oneof=1 2 3 4" enum:"1,2,3,4" description:"资产状态匹配 (1:在库, 2:已销售, 3:已换货, 4:已停用),为空不限"`
|
||
PreResetWindow *int `json:"pre_reset_window" validate:"omitempty,min=60" minimum:"60" description:"重置日前加密窗口长度(秒),与窗口内流量间隔同时配置才生效"`
|
||
PreResetCarddataInterval *int `json:"pre_reset_carddata_interval" validate:"omitempty,min=60" minimum:"60" description:"重置日前窗口内的流量检查间隔(秒),与窗口长度同时配置才生效"`
|
||
ClearFields []PollingConfigClearField `json:"clear_fields" validate:"omitempty,dive,oneof=realname_check_interval carddata_check_interval package_check_interval card_status_check_interval carrier_id package_state asset_status pre_reset_window pre_reset_carddata_interval" description:"要清空为空值的字段(间隔清空即改为继承,匹配条件清空即不限):realname_check_interval/carddata_check_interval/package_check_interval/card_status_check_interval/carrier_id/package_state/asset_status/pre_reset_window/pre_reset_carddata_interval"`
|
||
Description *string `json:"description" validate:"omitempty,max=500" maxLength:"500" description:"配置说明"`
|
||
}
|
||
|
||
// PollingConfigListRequest 轮询配置列表请求
|
||
type PollingConfigListRequest struct {
|
||
Page int `json:"page" query:"page" validate:"omitempty,min=1" minimum:"1" description:"页码"`
|
||
PageSize int `json:"page_size" query:"page_size" validate:"omitempty,min=1,max=100" minimum:"1" maximum:"100" description:"每页数量"`
|
||
Status *int16 `json:"status" query:"status" validate:"omitempty,oneof=0 1" description:"状态 (1:启用, 0:禁用)"`
|
||
CardCondition *string `json:"card_condition" query:"card_condition" validate:"omitempty,oneof=not_real_name real_name activated suspended" description:"卡状态条件"`
|
||
CardCategory *string `json:"card_category" query:"card_category" validate:"omitempty,oneof=normal industry" description:"卡业务类型"`
|
||
CarrierID *uint `json:"carrier_id" query:"carrier_id" validate:"omitempty" description:"运营商ID"`
|
||
ConfigName *string `json:"config_name" query:"config_name" validate:"omitempty,max=100" maxLength:"100" description:"配置名称(模糊搜索)"`
|
||
}
|
||
|
||
// UpdatePollingConfigStatusRequest 更新轮询配置状态请求
|
||
type UpdatePollingConfigStatusRequest struct {
|
||
Status int16 `json:"status" validate:"required,oneof=0 1" required:"true" description:"状态 (1:启用, 0:禁用)"`
|
||
}
|
||
|
||
// PollingConfigResponse 轮询配置响应
|
||
type PollingConfigResponse struct {
|
||
ID uint `json:"id" description:"配置ID"`
|
||
ConfigName string `json:"config_name" description:"配置名称"`
|
||
CardCondition string `json:"card_condition" description:"卡状态条件 (not_real_name:未实名, real_name:已实名, activated:已激活, suspended:已停用)"`
|
||
CardCategory string `json:"card_category" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
|
||
CarrierID *uint `json:"carrier_id" description:"运营商ID"`
|
||
Priority int `json:"priority" description:"优先级(数字越小优先级越高)"`
|
||
RealnameCheckInterval *int `json:"realname_check_interval" description:"实名检查间隔(秒):正数按间隔,0 不检查,空继承"`
|
||
CarddataCheckInterval *int `json:"carddata_check_interval" description:"流量检查间隔(秒):正数按间隔,0 不检查,空继承"`
|
||
PackageCheckInterval *int `json:"package_check_interval" description:"套餐检查间隔(秒):正数按间隔,0 不检查,空继承"`
|
||
CardStatusCheckInterval *int `json:"card_status_check_interval" description:"卡状态检查间隔(秒):正数按间隔,0 不检查,空继承"`
|
||
PackageState *string `json:"package_state" description:"套餐状态匹配 (active:有生效套餐, depleted:套餐已用完, pending:只有待生效套餐, none:无套餐),为空不限"`
|
||
AssetStatus *int `json:"asset_status" description:"资产状态匹配 (1:在库, 2:已销售, 3:已换货, 4:已停用),为空不限"`
|
||
PreResetWindow *int `json:"pre_reset_window" description:"重置日前加密窗口长度(秒)"`
|
||
PreResetCarddataInterval *int `json:"pre_reset_carddata_interval" description:"重置日前窗口内的流量检查间隔(秒)"`
|
||
Warnings []string `json:"warnings,omitempty" description:"保存提示(如与其他启用配置优先级相同且匹配条件可能重叠),不影响保存结果"`
|
||
Status int16 `json:"status" description:"状态 (1:启用, 0:禁用)"`
|
||
Description string `json:"description" description:"配置说明"`
|
||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||
UpdatedAt string `json:"updated_at" description:"更新时间"`
|
||
}
|
||
|
||
// UpdatePollingConfigParams 更新轮询配置参数
|
||
type UpdatePollingConfigParams struct {
|
||
IDReq
|
||
UpdatePollingConfigRequest
|
||
}
|
||
|
||
// UpdatePollingConfigStatusParams 更新轮询配置状态参数
|
||
type UpdatePollingConfigStatusParams struct {
|
||
IDReq
|
||
UpdatePollingConfigStatusRequest
|
||
}
|
||
|
||
// PollingConfigPageResult 轮询配置分页结果
|
||
type PollingConfigPageResult struct {
|
||
List []*PollingConfigResponse `json:"items" description:"配置列表"`
|
||
Total int64 `json:"total" description:"总数"`
|
||
Page int `json:"page" description:"当前页"`
|
||
PageSize int `json:"size" description:"每页数量"`
|
||
}
|
||
|
||
// UpdatePollingConfigPrioritiesRequest 整体调整轮询配置优先级请求
|
||
type UpdatePollingConfigPrioritiesRequest struct {
|
||
OrderedIDs []uint `json:"ordered_ids" validate:"required,min=1,max=1000,dive,min=1" required:"true" minItems:"1" maxItems:"1000" description:"按期望生效顺序排列的配置 ID 列表(排在前面的优先级更高);ID 须为正整数且不重复;系统按顺序把优先级重排为 1、2、3…,未列出的配置保持原优先级"`
|
||
}
|
||
|
||
// PollingConfigOverride 匹配预览中的未保存修改;ID 为 0 表示新增草稿,Disabled 为 true 表示假设该配置停用。
|
||
// 字段含义与创建轮询配置相同,均为可选;草稿名称为空时显示"未保存的配置"。
|
||
type PollingConfigOverride struct {
|
||
ID uint `json:"id" description:"要覆盖的配置 ID,0 表示新增一条草稿配置"`
|
||
Disabled bool `json:"disabled" description:"假设该配置停用(不参与匹配),为 true 时其余字段忽略"`
|
||
ConfigName string `json:"config_name" maxLength:"100" description:"草稿配置名称"`
|
||
CardCondition string `json:"card_condition" enum:"not_real_name,activated,suspended" description:"卡状态条件 (not_real_name:未实名, activated:已激活, suspended:已停用),为空不限"`
|
||
CardCategory string `json:"card_category" enum:"normal,industry" description:"卡业务类型 (normal:普通卡, industry:行业卡),为空不限"`
|
||
CarrierID *uint `json:"carrier_id" description:"运营商账户ID,为空不限"`
|
||
Priority int `json:"priority" minimum:"0" description:"优先级(数字越小越优先;与已有配置相同时排在已有配置之后)"`
|
||
RealnameCheckInterval *int `json:"realname_check_interval" minimum:"0" description:"实名检查间隔(秒),正数按间隔、0 不检查、空继承"`
|
||
CarddataCheckInterval *int `json:"carddata_check_interval" minimum:"0" description:"流量检查间隔(秒),正数按间隔、0 不检查、空继承"`
|
||
PackageCheckInterval *int `json:"package_check_interval" minimum:"0" description:"套餐检查间隔(秒),正数按间隔、0 不检查、空继承"`
|
||
CardStatusCheckInterval *int `json:"card_status_check_interval" minimum:"0" description:"卡状态检查间隔(秒),正数按间隔、0 不检查、空继承"`
|
||
PackageState *string `json:"package_state" enum:"active,depleted,pending,none" description:"套餐状态匹配 (active:有生效套餐, depleted:套餐已用完, pending:只有待生效套餐, none:无套餐),为空不限"`
|
||
AssetStatus *int `json:"asset_status" enum:"1,2,3,4" description:"资产状态匹配 (1:在库, 2:已销售, 3:已换货, 4:已停用),为空不限"`
|
||
PreResetWindow *int `json:"pre_reset_window" minimum:"60" description:"重置日前加密窗口长度(秒),与窗口内流量间隔同时配置才生效"`
|
||
PreResetCarddataInterval *int `json:"pre_reset_carddata_interval" minimum:"60" description:"重置日前窗口内的流量检查间隔(秒),与窗口长度同时配置才生效"`
|
||
}
|
||
|
||
// PollingConfigMatchPreviewQuery 按当前配置预览的查询参数
|
||
type PollingConfigMatchPreviewQuery struct {
|
||
ICCID string `json:"-" query:"iccid" validate:"required,max=30" required:"true" maxLength:"30" description:"要预览的卡 ICCID"`
|
||
}
|
||
|
||
// PollingConfigMatchPreviewRequest 带未保存修改的匹配预览请求(请求体)
|
||
type PollingConfigMatchPreviewRequest struct {
|
||
ICCID string `json:"iccid" validate:"required,max=30" required:"true" maxLength:"30" description:"要预览的卡 ICCID"`
|
||
Overrides []PollingConfigOverride `json:"overrides" maxItems:"20" description:"未保存的修改,不写任何数据"`
|
||
}
|
||
|
||
// PollingCardMatchFacts 卡的匹配维度取值
|
||
type PollingCardMatchFacts struct {
|
||
CardID uint `json:"card_id" description:"IoT卡ID"`
|
||
ICCID string `json:"iccid" description:"ICCID"`
|
||
CardCondition string `json:"card_condition" description:"卡状态条件 (not_real_name:未实名, activated:已激活, suspended:已停用)"`
|
||
CardCategory string `json:"card_category" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
|
||
CarrierID uint `json:"carrier_id" description:"运营商账户ID"`
|
||
AssetStatus int `json:"asset_status" description:"资产状态 (1:在库, 2:已销售, 3:已换货, 4:已停用)"`
|
||
PackageState string `json:"package_state" description:"套餐状态 (active:有生效套餐, depleted:套餐已用完, pending:只有待生效套餐, none:无套餐),解析失败为空"`
|
||
PackageStateName string `json:"package_state_name" description:"套餐状态名称"`
|
||
EnablePolling bool `json:"enable_polling" description:"是否开启轮询"`
|
||
}
|
||
|
||
// PollingConfigBrief 匹配到的配置摘要
|
||
type PollingConfigBrief struct {
|
||
ID uint `json:"id" description:"配置ID"`
|
||
ConfigName string `json:"config_name" description:"配置名称"`
|
||
Priority int `json:"priority" description:"优先级"`
|
||
Draft bool `json:"draft" description:"是否为预览中的未保存配置"`
|
||
}
|
||
|
||
// PollingIntervalPreview 某检查类型最终采用的间隔与来源
|
||
type PollingIntervalPreview struct {
|
||
TaskType string `json:"task_type" description:"检查类型 (polling:realname:实名, polling:carddata:流量, polling:package:套餐, polling:card_status:卡状态)"`
|
||
TaskTypeName string `json:"task_type_name" description:"检查类型名称"`
|
||
Mode string `json:"mode" description:"结果 (interval:按间隔检查, disabled:不检查, unmatched:没有任何配置给出取值,不检查)"`
|
||
Interval int `json:"interval" description:"间隔(秒),仅 mode=interval 时有值"`
|
||
ConfigID uint `json:"config_id" description:"给出取值的配置ID"`
|
||
ConfigName string `json:"config_name" description:"给出取值的配置名称"`
|
||
Inherited bool `json:"inherited" description:"是否继承自非首个命中的配置(首个命中配置该项为空)"`
|
||
}
|
||
|
||
// PollingConfigMatchPreviewResponse 匹配预览响应
|
||
type PollingConfigMatchPreviewResponse struct {
|
||
Card PollingCardMatchFacts `json:"card" description:"卡的匹配维度取值"`
|
||
Matched []PollingConfigBrief `json:"matched" description:"命中的配置(按优先级、ID 升序)"`
|
||
Intervals []PollingIntervalPreview `json:"intervals" description:"各检查类型最终结果"`
|
||
}
|
||
|
||
// PollingRecalculateDueRequest 立即重算到期时间请求
|
||
type PollingRecalculateDueRequest struct {
|
||
CarrierID *uint `json:"carrier_id" description:"只处理该运营商账户的卡,为空处理全部开启轮询的卡"`
|
||
}
|
||
|
||
// PollingRecalculateDueTaskIDRequest 重算任务进度查询路径参数
|
||
type PollingRecalculateDueTaskIDRequest struct {
|
||
TaskID string `json:"-" path:"task_id" required:"true" description:"重算任务ID"`
|
||
}
|
||
|
||
// PollingRecalculateDueResponse 重算到期时间任务进度
|
||
type PollingRecalculateDueResponse struct {
|
||
TaskID string `json:"task_id" description:"重算任务ID"`
|
||
Status string `json:"status" description:"状态 (pending:已入队, running:执行中, completed:已完成, failed:失败)"`
|
||
CarrierID string `json:"carrier_id" description:"限定的运营商账户ID,为空表示全部"`
|
||
Total int `json:"total" description:"需处理的卡数"`
|
||
Processed int `json:"processed" description:"已处理的卡数"`
|
||
Advanced int `json:"advanced" description:"被提前的检查项数"`
|
||
Error string `json:"error" description:"失败原因"`
|
||
CreatedAt string `json:"created_at" description:"创建时间"`
|
||
StartedAt string `json:"started_at" description:"开始时间"`
|
||
FinishedAt string `json:"finished_at" description:"结束时间"`
|
||
}
|
||
|
||
// PollingTierStatItem 按命中配置统计的卡数
|
||
type PollingTierStatItem struct {
|
||
ConfigID uint `json:"config_id" description:"首个命中的配置ID,0 表示未匹配任何配置"`
|
||
ConfigName string `json:"config_name" description:"首个命中的配置名称"`
|
||
Cards int `json:"cards" description:"卡数"`
|
||
}
|
||
|
||
// PollingTierStatsResponse 分层统计响应
|
||
type PollingTierStatsResponse struct {
|
||
TotalCards int `json:"total_cards" description:"开启轮询的卡数"`
|
||
ByConfig []PollingTierStatItem `json:"by_config" description:"按首个命中配置统计"`
|
||
ByPackageState map[string]int `json:"by_package_state" description:"按套餐状态统计 (active/depleted/pending/none/unknown)"`
|
||
UnmatchedInStock int `json:"unmatched_in_stock" description:"未匹配任何配置的在库卡数(应告警)"`
|
||
UnmatchedSoldNoPackage int `json:"unmatched_sold_no_package" description:"未匹配任何配置的已销售无套餐卡数(应告警)"`
|
||
ComputedAt string `json:"computed_at" description:"统计时间(结果缓存 5 分钟)"`
|
||
}
|
||
|
||
// PollingPreResetCycleStat 某运营商账户某个重置周期的加密效果
|
||
type PollingPreResetCycleStat struct {
|
||
ResetAt string `json:"reset_at" description:"重置时刻(上海时区)"`
|
||
ActivePackageCards int `json:"active_package_cards" description:"当前有生效套餐的轮询卡数"`
|
||
CheckedInWindow int64 `json:"checked_in_window" description:"窗口内查到过流量的卡数(近似去重计数)"`
|
||
NotCheckedInWindow int64 `json:"not_checked_in_window" description:"有生效套餐但窗口内未查到流量的卡数(近似,最小为 0)"`
|
||
LastOffsetBuckets map[string]int `json:"last_offset_buckets" description:"每张卡窗口内最后一次查询距重置时刻的分布(分钟):le_5/le_15/le_30/le_60/gt_60"`
|
||
}
|
||
|
||
// PollingPreResetCarrierStat 某运营商账户的重置日前加密效果
|
||
type PollingPreResetCarrierStat struct {
|
||
CarrierID uint `json:"carrier_id" description:"运营商账户ID"`
|
||
CarrierName string `json:"carrier_name" description:"运营商账户名称"`
|
||
Previous PollingPreResetCycleStat `json:"previous" description:"最近一次已过去的重置周期"`
|
||
Upcoming PollingPreResetCycleStat `json:"upcoming" description:"即将到来的重置周期(窗口未开始时计数为 0)"`
|
||
}
|
||
|
||
// PollingPreResetStatsResponse 重置日前加密效果统计响应
|
||
type PollingPreResetStatsResponse struct {
|
||
Carriers []PollingPreResetCarrierStat `json:"carriers" description:"有开启轮询卡的运营商账户"`
|
||
}
|
||
|
||
// PollingConfigClearField 是更新轮询配置时可清空为空值的字段名。
|
||
type PollingConfigClearField string
|
||
|
||
// Enum 返回可清空字段的全部取值,供接口文档生成数组元素枚举。
|
||
func (PollingConfigClearField) Enum() []interface{} {
|
||
return []interface{}{"realname_check_interval", "carddata_check_interval", "package_check_interval", "card_status_check_interval",
|
||
"carrier_id", "package_state", "asset_status", "pre_reset_window", "pre_reset_carddata_interval"}
|
||
}
|