Files
junhong_cmp_fiber/internal/model/dto/polling_config_dto.go
邹进 79b7580554
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 9m30s
feat: 下线设备保护期
- 后台设备停复机不再设置 1 小时保护期,也不再因保护期拒绝相反操作;单卡手动停复机去掉保护期检查
- 删除保护期一致性轮询(polling:protect)及其强制停复机方法;调度、初始化、监控、匹配预览不再包含保护期;已入队的旧任务由空处理函数直接确认,下一次发布移除
- 轮询配置接口不再接受与返回 protect_check_interval;并发配置不再返回 protect,查询、更新、重置该类型时拒绝
- 资产详情 device_protect_status 固定返回 none 并标记废弃,兼容老版本客户端
- 删除保护期 Redis key 与时长常量;停机原因 protect_period 保留供历史数据与开放接口映射
- 迁移 000249 只把 protect_check_interval、last_protect_check_at 列注释标记为已废弃,不删列不改数据
2026-10-25 17:19:10 +09:00

245 lines
22 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 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"}
}