分裂iccid长度
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m47s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m47s
This commit is contained in:
@@ -188,7 +188,7 @@ func initServices(s *stores, deps *Dependencies) *services {
|
||||
deps.Logger,
|
||||
),
|
||||
Enterprise: enterpriseSvc.New(deps.DB, s.Enterprise, s.Shop, s.Account),
|
||||
EnterpriseCard: enterpriseCardSvc.New(deps.DB, s.Enterprise, s.EnterpriseCardAuthorization),
|
||||
EnterpriseCard: enterpriseCardSvc.New(deps.DB, s.Enterprise, s.EnterpriseCardAuthorization, s.IotCard),
|
||||
EnterpriseDevice: enterpriseDeviceSvc.New(deps.DB, s.Enterprise, s.Device, s.DeviceSimBinding, s.EnterpriseDeviceAuthorization, s.EnterpriseCardAuthorization, deps.Logger),
|
||||
Authorization: enterpriseCardSvc.NewAuthorizationService(s.Enterprise, s.IotCard, s.EnterpriseCardAuthorization, deps.Logger),
|
||||
IotCard: iotCard,
|
||||
|
||||
@@ -55,6 +55,11 @@ type IotCard struct {
|
||||
DeviceVirtualNo string `gorm:"column:device_virtual_no;type:varchar(100);not null;default:'';comment:绑定设备的虚拟号快照(未绑定时为空字符串)" json:"device_virtual_no"`
|
||||
LastGatewayReadingMB float64 `gorm:"column:last_gateway_reading_mb;type:float;not null;default:0;comment:上次轮询时网关返回的流量读数(MB)" json:"last_gateway_reading_mb"`
|
||||
RealnamePolicy string `gorm:"column:realname_policy;type:varchar(20);default:'after_order';not null;comment:实名认证策略(none=无需实名,before_order=先实名后充值/购买,after_order=先充值/购买后实名)" json:"realname_policy"`
|
||||
|
||||
// ICCID 双列存储,用于支持 19/20 位 ICCID 精确路由查询
|
||||
// 所有卡必须有 ICCID19;仅 20 位运营商卡有 ICCID20(19 位卡为 nil → 数据库 NULL)
|
||||
ICCID19 string `gorm:"column:iccid_19;type:varchar(19);comment:ICCID前19位(所有卡必填,用于19位运营商精确查询)" json:"iccid_19,omitempty"`
|
||||
ICCID20 *string `gorm:"column:iccid_20;type:varchar(20);comment:完整20位ICCID(仅20位运营商卡有值,19位卡为NULL)" json:"iccid_20,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -15,6 +15,7 @@ type PersonalCustomerICCID struct {
|
||||
BindAt time.Time `gorm:"column:bind_at;type:timestamp;not null;comment:绑定时间" json:"bind_at"`
|
||||
LastUsedAt *time.Time `gorm:"column:last_used_at;type:timestamp;comment:最后使用时间" json:"last_used_at"`
|
||||
Status int `gorm:"column:status;type:int;not null;default:1;comment:状态 0=禁用 1=启用" json:"status"`
|
||||
ICCID19 string `gorm:"column:iccid_19;type:varchar(19);comment:ICCID前19位(用于19位运营商精确查询)" json:"iccid_19,omitempty"`
|
||||
}
|
||||
|
||||
// TableName 指定表名
|
||||
|
||||
@@ -17,17 +17,20 @@ type Service struct {
|
||||
db *gorm.DB
|
||||
enterpriseStore *postgres.EnterpriseStore
|
||||
enterpriseCardAuthStore *postgres.EnterpriseCardAuthorizationStore
|
||||
iotCardStore *postgres.IotCardStore
|
||||
}
|
||||
|
||||
func New(
|
||||
db *gorm.DB,
|
||||
enterpriseStore *postgres.EnterpriseStore,
|
||||
enterpriseCardAuthStore *postgres.EnterpriseCardAuthorizationStore,
|
||||
iotCardStore *postgres.IotCardStore,
|
||||
) *Service {
|
||||
return &Service{
|
||||
db: db,
|
||||
enterpriseStore: enterpriseStore,
|
||||
enterpriseCardAuthStore: enterpriseCardAuthStore,
|
||||
iotCardStore: iotCardStore,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,21 +45,18 @@ func (s *Service) AllocateCardsPreview(ctx context.Context, enterpriseID uint, r
|
||||
return nil, errors.New(errors.CodeEnterpriseNotFound, "企业不存在")
|
||||
}
|
||||
|
||||
var iotCards []model.IotCard
|
||||
if err := s.db.WithContext(ctx).Where("iccid IN ?", req.ICCIDs).Find(&iotCards).Error; err != nil {
|
||||
iotCardPtrs, err := s.iotCardStore.GetByICCIDs(ctx, req.ICCIDs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡信息失败")
|
||||
}
|
||||
|
||||
cardMap := make(map[string]*model.IotCard)
|
||||
cardIDMap := make(map[uint]*model.IotCard)
|
||||
for i := range iotCards {
|
||||
cardMap[iotCards[i].ICCID] = &iotCards[i]
|
||||
cardIDMap[iotCards[i].ID] = &iotCards[i]
|
||||
}
|
||||
|
||||
cardIDs := make([]uint, 0, len(iotCards))
|
||||
for _, card := range iotCards {
|
||||
cardIDs = append(cardIDs, card.ID)
|
||||
cardIDs := make([]uint, 0, len(iotCardPtrs))
|
||||
for _, c := range iotCardPtrs {
|
||||
cardMap[c.ICCID] = c
|
||||
cardIDMap[c.ID] = c
|
||||
cardIDs = append(cardIDs, c.ID)
|
||||
}
|
||||
|
||||
var bindings []model.DeviceSimBinding
|
||||
@@ -181,18 +181,18 @@ func (s *Service) RecallCards(ctx context.Context, enterpriseID uint, req *dto.R
|
||||
return nil, errors.New(errors.CodeEnterpriseNotFound, "企业不存在")
|
||||
}
|
||||
|
||||
var iotCards []model.IotCard
|
||||
if err := s.db.WithContext(ctx).Where("iccid IN ?", req.ICCIDs).Find(&iotCards).Error; err != nil {
|
||||
iotCardPtrs, err := s.iotCardStore.GetByICCIDs(ctx, req.ICCIDs)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(errors.CodeInternalError, err, "查询卡信息失败")
|
||||
}
|
||||
|
||||
cardMap := make(map[string]*model.IotCard)
|
||||
cardIDMap := make(map[uint]*model.IotCard)
|
||||
cardIDs := make([]uint, 0, len(iotCards))
|
||||
for i := range iotCards {
|
||||
cardMap[iotCards[i].ICCID] = &iotCards[i]
|
||||
cardIDMap[iotCards[i].ID] = &iotCards[i]
|
||||
cardIDs = append(cardIDs, iotCards[i].ID)
|
||||
cardIDs := make([]uint, 0, len(iotCardPtrs))
|
||||
for _, c := range iotCardPtrs {
|
||||
cardMap[c.ICCID] = c
|
||||
cardIDMap[c.ID] = c
|
||||
cardIDs = append(cardIDs, c.ID)
|
||||
}
|
||||
|
||||
existingAuths, err := s.enterpriseCardAuthStore.GetActiveAuthsByCardIDs(ctx, enterpriseID, cardIDs)
|
||||
|
||||
@@ -8,8 +8,10 @@ import (
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/errors"
|
||||
"github.com/break/junhong_cmp_fiber/pkg/logger"
|
||||
"github.com/jackc/pgx/v5/pgconn"
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -183,21 +185,46 @@ func (s *DeviceSimBindingStore) GetBoundICCIDs(ctx context.Context, iccids []str
|
||||
return result, nil
|
||||
}
|
||||
|
||||
var bindings []struct {
|
||||
ICCID string
|
||||
}
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("tb_device_sim_binding b").
|
||||
Select("c.iccid").
|
||||
Joins("JOIN tb_iot_card c ON c.id = b.iot_card_id").
|
||||
Where("c.iccid IN ? AND b.bind_status = 1 AND c.deleted_at IS NULL", iccids).
|
||||
Find(&bindings).Error; err != nil {
|
||||
return nil, err
|
||||
var list19, list20 []string
|
||||
for _, id := range iccids {
|
||||
switch len(id) {
|
||||
case 19:
|
||||
list19 = append(list19, id)
|
||||
case 20:
|
||||
list20 = append(list20, id)
|
||||
}
|
||||
}
|
||||
|
||||
for _, b := range bindings {
|
||||
result[b.ICCID] = true
|
||||
if len(list19) > 0 {
|
||||
var rows []struct{ ICCID string }
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("tb_device_sim_binding b").
|
||||
Select("c.iccid_19 AS iccid").
|
||||
Joins("JOIN tb_iot_card c ON c.id = b.iot_card_id").
|
||||
Where("c.iccid_19 IN ? AND b.bind_status = 1 AND c.deleted_at IS NULL", list19).
|
||||
Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range rows {
|
||||
result[r.ICCID] = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(list20) > 0 {
|
||||
var rows []struct{ ICCID string }
|
||||
if err := s.db.WithContext(ctx).
|
||||
Table("tb_device_sim_binding b").
|
||||
Select("c.iccid_20 AS iccid").
|
||||
Joins("JOIN tb_iot_card c ON c.id = b.iot_card_id").
|
||||
Where("c.iccid_20 IN ? AND b.bind_status = 1 AND c.deleted_at IS NULL", list20).
|
||||
Find(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, r := range rows {
|
||||
result[r.ICCID] = true
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -206,27 +233,44 @@ func (s *DeviceSimBindingStore) GetBoundICCIDs(ctx context.Context, iccids []str
|
||||
// currentIccid 为空字符串时,仅执行全部清空(无当前卡的情况)
|
||||
func (s *DeviceSimBindingStore) UpdateIsCurrentByDeviceID(ctx context.Context, deviceID uint, currentIccid string) error {
|
||||
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||
// 第一步:将该设备所有活跃绑定的 is_current 设为 false
|
||||
if err := tx.Model(&model.DeviceSimBinding{}).
|
||||
Where("device_id = ? AND bind_status = 1", deviceID).
|
||||
Update("is_current", false).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 第二步:将当前 ICCID 对应的绑定记录设为 is_current = true
|
||||
if currentIccid == "" {
|
||||
return nil
|
||||
}
|
||||
// 通过子查询找到对应的 iot_card_id(避免跨表 JOIN 更新)
|
||||
|
||||
var column string
|
||||
switch len(currentIccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
case 20:
|
||||
column = "iccid_20"
|
||||
default:
|
||||
logger.GetAppLogger().Error("UpdateIsCurrentByDeviceID: ICCID 长度异常,跳过 is_current 更新",
|
||||
zap.String("iccid", currentIccid),
|
||||
zap.Uint("device_id", deviceID),
|
||||
zap.Int("length", len(currentIccid)),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
|
||||
var iotCardID uint
|
||||
if err := tx.Table("tb_iot_card").
|
||||
Select("id").
|
||||
Where("iccid = ? AND deleted_at IS NULL", currentIccid).
|
||||
Where(column+" = ? AND deleted_at IS NULL", currentIccid).
|
||||
Scan(&iotCardID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if iotCardID == 0 {
|
||||
// 未找到对应卡记录,不更新(可能卡尚未入库)
|
||||
logger.GetAppLogger().Warn("UpdateIsCurrentByDeviceID: 未命中卡记录,is_current 不更新",
|
||||
zap.String("iccid", currentIccid),
|
||||
zap.Uint("device_id", deviceID),
|
||||
zap.String("column_used", column),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
return tx.Model(&model.DeviceSimBinding{}).
|
||||
|
||||
@@ -56,13 +56,30 @@ func (s *IotCardStore) GetByID(ctx context.Context, id uint) (*model.IotCard, er
|
||||
|
||||
func (s *IotCardStore) GetByICCID(ctx context.Context, iccid string) (*model.IotCard, error) {
|
||||
var card model.IotCard
|
||||
query := s.db.WithContext(ctx).Where("iccid = ?", iccid)
|
||||
// 应用数据权限过滤
|
||||
var column string
|
||||
switch len(iccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
case 20:
|
||||
column = "iccid_20"
|
||||
default:
|
||||
logger.GetAppLogger().Error("GetByICCID: ICCID 长度异常,拒绝查询",
|
||||
zap.String("iccid", iccid),
|
||||
zap.Int("length", len(iccid)),
|
||||
)
|
||||
return nil, gorm.ErrRecordNotFound
|
||||
}
|
||||
query := s.db.WithContext(ctx).Where(column+" = ?", iccid)
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
if err := query.First(&card).Error; err != nil {
|
||||
err := query.First(&card).Error
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
logger.GetAppLogger().Warn("GetByICCID: 未命中,上游 ICCID 格式可能与存储不一致",
|
||||
zap.String("iccid", iccid),
|
||||
zap.String("column_used", column),
|
||||
)
|
||||
return nil, err
|
||||
}
|
||||
return &card, nil
|
||||
return &card, err
|
||||
}
|
||||
|
||||
func (s *IotCardStore) GetByIDs(ctx context.Context, ids []uint) ([]*model.IotCard, error) {
|
||||
@@ -80,8 +97,21 @@ func (s *IotCardStore) GetByIDs(ctx context.Context, ids []uint) ([]*model.IotCa
|
||||
}
|
||||
|
||||
func (s *IotCardStore) ExistsByICCID(ctx context.Context, iccid string) (bool, error) {
|
||||
var column string
|
||||
switch len(iccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
case 20:
|
||||
column = "iccid_20"
|
||||
default:
|
||||
logger.GetAppLogger().Error("ExistsByICCID: ICCID 长度异常,拒绝查询",
|
||||
zap.String("iccid", iccid),
|
||||
zap.Int("length", len(iccid)),
|
||||
)
|
||||
return false, nil
|
||||
}
|
||||
var count int64
|
||||
if err := s.db.WithContext(ctx).Model(&model.IotCard{}).Where("iccid = ?", iccid).Count(&count).Error; err != nil {
|
||||
if err := s.db.WithContext(ctx).Model(&model.IotCard{}).Where(column+" = ?", iccid).Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
@@ -92,17 +122,42 @@ func (s *IotCardStore) ExistsByICCIDBatch(ctx context.Context, iccids []string)
|
||||
return make(map[string]bool), nil
|
||||
}
|
||||
|
||||
var existingICCIDs []string
|
||||
if err := s.db.WithContext(ctx).Model(&model.IotCard{}).
|
||||
Where("iccid IN ?", iccids).
|
||||
Pluck("iccid", &existingICCIDs).Error; err != nil {
|
||||
return nil, err
|
||||
var list19, list20 []string
|
||||
for _, id := range iccids {
|
||||
switch len(id) {
|
||||
case 19:
|
||||
list19 = append(list19, id)
|
||||
case 20:
|
||||
list20 = append(list20, id)
|
||||
}
|
||||
}
|
||||
|
||||
result := make(map[string]bool)
|
||||
for _, iccid := range existingICCIDs {
|
||||
result[iccid] = true
|
||||
|
||||
if len(list19) > 0 {
|
||||
var found []string
|
||||
if err := s.db.WithContext(ctx).Model(&model.IotCard{}).
|
||||
Where("iccid_19 IN ?", list19).
|
||||
Pluck("iccid_19", &found).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range found {
|
||||
result[v] = true
|
||||
}
|
||||
}
|
||||
|
||||
if len(list20) > 0 {
|
||||
var found []string
|
||||
if err := s.db.WithContext(ctx).Model(&model.IotCard{}).
|
||||
Where("iccid_20 IN ?", list20).
|
||||
Pluck("iccid_20", &found).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, v := range found {
|
||||
result[v] = true
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -689,14 +744,51 @@ func (s *IotCardStore) GetByICCIDs(ctx context.Context, iccids []string) ([]*mod
|
||||
if len(iccids) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
var cards []*model.IotCard
|
||||
query := s.db.WithContext(ctx).Where("iccid IN ?", iccids)
|
||||
// 应用数据权限过滤
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
if err := query.Find(&cards).Error; err != nil {
|
||||
return nil, err
|
||||
|
||||
var list19, list20 []string
|
||||
for _, id := range iccids {
|
||||
switch len(id) {
|
||||
case 19:
|
||||
list19 = append(list19, id)
|
||||
case 20:
|
||||
list20 = append(list20, id)
|
||||
}
|
||||
}
|
||||
return cards, nil
|
||||
|
||||
seen := make(map[uint]struct{})
|
||||
var all []*model.IotCard
|
||||
|
||||
if len(list19) > 0 {
|
||||
var cards []*model.IotCard
|
||||
query := s.db.WithContext(ctx).Where("iccid_19 IN ?", list19)
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
if err := query.Find(&cards).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range cards {
|
||||
if _, dup := seen[c.ID]; !dup {
|
||||
seen[c.ID] = struct{}{}
|
||||
all = append(all, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(list20) > 0 {
|
||||
var cards []*model.IotCard
|
||||
query := s.db.WithContext(ctx).Where("iccid_20 IN ?", list20)
|
||||
query = middleware.ApplyShopFilter(ctx, query)
|
||||
if err := query.Find(&cards).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, c := range cards {
|
||||
if _, dup := seen[c.ID]; !dup {
|
||||
seen[c.ID] = struct{}{}
|
||||
all = append(all, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return all, nil
|
||||
}
|
||||
|
||||
func (s *IotCardStore) GetStandaloneByICCIDRange(ctx context.Context, iccidStart, iccidEnd string, shopID *uint) ([]*model.IotCard, error) {
|
||||
|
||||
@@ -41,9 +41,16 @@ func (s *PersonalCustomerICCIDStore) GetByCustomerID(ctx context.Context, custom
|
||||
|
||||
// GetByICCID 根据 ICCID 获取所有绑定记录(查询哪些用户使用过这个 ICCID)
|
||||
func (s *PersonalCustomerICCIDStore) GetByICCID(ctx context.Context, iccid string) ([]*model.PersonalCustomerICCID, error) {
|
||||
var column string
|
||||
switch len(iccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
default:
|
||||
column = "iccid"
|
||||
}
|
||||
var records []*model.PersonalCustomerICCID
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("iccid = ?", iccid).
|
||||
Where(column+" = ?", iccid).
|
||||
Order("last_used_at DESC").
|
||||
Find(&records).Error; err != nil {
|
||||
return nil, err
|
||||
@@ -53,9 +60,16 @@ func (s *PersonalCustomerICCIDStore) GetByICCID(ctx context.Context, iccid strin
|
||||
|
||||
// GetByCustomerAndICCID 根据客户 ID 和 ICCID 获取绑定记录
|
||||
func (s *PersonalCustomerICCIDStore) GetByCustomerAndICCID(ctx context.Context, customerID uint, iccid string) (*model.PersonalCustomerICCID, error) {
|
||||
var column string
|
||||
switch len(iccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
default:
|
||||
column = "iccid"
|
||||
}
|
||||
var record model.PersonalCustomerICCID
|
||||
if err := s.db.WithContext(ctx).
|
||||
Where("customer_id = ? AND iccid = ?", customerID, iccid).
|
||||
Where("customer_id = ? AND "+column+" = ?", customerID, iccid).
|
||||
First(&record).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -85,10 +99,17 @@ func (s *PersonalCustomerICCIDStore) Delete(ctx context.Context, id uint) error
|
||||
|
||||
// ExistsByCustomerAndICCID 检查客户是否已绑定该 ICCID
|
||||
func (s *PersonalCustomerICCIDStore) ExistsByCustomerAndICCID(ctx context.Context, customerID uint, iccid string) (bool, error) {
|
||||
var column string
|
||||
switch len(iccid) {
|
||||
case 19:
|
||||
column = "iccid_19"
|
||||
default:
|
||||
column = "iccid"
|
||||
}
|
||||
var count int64
|
||||
if err := s.db.WithContext(ctx).
|
||||
Model(&model.PersonalCustomerICCID{}).
|
||||
Where("customer_id = ? AND iccid = ? AND status = ?", customerID, iccid, 1).
|
||||
Where("customer_id = ? AND "+column+" = ? AND status = ?", customerID, iccid, 1).
|
||||
Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -100,17 +121,20 @@ func (s *PersonalCustomerICCIDStore) ExistsByCustomerAndICCID(ctx context.Contex
|
||||
func (s *PersonalCustomerICCIDStore) CreateOrUpdateLastUsed(ctx context.Context, customerID uint, iccid string) error {
|
||||
record, err := s.GetByCustomerAndICCID(ctx, customerID, iccid)
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
// 不存在,创建新记录
|
||||
iccid19 := iccid
|
||||
if len(iccid) == 20 {
|
||||
iccid19 = iccid[:19]
|
||||
}
|
||||
newRecord := &model.PersonalCustomerICCID{
|
||||
CustomerID: customerID,
|
||||
ICCID: iccid,
|
||||
Status: 1, // 启用
|
||||
ICCID19: iccid19,
|
||||
Status: 1,
|
||||
}
|
||||
return s.Create(ctx, newRecord)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 存在,更新最后使用时间
|
||||
return s.UpdateLastUsedAt(ctx, record.ID)
|
||||
}
|
||||
|
||||
@@ -345,8 +345,28 @@ func (h *IotCardImportHandler) processBatch(ctx context.Context, task *model.Iot
|
||||
|
||||
for _, card := range finalCards {
|
||||
meta := cardMetaMap[card.ICCID]
|
||||
|
||||
// 拆分 ICCID 为双列存储值(长度校验已在 ValidateICCID 通过,此处作防御性保留)
|
||||
iccid19, iccid20 := utils.SplitICCID(card.ICCID)
|
||||
if iccid19 == "" {
|
||||
h.logger.Error("ICCID 长度异常,跳过写入",
|
||||
zap.String("iccid", card.ICCID),
|
||||
zap.Int("length", len(card.ICCID)),
|
||||
)
|
||||
result.failedItems = append(result.failedItems, model.ImportResultItem{
|
||||
Line: meta.line,
|
||||
ICCID: card.ICCID,
|
||||
MSISDN: meta.msisdn,
|
||||
Reason: "ICCID 长度异常,无法拆分",
|
||||
})
|
||||
result.failCount++
|
||||
continue
|
||||
}
|
||||
|
||||
iotCard := &model.IotCard{
|
||||
ICCID: card.ICCID,
|
||||
ICCID19: iccid19,
|
||||
ICCID20: iccid20,
|
||||
MSISDN: card.MSISDN,
|
||||
VirtualNo: card.VirtualNo,
|
||||
CarrierID: task.CarrierID,
|
||||
|
||||
Reference in New Issue
Block a user