Files
junhong_cmp_fiber/internal/model/dto/iot_card_dto.go
break 3b7b856e48
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 8m9s
企业授权增强与资产列表扩展
- 企业卡授权唯一约束:新增 DB 迁移(000154),卡级部分唯一索引防止同一张卡被多个企业同时持有,Service 层新增跨企业冲突检测
- 单卡列表新增 network_status 过滤参数
- 单卡/设备列表新增 asset_status、asset_status_name、generation 响应字段
- 单卡/设备列表新增企业维度过滤(authorized_enterprise_id、is_authorized_to_enterprise)及响应中企业授权信息(批量加载,无 N+1)
- 主钱包流水/退款列表新增 asset_identifier 精确过滤参数
- 企业卡授权/收回接口升级为三模式(list/range/filter),企业设备授权/收回升级为双模式(list/filter)
- 升级 sonic v1.14.2 → v1.15.2 以兼容 Go 1.26

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 16:23:03 +09:00

200 lines
17 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
import "time"
type ListStandaloneIotCardRequest 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 *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
CarrierID *uint `json:"carrier_id" query:"carrier_id" description:"运营商ID"`
ShopID *uint `json:"shop_id" query:"shop_id" description:"分销商ID兼容旧参数单选"`
ShopIDs []uint `json:"shop_ids" query:"shop_ids" validate:"omitempty,dive,min=1" description:"分销商ID列表多选"`
SeriesID *uint `json:"series_id" query:"series_id" description:"套餐系列ID"`
ICCID string `json:"iccid" query:"iccid" validate:"omitempty,max=20" maxLength:"20" description:"ICCID(模糊查询)"`
VirtualNo string `json:"virtual_no" query:"virtual_no" validate:"omitempty,max=100" maxLength:"100" description:"卡虚拟号(模糊查询)"`
MSISDN string `json:"msisdn" query:"msisdn" validate:"omitempty,max=20" maxLength:"20" description:"卡接入号(模糊查询)"`
IsStandalone *bool `json:"is_standalone" query:"is_standalone" description:"是否为独立卡(true:仅返回未绑定设备的卡, false:仅返回已绑定设备的卡, 不传:返回全部)"`
BatchNo string `json:"batch_no" query:"batch_no" validate:"omitempty,max=100" maxLength:"100" description:"批次号"`
PackageID *uint `json:"package_id" query:"package_id" description:"套餐ID"`
IsDistributed *bool `json:"is_distributed" query:"is_distributed" description:"是否已分销 (true:已分销, false:未分销)"`
IsReplaced *bool `json:"is_replaced" query:"is_replaced" description:"是否有换卡记录 (true:有换卡记录, false:无换卡记录)"`
HasActivePackage *bool `json:"has_active_package" query:"has_active_package" description:"是否有生效中的套餐 (true:有生效中套餐, false:无生效中套餐, 不传:不过滤)"`
ICCIDStart string `json:"iccid_start" query:"iccid_start" validate:"omitempty,max=20" maxLength:"20" description:"ICCID起始号"`
ICCIDEnd string `json:"iccid_end" query:"iccid_end" validate:"omitempty,max=20" maxLength:"20" description:"ICCID结束号"`
CarrierName string `json:"carrier_name" query:"carrier_name" validate:"omitempty,max=100" maxLength:"100" description:"运营商名称(模糊查询)"`
Keyword string `json:"keyword" query:"keyword" validate:"omitempty,max=100" maxLength:"100" description:"关键字搜索匹配ICCID或卡虚拟号(模糊查询与iccid/virtual_no独立)"`
NetworkStatus *int `json:"network_status" query:"network_status" validate:"omitempty,min=0,max=1" minimum:"0" maximum:"1" description:"网络状态 (0:停机, 1:开机)"`
AuthorizedEnterpriseID *uint `json:"authorized_enterprise_id" query:"authorized_enterprise_id" description:"按有效授权企业ID过滤只返回当前授权给该企业的卡"`
IsAuthorizedToEnterprise *bool `json:"is_authorized_to_enterprise" query:"is_authorized_to_enterprise" description:"企业授权状态过滤 (true:已授权给某企业, false:未授权任何企业)"`
}
type StandaloneIotCardResponse struct {
ID uint `json:"id" description:"卡ID"`
ICCID string `json:"iccid" description:"ICCID"`
VirtualNo string `json:"virtual_no" description:"卡虚拟号(用于客服查找资产)"`
CardCategory string `json:"card_category" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
CarrierID uint `json:"carrier_id" description:"运营商ID"`
CarrierType string `json:"carrier_type" description:"运营商类型 (CMCC:中国移动, CUCC:中国联通, CTCC:中国电信, CBN:中国广电)"`
CarrierName string `json:"carrier_name" description:"运营商名称"`
IMSI string `json:"imsi" description:"IMSI"`
MSISDN string `json:"msisdn" description:"卡接入号"`
BatchNo string `json:"batch_no" description:"批次号"`
Supplier string `json:"supplier" description:"供应商"`
Status int `json:"status" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
StatusName string `json:"status_name" description:"状态名称(中文)"`
ShopID *uint `json:"shop_id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
ActivatedAt *time.Time `json:"activated_at" description:"激活时间"`
ActivationStatus int `json:"activation_status" description:"激活状态 (0:未激活, 1:已激活)"`
ActivationStatusName string `json:"activation_status_name" description:"激活状态名称(中文)"`
RealNameStatus int `json:"real_name_status" description:"实名状态 (0:未实名, 1:已实名)"`
RealNameStatusName string `json:"real_name_status_name" description:"实名状态名称(中文)"`
NetworkStatus int `json:"network_status" description:"网络状态 (0:停机, 1:开机)"`
NetworkStatusName string `json:"network_status_name" description:"网络状态名称(中文)"`
GatewayExtend string `json:"gateway_extend" description:"Gateway 卡状态扩展字段,原样返回上游 extend用于展示运营商侧实际停机原因"`
GatewayCardIMEI string `json:"gateway_card_imei" description:"插拔卡业务 IMEI由 Gateway 卡状态接口同步,非设备自身 IMEI无业务含义仅供查看"`
DataUsageMB int64 `json:"data_usage_mb" description:"累计流量使用(MB)"`
CurrentMonthUsageMB float64 `json:"current_month_usage_mb" description:"系统自然月累计流量(MB不等于运营商周期口径)"`
LastGatewayReadingMB float64 `json:"last_gateway_reading_mb" description:"运营商当前周期累计流量读数(MB展示运营商口径时使用)"`
CurrentMonthStartDate *time.Time `json:"current_month_start_date" description:"本月开始日期"`
LastMonthTotalMB float64 `json:"last_month_total_mb" description:"上月流量总量(MB)"`
LastDataCheckAt *time.Time `json:"last_data_check_at" description:"最后流量检查时间"`
LastRealNameCheckAt *time.Time `json:"last_real_name_check_at" description:"最后实名检查时间"`
EnablePolling bool `json:"enable_polling" description:"是否参与轮询"`
SeriesID *uint `json:"series_id" description:"套餐系列ID"`
SeriesName string `json:"series_name" description:"套餐系列名称"`
DeviceVirtualNo string `json:"device_virtual_no" description:"绑定设备的虚拟号(未绑定时为空字符串)"`
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
// asset_status=3 表示该资产已换货且尚未执行"旧资产转新",不再流通
// generation>1 表示该资产历史上曾执行过换货后转新,目前仍在使用
AssetStatus int `json:"asset_status" description:"业务状态 (1:在库, 2:已销售, 3:已换货, 4:已停用)"`
AssetStatusName string `json:"asset_status_name" description:"业务状态名称(中文)"`
Generation int `json:"generation" description:"资产世代编号初始值1每次换货转新后+1"`
AuthorizedEnterpriseID *uint `json:"authorized_enterprise_id" description:"当前有效授权的企业ID未授权时为 null"`
AuthorizedEnterpriseName string `json:"authorized_enterprise_name" description:"当前有效授权的企业名称,未授权时为空字符串"`
CreatedAt time.Time `json:"created_at" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
}
type ListStandaloneIotCardResponse struct {
List []*StandaloneIotCardResponse `json:"items" description:"单卡列表"`
Total int64 `json:"total" description:"总数"`
Page int `json:"page" description:"当前页码"`
PageSize int `json:"size" description:"每页数量"`
}
type ImportIotCardRequest struct {
CarrierID uint `json:"carrier_id" validate:"required,min=1" required:"true" minimum:"1" description:"运营商ID"`
BatchNo string `json:"batch_no" validate:"omitempty,max=100" maxLength:"100" description:"批次号"`
FileKey string `json:"file_key" validate:"required,min=1,max=500" required:"true" minLength:"1" maxLength:"500" description:"对象存储文件路径(通过 /storage/upload-url 获取)"`
CardCategory string `json:"card_category" validate:"omitempty,oneof=normal industry" description:"卡业务类型 (normal:普通卡, industry:行业卡),默认 normal"`
RealnamePolicy string `json:"realname_policy" validate:"omitempty,oneof=none before_order after_order" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名),默认 after_order"`
}
type ImportIotCardResponse struct {
TaskID uint `json:"task_id" description:"导入任务ID"`
TaskNo string `json:"task_no" description:"任务编号"`
Message string `json:"message" description:"提示信息"`
}
type ListImportTaskRequest 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 *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:失败)"`
CarrierID *uint `json:"carrier_id" query:"carrier_id" description:"运营商ID"`
BatchNo string `json:"batch_no" query:"batch_no" validate:"omitempty,max=100" maxLength:"100" description:"批次号(模糊查询)"`
StartTime *time.Time `json:"start_time" query:"start_time" description:"创建时间起始"`
EndTime *time.Time `json:"end_time" query:"end_time" description:"创建时间结束"`
}
type ImportTaskResponse struct {
ID uint `json:"id" description:"任务ID"`
TaskNo string `json:"task_no" description:"任务编号"`
Status int `json:"status" description:"任务状态 (1:待处理, 2:处理中, 3:已完成, 4:失败)"`
StatusText string `json:"status_text" description:"任务状态文本"`
CarrierID uint `json:"carrier_id" description:"运营商ID"`
CarrierType string `json:"carrier_type,omitempty" description:"运营商类型 (CMCC:中国移动, CUCC:中国联通, CTCC:中国电信, CBN:中国广电)"`
CarrierName string `json:"carrier_name,omitempty" description:"运营商名称"`
BatchNo string `json:"batch_no,omitempty" description:"批次号"`
CardCategory string `json:"card_category" description:"卡业务类型 (normal:普通卡, industry:行业卡)"`
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
FileName string `json:"file_name,omitempty" description:"文件名"`
TotalCount int `json:"total_count" description:"总数"`
SuccessCount int `json:"success_count" description:"成功数"`
SkipCount int `json:"skip_count" description:"跳过数"`
FailCount int `json:"fail_count" description:"失败数"`
StartedAt *time.Time `json:"started_at,omitempty" description:"开始处理时间"`
CompletedAt *time.Time `json:"completed_at,omitempty" description:"完成时间"`
ErrorMessage string `json:"error_message,omitempty" description:"错误信息"`
CreatedAt time.Time `json:"created_at" description:"创建时间"`
}
type ListImportTaskResponse struct {
List []*ImportTaskResponse `json:"items" description:"任务列表"`
Total int64 `json:"total" description:"总数"`
Page int `json:"page" description:"当前页码"`
PageSize int `json:"size" description:"每页数量"`
}
type ImportResultItemDTO struct {
Line int `json:"line" description:"行号"`
ICCID string `json:"iccid" description:"ICCID"`
MSISDN string `json:"msisdn,omitempty" description:"接入号"`
Reason string `json:"reason" description:"原因"`
}
type ImportTaskDetailResponse struct {
ImportTaskResponse
SkippedItems []*ImportResultItemDTO `json:"skipped_items" description:"跳过记录详情"`
FailedItems []*ImportResultItemDTO `json:"failed_items" description:"失败记录详情"`
}
type GetImportTaskRequest struct {
ID uint `path:"id" description:"任务ID" required:"true"`
}
type GetIotCardByICCIDRequest struct {
ICCID string `path:"iccid" description:"ICCID" required:"true"`
}
type IotCardDetailResponse struct {
StandaloneIotCardResponse
}
// BatchSetCardSeriesBindngRequest 批量设置卡的套餐系列绑定请求
type BatchSetCardSeriesBindngRequest struct {
SelectionType string `json:"selection_type" validate:"omitempty,oneof=list range filter" enum:"list,range,filter" description:"选卡方式 (list:ICCID列表, range:号段范围, filter:筛选条件不传时兼容旧版ICCID列表)"`
ICCIDs []string `json:"iccids" validate:"omitempty,max=1000,dive,required,max=20" maxItems:"1000" description:"ICCID列表selection_type=list时使用最多1000个"`
ICCIDStart string `json:"iccid_start" validate:"omitempty,max=20" maxLength:"20" description:"起始ICCIDselection_type=range时使用"`
ICCIDEnd string `json:"iccid_end" validate:"omitempty,max=20" maxLength:"20" description:"结束ICCIDselection_type=range时使用"`
Status *int `json:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)selection_type=filter时可选"`
CarrierID *uint `json:"carrier_id" description:"运营商IDselection_type=filter时可选"`
ShopID *uint `json:"shop_id" description:"分销商IDselection_type=filter时可选兼容旧参数单选"`
ShopIDs []uint `json:"shop_ids" validate:"omitempty,dive,min=1" description:"分销商ID列表selection_type=filter时可选多选"`
FilterSeriesID *uint `json:"filter_series_id" description:"当前绑定套餐系列IDselection_type=filter时可选目标套餐系列仍使用series_id"`
ICCID string `json:"iccid" validate:"omitempty,max=20" maxLength:"20" description:"ICCID模糊查询selection_type=filter时可选"`
MSISDN string `json:"msisdn" validate:"omitempty,max=20" maxLength:"20" description:"卡接入号模糊查询selection_type=filter时可选"`
IsStandalone *bool `json:"is_standalone" description:"是否为独立卡selection_type=filter时可选"`
BatchNo string `json:"batch_no" validate:"omitempty,max=100" maxLength:"100" description:"批次号selection_type=filter时可选"`
PackageID *uint `json:"package_id" description:"套餐IDselection_type=filter时可选"`
IsDistributed *bool `json:"is_distributed" description:"是否已分销selection_type=filter时可选"`
IsReplaced *bool `json:"is_replaced" description:"是否有换卡记录selection_type=filter时可选"`
CarrierName string `json:"carrier_name" validate:"omitempty,max=100" maxLength:"100" description:"运营商名称模糊查询selection_type=filter时可选"`
SeriesID uint `json:"series_id" validate:"required,min=0" required:"true" minimum:"0" description:"目标套餐系列ID0表示清除关联"`
}
// CardSeriesBindngFailedItem 卡系列绑定失败项
type CardSeriesBindngFailedItem struct {
ICCID string `json:"iccid" description:"ICCID"`
Reason string `json:"reason" description:"失败原因"`
}
// BatchSetCardSeriesBindngResponse 批量设置卡的套餐系列绑定响应
type BatchSetCardSeriesBindngResponse struct {
SuccessCount int `json:"success_count" description:"成功数量"`
FailCount int `json:"fail_count" description:"失败数量"`
FailedItems []CardSeriesBindngFailedItem `json:"failed_items" description:"失败详情列表"`
}