c端当前套餐开始时间过期时间,以及excel导入字段
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m55s
This commit is contained in:
@@ -152,48 +152,50 @@ func (h *ClientAssetHandler) GetAssetInfo(c *fiber.Ctx) error {
|
||||
phone, _ := middleware.GetCustomerPhone(c)
|
||||
|
||||
resp := &dto.AssetInfoResponse{
|
||||
BoundPhone: phone,
|
||||
AssetType: resolved.Asset.AssetType,
|
||||
AssetID: resolved.Asset.AssetID,
|
||||
Identifier: resolved.Identifier,
|
||||
VirtualNo: resolved.Asset.VirtualNo,
|
||||
Status: resolved.Asset.Status,
|
||||
StatusName: resolved.Asset.StatusName,
|
||||
RealNameStatus: resolved.Asset.RealNameStatus,
|
||||
RealNameStatusName: constants.GetRealNameStatusName(resolved.Asset.RealNameStatus),
|
||||
CarrierName: resolved.Asset.CarrierName,
|
||||
Generation: strconv.Itoa(resolved.Generation),
|
||||
WalletBalance: resolved.WalletBalance,
|
||||
ActivatedAt: resolved.Asset.ActivatedAt,
|
||||
CurrentPackage: resolved.Asset.CurrentPackage,
|
||||
CurrentPackageUsageID: resolved.Asset.CurrentPackageUsageID,
|
||||
RealTotalMB: resolved.Asset.RealTotalMB,
|
||||
RealUsedMB: resolved.Asset.RealUsedMB,
|
||||
VirtualTotalMB: resolved.Asset.VirtualTotalMB,
|
||||
VirtualUsedMB: resolved.Asset.VirtualUsedMB,
|
||||
ReductionPct: resolved.Asset.ReductionPct,
|
||||
DeviceName: resolved.Asset.DeviceName,
|
||||
IMEI: resolved.Asset.IMEI,
|
||||
SN: resolved.Asset.SN,
|
||||
DeviceModel: resolved.Asset.DeviceModel,
|
||||
DeviceType: resolved.Asset.DeviceType,
|
||||
Manufacturer: resolved.Asset.Manufacturer,
|
||||
MaxSimSlots: resolved.Asset.MaxSimSlots,
|
||||
BoundCardCount: resolved.Asset.BoundCardCount,
|
||||
Cards: resolved.Asset.Cards,
|
||||
DeviceProtectStatus: resolved.Asset.DeviceProtectStatus,
|
||||
ICCID: resolved.Asset.ICCID,
|
||||
MSISDN: resolved.Asset.MSISDN,
|
||||
CarrierID: resolved.Asset.CarrierID,
|
||||
CarrierType: resolved.Asset.CarrierType,
|
||||
NetworkStatus: resolved.Asset.NetworkStatus,
|
||||
NetworkStatusName: constants.GetNetworkStatusName(resolved.Asset.NetworkStatus),
|
||||
ActivationStatus: resolved.Asset.ActivationStatus,
|
||||
ActivationStatusName: constants.GetActivationStatusName(resolved.Asset.ActivationStatus),
|
||||
CardCategory: resolved.Asset.CardCategory,
|
||||
BoundDeviceID: resolved.Asset.BoundDeviceID,
|
||||
BoundDeviceNo: resolved.Asset.BoundDeviceNo,
|
||||
BoundDeviceName: resolved.Asset.BoundDeviceName,
|
||||
BoundPhone: phone,
|
||||
AssetType: resolved.Asset.AssetType,
|
||||
AssetID: resolved.Asset.AssetID,
|
||||
Identifier: resolved.Identifier,
|
||||
VirtualNo: resolved.Asset.VirtualNo,
|
||||
Status: resolved.Asset.Status,
|
||||
StatusName: resolved.Asset.StatusName,
|
||||
RealNameStatus: resolved.Asset.RealNameStatus,
|
||||
RealNameStatusName: constants.GetRealNameStatusName(resolved.Asset.RealNameStatus),
|
||||
CarrierName: resolved.Asset.CarrierName,
|
||||
Generation: strconv.Itoa(resolved.Generation),
|
||||
WalletBalance: resolved.WalletBalance,
|
||||
ActivatedAt: resolved.Asset.ActivatedAt,
|
||||
CurrentPackage: resolved.Asset.CurrentPackage,
|
||||
CurrentPackageUsageID: resolved.Asset.CurrentPackageUsageID,
|
||||
CurrentPackageActivatedAt: resolved.Asset.CurrentPackageActivatedAt,
|
||||
CurrentPackageExpiresAt: resolved.Asset.CurrentPackageExpiresAt,
|
||||
RealTotalMB: resolved.Asset.RealTotalMB,
|
||||
RealUsedMB: resolved.Asset.RealUsedMB,
|
||||
VirtualTotalMB: resolved.Asset.VirtualTotalMB,
|
||||
VirtualUsedMB: resolved.Asset.VirtualUsedMB,
|
||||
ReductionPct: resolved.Asset.ReductionPct,
|
||||
DeviceName: resolved.Asset.DeviceName,
|
||||
IMEI: resolved.Asset.IMEI,
|
||||
SN: resolved.Asset.SN,
|
||||
DeviceModel: resolved.Asset.DeviceModel,
|
||||
DeviceType: resolved.Asset.DeviceType,
|
||||
Manufacturer: resolved.Asset.Manufacturer,
|
||||
MaxSimSlots: resolved.Asset.MaxSimSlots,
|
||||
BoundCardCount: resolved.Asset.BoundCardCount,
|
||||
Cards: resolved.Asset.Cards,
|
||||
DeviceProtectStatus: resolved.Asset.DeviceProtectStatus,
|
||||
ICCID: resolved.Asset.ICCID,
|
||||
MSISDN: resolved.Asset.MSISDN,
|
||||
CarrierID: resolved.Asset.CarrierID,
|
||||
CarrierType: resolved.Asset.CarrierType,
|
||||
NetworkStatus: resolved.Asset.NetworkStatus,
|
||||
NetworkStatusName: constants.GetNetworkStatusName(resolved.Asset.NetworkStatus),
|
||||
ActivationStatus: resolved.Asset.ActivationStatus,
|
||||
ActivationStatusName: constants.GetActivationStatusName(resolved.Asset.ActivationStatus),
|
||||
CardCategory: resolved.Asset.CardCategory,
|
||||
BoundDeviceID: resolved.Asset.BoundDeviceID,
|
||||
BoundDeviceNo: resolved.Asset.BoundDeviceNo,
|
||||
BoundDeviceName: resolved.Asset.BoundDeviceName,
|
||||
}
|
||||
|
||||
// 调用服务层获取设备实时 Gateway 数据(per D-11)
|
||||
|
||||
@@ -19,17 +19,19 @@ type AssetResolveResponse struct {
|
||||
CreatedAt time.Time `json:"created_at" description:"创建时间"`
|
||||
UpdatedAt time.Time `json:"updated_at" description:"更新时间"`
|
||||
// 状态聚合字段
|
||||
RealNameStatus int `json:"real_name_status" description:"实名状态:0未实名 1已实名"`
|
||||
RealNameAt *time.Time `json:"real_name_at" description:"最近一次完成实名的时间,未实名时为 null"`
|
||||
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
|
||||
CurrentPackage string `json:"current_package" description:"当前套餐名称(无套餐时为空)"`
|
||||
CurrentPackageUsageID *uint `json:"current_package_usage_id" description:"当前主套餐的套餐使用记录ID,无主套餐时为 null"`
|
||||
RealTotalMB int64 `json:"real_total_mb" description:"当前主套餐真实总量(MB)"`
|
||||
RealUsedMB int64 `json:"real_used_mb" description:"当前主套餐真实已用量(MB)"`
|
||||
VirtualTotalMB int64 `json:"virtual_total_mb" description:"当前主套餐业务停机阈值(MB)"`
|
||||
VirtualUsedMB float64 `json:"virtual_used_mb" description:"当前主套餐展示已用量(MB)"`
|
||||
ReductionPct float64 `json:"reduction_pct" description:"展示增幅比例,公式为(real_total_mb / virtual_total_mb) - 1"`
|
||||
DeviceProtectStatus string `json:"device_protect_status,omitempty" description:"设备保护期状态:none/stop/start(仅asset_type=device时有效)"`
|
||||
RealNameStatus int `json:"real_name_status" description:"实名状态:0未实名 1已实名"`
|
||||
RealNameAt *time.Time `json:"real_name_at" description:"最近一次完成实名的时间,未实名时为 null"`
|
||||
RealnamePolicy string `json:"realname_policy" description:"实名认证策略 (none:无需实名, before_order:先实名后充值/购买, after_order:先充值/购买后实名)"`
|
||||
CurrentPackage string `json:"current_package" description:"当前套餐名称(无套餐时为空)"`
|
||||
CurrentPackageUsageID *uint `json:"current_package_usage_id" description:"当前主套餐的套餐使用记录ID,无主套餐时为 null"`
|
||||
CurrentPackageActivatedAt *time.Time `json:"current_package_activated_at,omitempty" description:"当前主套餐开始时间"`
|
||||
CurrentPackageExpiresAt *time.Time `json:"current_package_expires_at,omitempty" description:"当前主套餐过期时间"`
|
||||
RealTotalMB int64 `json:"real_total_mb" description:"当前主套餐真实总量(MB)"`
|
||||
RealUsedMB int64 `json:"real_used_mb" description:"当前主套餐真实已用量(MB)"`
|
||||
VirtualTotalMB int64 `json:"virtual_total_mb" description:"当前主套餐业务停机阈值(MB)"`
|
||||
VirtualUsedMB float64 `json:"virtual_used_mb" description:"当前主套餐展示已用量(MB)"`
|
||||
ReductionPct float64 `json:"reduction_pct" description:"展示增幅比例,公式为(real_total_mb / virtual_total_mb) - 1"`
|
||||
DeviceProtectStatus string `json:"device_protect_status,omitempty" description:"设备保护期状态:none/stop/start(仅asset_type=device时有效)"`
|
||||
// 绑定关系字段
|
||||
ICCID string `json:"iccid,omitempty" description:"卡ICCID(asset_type=card时有效)"`
|
||||
BoundDeviceID *uint `json:"bound_device_id,omitempty" description:"绑定的设备ID(asset_type=card时有效)"`
|
||||
|
||||
@@ -33,13 +33,15 @@ type AssetInfoResponse struct {
|
||||
ActivatedAt *time.Time `json:"activated_at,omitempty" description:"激活时间"`
|
||||
|
||||
// === 套餐信息(通用) ===
|
||||
CurrentPackage string `json:"current_package" description:"当前套餐名称(无套餐时为空)"`
|
||||
CurrentPackageUsageID *uint `json:"current_package_usage_id" description:"当前主套餐的套餐使用记录ID,无主套餐时为 null"`
|
||||
RealTotalMB int64 `json:"real_total_mb" description:"当前主套餐真实总量(MB)"`
|
||||
RealUsedMB int64 `json:"real_used_mb" description:"当前主套餐真实已用量(MB)"`
|
||||
VirtualTotalMB int64 `json:"virtual_total_mb" description:"当前主套餐业务停机阈值(MB)"`
|
||||
VirtualUsedMB float64 `json:"virtual_used_mb" description:"当前主套餐展示已用量(MB)"`
|
||||
ReductionPct float64 `json:"reduction_pct" description:"展示增幅比例,公式为(real_total_mb / virtual_total_mb) - 1"`
|
||||
CurrentPackage string `json:"current_package" description:"当前套餐名称(无套餐时为空)"`
|
||||
CurrentPackageUsageID *uint `json:"current_package_usage_id" description:"当前主套餐的套餐使用记录ID,无主套餐时为 null"`
|
||||
CurrentPackageActivatedAt *time.Time `json:"current_package_activated_at,omitempty" description:"当前主套餐开始时间"`
|
||||
CurrentPackageExpiresAt *time.Time `json:"current_package_expires_at,omitempty" description:"当前主套餐过期时间"`
|
||||
RealTotalMB int64 `json:"real_total_mb" description:"当前主套餐真实总量(MB)"`
|
||||
RealUsedMB int64 `json:"real_used_mb" description:"当前主套餐真实已用量(MB)"`
|
||||
VirtualTotalMB int64 `json:"virtual_total_mb" description:"当前主套餐业务停机阈值(MB)"`
|
||||
VirtualUsedMB float64 `json:"virtual_used_mb" description:"当前主套餐展示已用量(MB)"`
|
||||
ReductionPct float64 `json:"reduction_pct" description:"展示增幅比例,公式为(real_total_mb / virtual_total_mb) - 1"`
|
||||
|
||||
// === 设备专属字段(asset_type=device 时有效) ===
|
||||
DeviceName string `json:"device_name,omitempty" description:"设备名称"`
|
||||
|
||||
@@ -89,6 +89,7 @@ func registerDeviceRoutes(router fiber.Router, handler *admin.DeviceHandler, imp
|
||||
- 文件格式:仅支持 .xlsx (Excel 2007+)
|
||||
- 必须包含列(首行为表头):
|
||||
- ` + "`virtual_no`" + `: 设备虚拟号(**必填**,全局唯一;**为空的行记为失败,不再静默跳过**)
|
||||
- ` + "`sn`" + `: 设备 SN
|
||||
- ` + "`device_name`" + `: 设备名称
|
||||
- ` + "`device_model`" + `: 设备型号
|
||||
- ` + "`device_type`" + `: 设备类型
|
||||
@@ -97,6 +98,7 @@ func registerDeviceRoutes(router fiber.Router, handler *admin.DeviceHandler, imp
|
||||
- ` + "`max_sim_slots`" + `: 最大插槽数(默认4,范围1-4)
|
||||
- ` + "`iccid_1`" + ` ~ ` + "`iccid_4`" + `: 固定槽位的卡 ICCID(` + "`iccid_1`" + `=槽1,` + "`iccid_2`" + `=槽2,` + "`iccid_3`" + `=槽3,` + "`iccid_4`" + `=槽4;卡必须已存在且未绑定)
|
||||
- 槽位规则:中间留空不会触发前移补位;如果 ` + "`max_sim_slots=2`" + `,则 ` + "`iccid_3`" + `、` + "`iccid_4`" + ` 必须留空,否则该行失败
|
||||
- 固定列顺序:` + "`virtual_no`" + `、` + "`sn`" + `、` + "`device_name`" + `、` + "`device_model`" + `、` + "`device_type`" + `、` + "`imei`" + `、` + "`manufacturer`" + `、` + "`max_sim_slots`" + `、` + "`iccid_1`" + `、` + "`iccid_2`" + `、` + "`iccid_3`" + `、` + "`iccid_4`" + `
|
||||
- 列格式:设置为文本格式(避免长数字被转为科学记数法)`,
|
||||
Tags: []string{"设备管理"},
|
||||
Input: new(dto.ImportDeviceRequest),
|
||||
|
||||
@@ -299,6 +299,8 @@ func (s *Service) fillPackageInfo(ctx context.Context, resp *dto.AssetResolveRes
|
||||
|
||||
resp.CurrentPackageUsageID = &usage.ID
|
||||
resp.CurrentPackage = usage.PackageName
|
||||
resp.CurrentPackageActivatedAt = usage.ActivatedAt
|
||||
resp.CurrentPackageExpiresAt = usage.ExpiresAt
|
||||
if resp.CurrentPackage == "" {
|
||||
pkg, pkgErr := s.packageStore.GetByID(ctx, usage.PackageID)
|
||||
if pkgErr == nil && pkg != nil {
|
||||
|
||||
@@ -304,6 +304,7 @@ func (h *DeviceImportHandler) processBatch(ctx context.Context, task *model.Devi
|
||||
|
||||
device := &model.Device{
|
||||
VirtualNo: row.VirtualNo,
|
||||
SN: row.SN,
|
||||
IMEI: row.IMEI,
|
||||
DeviceName: row.DeviceName,
|
||||
DeviceModel: row.DeviceModel,
|
||||
|
||||
Reference in New Issue
Block a user