Files
junhong_cmp_fiber/internal/model/dto/device_dto.go
huang 80c6f6c756
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m21s
feat: 资产标识符标准化、资产历史订单查询及导入虚拟号强制验证
主要变更:
- 新增 AssetIdentifier 模型及 Store,统一管理资产标识符(ICCID/IMEI/SN 等)
- 新增迁移:asset_identifier 表、order 表新增 asset_identifier 字段、iot_card.virtual_no NOT NULL 约束
- 资产 Handler/Service/Route 全面重构,支持标识符路由查询与解析
- 新增资产历史订单查询接口,支持跨设备/卡/钱包维度的订单聚合
- 设备与物联卡导入任务强制校验虚拟号,缺失时直接拒绝
- Excel 工具函数优化,前端导入指引文档同步更新
- 归档三个 OpenSpec 提案:asset-identifier-standardization、asset-historical-orders、import-mandatory-virtual-no
- 更新 OpenAPI 文档及相关 DTO

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-07 17:39:36 +08:00

199 lines
11 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 ListDeviceRequest 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:"每页数量"`
VirtualNo string `json:"virtual_no" query:"virtual_no" validate:"omitempty,max=100" maxLength:"100" description:"虚拟号(模糊查询)"`
DeviceName string `json:"device_name" query:"device_name" validate:"omitempty,max=255" maxLength:"255" description:"设备名称(模糊查询)"`
Status *int `json:"status" query:"status" validate:"omitempty,min=1,max=4" minimum:"1" maximum:"4" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
ShopID *uint `json:"shop_id" query:"shop_id" description:"店铺ID (NULL表示平台库存)"`
SeriesID *uint `json:"series_id" query:"series_id" description:"套餐系列ID"`
BatchNo string `json:"batch_no" query:"batch_no" validate:"omitempty,max=100" maxLength:"100" description:"批次号"`
DeviceType string `json:"device_type" query:"device_type" validate:"omitempty,max=50" maxLength:"50" description:"设备类型"`
Manufacturer string `json:"manufacturer" query:"manufacturer" validate:"omitempty,max=255" maxLength:"255" description:"制造商(模糊查询)"`
CreatedAtStart *time.Time `json:"created_at_start" query:"created_at_start" description:"创建时间起始"`
CreatedAtEnd *time.Time `json:"created_at_end" query:"created_at_end" description:"创建时间结束"`
}
type DeviceResponse struct {
ID uint `json:"id" description:"设备ID"`
VirtualNo string `json:"virtual_no" description:"设备虚拟号/别名"`
IMEI string `json:"imei" description:"设备IMEI"`
SN string `json:"sn" description:"设备序列号"`
DeviceName string `json:"device_name" description:"设备名称"`
DeviceModel string `json:"device_model" description:"设备型号"`
DeviceType string `json:"device_type" description:"设备类型"`
MaxSimSlots int `json:"max_sim_slots" description:"最大插槽数"`
Manufacturer string `json:"manufacturer" description:"制造商"`
BatchNo string `json:"batch_no" description:"批次号"`
ShopID *uint `json:"shop_id" description:"店铺ID"`
ShopName string `json:"shop_name" description:"店铺名称"`
Status int `json:"status" description:"状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
StatusName string `json:"status_name" description:"状态名称"`
BoundCardCount int `json:"bound_card_count" description:"已绑定卡数量"`
SeriesID *uint `json:"series_id" description:"套餐系列ID"`
SeriesName string `json:"series_name" description:"套餐系列名称"`
FirstCommissionPaid bool `json:"first_commission_paid" description:"一次性佣金是否已发放"`
AccumulatedRecharge int64 `json:"accumulated_recharge" description:"累计充值金额(分)"`
ActivatedAt *time.Time `json:"activated_at" description:"激活时间"`
CreatedAt time.Time `json:"created_at" description:"创建时间"`
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
// 设备实时同步字段(由 sync-info 接口写入)
OnlineStatus int `json:"online_status" description:"在线状态0未知 1在线 2离线"`
LastOnlineTime *time.Time `json:"last_online_time" description:"最后在线时间"`
SoftwareVersion string `json:"software_version" description:"固件版本号"`
SwitchMode string `json:"switch_mode" description:"切卡模式0=自动1=手动"`
LastGatewaySyncAt *time.Time `json:"last_gateway_sync_at" description:"最后 sync-info 同步时间"`
}
type ListDeviceResponse struct {
List []*DeviceResponse `json:"items" description:"设备列表"`
Total int64 `json:"total" description:"总数"`
Page int `json:"page" description:"当前页码"`
PageSize int `json:"size" description:"每页数量"`
}
type GetDeviceRequest struct {
ID uint `path:"id" description:"设备ID" required:"true"`
}
// GetDeviceByIdentifierRequest 通过标识符查询设备请求
type GetDeviceByIdentifierRequest struct {
Identifier string `path:"identifier" description:"设备标识符(支持虚拟号/IMEI/SN)" required:"true"`
}
type DeleteDeviceRequest struct {
VirtualNo string `path:"virtual_no" description:"设备虚拟号" required:"true"`
}
type ListDeviceCardsRequest struct {
VirtualNo string `path:"virtual_no" description:"设备虚拟号" required:"true"`
}
type DeviceCardBindingResponse struct {
ID uint `json:"id" description:"绑定记录ID"`
SlotPosition int `json:"slot_position" description:"插槽位置 (1-4)"`
IotCardID uint `json:"iot_card_id" description:"IoT卡ID"`
ICCID string `json:"iccid" description:"ICCID"`
MSISDN string `json:"msisdn" description:"接入号"`
CarrierName string `json:"carrier_name" description:"运营商名称"`
Status int `json:"status" description:"卡状态 (1:在库, 2:已分销, 3:已激活, 4:已停用)"`
BindTime *time.Time `json:"bind_time" description:"绑定时间"`
IsCurrent bool `json:"is_current" description:"是否为当前使用的卡"`
}
type ListDeviceCardsResponse struct {
Bindings []*DeviceCardBindingResponse `json:"bindings" description:"绑定列表"`
}
type BindCardToDeviceRequest struct {
VirtualNo string `path:"virtual_no" description:"设备虚拟号" required:"true"`
ID uint `json:"-"`
IotCardID uint `json:"iot_card_id" validate:"required,min=1" required:"true" minimum:"1" description:"IoT卡ID"`
SlotPosition int `json:"slot_position" validate:"required,min=1,max=4" required:"true" minimum:"1" maximum:"4" description:"插槽位置 (1-4)"`
}
type BindCardToDeviceResponse struct {
BindingID uint `json:"binding_id" description:"绑定记录ID"`
Message string `json:"message" description:"提示信息"`
}
type UnbindCardFromDeviceRequest struct {
VirtualNo string `path:"virtual_no" description:"设备虚拟号" required:"true"`
ICCID string `path:"iccid" description:"IoT卡ICCID" required:"true"`
}
type UnbindCardFromDeviceResponse struct {
Message string `json:"message" description:"提示信息"`
}
type AllocateDevicesRequest struct {
TargetShopID uint `json:"target_shop_id" validate:"required,min=1" required:"true" minimum:"1" description:"目标店铺ID"`
DeviceIDs []uint `json:"device_ids" validate:"required,min=1,max=100" required:"true" minItems:"1" maxItems:"100" description:"设备ID列表"`
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注"`
}
type AllocationDeviceFailedItem struct {
DeviceID uint `json:"device_id" description:"设备ID"`
VirtualNo string `json:"virtual_no" description:"设备虚拟号"`
Reason string `json:"reason" description:"失败原因"`
}
type AllocateDevicesResponse struct {
SuccessCount int `json:"success_count" description:"成功数量"`
FailCount int `json:"fail_count" description:"失败数量"`
FailedItems []AllocationDeviceFailedItem `json:"failed_items" description:"失败详情列表"`
}
type RecallDevicesRequest struct {
DeviceIDs []uint `json:"device_ids" validate:"required,min=1,max=100" required:"true" minItems:"1" maxItems:"100" description:"设备ID列表"`
Remark string `json:"remark" validate:"omitempty,max=500" maxLength:"500" description:"备注"`
}
type RecallDevicesResponse struct {
SuccessCount int `json:"success_count" description:"成功数量"`
FailCount int `json:"fail_count" description:"失败数量"`
FailedItems []AllocationDeviceFailedItem `json:"failed_items" description:"失败详情列表"`
}
// BatchSetDeviceSeriesBindngRequest 批量设置设备的套餐系列绑定请求
type BatchSetDeviceSeriesBindngRequest struct {
DeviceIDs []uint `json:"device_ids" validate:"required,min=1,max=500,dive,required" required:"true" minItems:"1" maxItems:"500" description:"设备ID列表"`
SeriesID uint `json:"series_id" validate:"required,min=0" required:"true" minimum:"0" description:"套餐系列ID0表示清除关联"`
}
// DeviceSeriesBindngFailedItem 设备系列绑定失败项
type DeviceSeriesBindngFailedItem struct {
DeviceID uint `json:"device_id" description:"设备ID"`
VirtualNo string `json:"virtual_no" description:"设备虚拟号"`
Reason string `json:"reason" description:"失败原因"`
}
// BatchSetDeviceSeriesBindngResponse 批量设置设备的套餐系列绑定响应
type BatchSetDeviceSeriesBindngResponse struct {
SuccessCount int `json:"success_count" description:"成功数量"`
FailCount int `json:"fail_count" description:"失败数量"`
FailedItems []DeviceSeriesBindngFailedItem `json:"failed_items" description:"失败详情列表"`
}
// SetSpeedLimitRequest 设置设备限速请求
type SetSpeedLimitRequest struct {
Identifier string `path:"identifier" description:"设备标识符(支持虚拟号/IMEI/SN)" required:"true"`
SpeedLimit int `json:"speed_limit" validate:"required,min=1" required:"true" minimum:"1" description:"限速值KB/s"`
}
// SetWiFiRequest 设置设备 WiFi 请求
type SetWiFiRequest struct {
Identifier string `path:"identifier" description:"设备标识符(支持虚拟号/IMEI/SN)" required:"true"`
CardNo string `json:"card_no" validate:"required" required:"true" description:"流量卡号ICCID"`
SSID string `json:"ssid" validate:"required,min=1,max=32" required:"true" minLength:"1" maxLength:"32" description:"WiFi 名称"`
Password string `json:"password,omitempty" description:"WiFi 密码"`
Enabled bool `json:"enabled" description:"启用状态"`
}
// SwitchCardRequest 切卡请求
type SwitchCardRequest struct {
Identifier string `path:"identifier" description:"设备标识符(支持虚拟号/IMEI/SN)" required:"true"`
TargetICCID string `json:"target_iccid" validate:"required" required:"true" description:"目标卡 ICCID"`
}
type EmptyResponse struct {
Message string `json:"message,omitempty" description:"提示信息"`
}
// DeviceSuspendResponse 设备停机响应
type DeviceSuspendResponse struct {
SuccessCount int `json:"success_count" description:"成功停机卡数"`
FailCount int `json:"fail_count" description:"失败卡数"`
SkipCount int `json:"skip_count" description:"跳过卡数(未实名或已停机)"`
FailedItems []DeviceSuspendFailItem `json:"failed_items,omitempty" description:"失败详情"`
}
// DeviceSuspendFailItem 设备停机失败项
type DeviceSuspendFailItem struct {
ICCID string `json:"iccid" description:"卡ICCID"`
Reason string `json:"reason" description:"失败原因"`
}