package app import ( "context" "strconv" "strings" "git.5iot.com/iotlcm-public/iotlcm-app/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-app/internal/library/contexts" "git.5iot.com/iotlcm-public/iotlcm-app/internal/model/entity" "github.com/gogf/gf/v2/errors/gerror" ) type appCardChannelInfo struct { ChanKey string ChanName string ChanAlias string TempKey string } type appCardChannelAssocRecord struct { Id int64 `orm:"id"` ChannelID string `orm:"channel_id"` MatchType int `orm:"match_type"` Iccid string `orm:"iccid"` IccidStart string `orm:"iccid_start"` IccidEnd string `orm:"iccid_end"` Status int `orm:"status"` } func (s *sAppCard) attachCardChannelInfo(ctx context.Context, row *appCardQueryRow) error { if row == nil { return nil } info, err := s.loadCardChannelInfo(ctx, row.TenantId, row.Iccid, row.ChanKey) if err != nil { return err } if info == nil { return nil } row.ChanKey = info.ChanKey row.ChanName = info.ChanName row.ChanAlias = info.ChanAlias row.TempKey = info.TempKey return nil } func (s *sAppCard) attachDiagnosisCardChannelInfo(ctx context.Context, row *appCardQueryRow) error { if row == nil { return nil } info, err := s.loadDiagnosisCardChannelInfo(ctx, row.TenantId, row.Iccid, row.ChanKey) if err != nil { return err } if info == nil { return nil } row.ChanKey = info.ChanKey row.ChanName = info.ChanName row.ChanAlias = info.ChanAlias row.TempKey = info.TempKey return nil } func (s *sAppCard) attachCardChannelInfoRows(ctx context.Context, rows []*appCardQueryRow) error { if len(rows) == 0 { return nil } cache := make(map[string]*appCardChannelInfo, len(rows)) for _, row := range rows { if row == nil { continue } cacheKey := strings.Join([]string{ strings.TrimSpace(row.TenantId), strings.TrimSpace(row.Iccid), strings.TrimSpace(row.ChanKey), }, "|") info, ok := cache[cacheKey] if !ok { var err error info, err = s.loadCardChannelInfo(ctx, row.TenantId, row.Iccid, row.ChanKey) if err != nil { return err } cache[cacheKey] = info } if info == nil { continue } row.ChanKey = info.ChanKey row.ChanName = info.ChanName row.ChanAlias = info.ChanAlias row.TempKey = info.TempKey } return nil } func (s *sAppCard) loadCardChannelInfo(ctx context.Context, tenantId string, iccid string, legacyChanKey string) (*appCardChannelInfo, error) { tenantId = strings.TrimSpace(tenantId) legacyChanKey = strings.TrimSpace(legacyChanKey) if legacyChanKey == "" { return nil, nil } return s.findLegacyCardChannelInfo(ctx, tenantId, legacyChanKey) } func (s *sAppCard) loadDiagnosisCardChannelInfo(ctx context.Context, tenantId string, iccid string, legacyChanKey string) (*appCardChannelInfo, error) { iccid = strings.TrimSpace(iccid) tenantId = strings.TrimSpace(tenantId) legacyChanKey = strings.TrimSpace(legacyChanKey) if iccid != "" { info, err := s.findAssocCardChannelInfo(ctx, tenantId, iccid) if err != nil { return nil, err } if info != nil { return info, nil } } if legacyChanKey == "" { return nil, nil } return s.findLegacyCardChannelInfo(ctx, tenantId, legacyChanKey) } func (s *sAppCard) findAssocCardChannelInfo(ctx context.Context, tenantId string, iccid string) (*appCardChannelInfo, error) { if strings.TrimSpace(iccid) == "" { return nil, nil } assoc, err := s.resolveCardChannelAssocByIccid(ctx, iccid) if err != nil { return nil, err } if assoc == nil || strings.TrimSpace(assoc.ChannelID) == "" { return nil, nil } info, err := s.findCardChannelInfoByRef(ctx, tenantId, assoc.ChannelID) if err != nil { return nil, err } if info == nil || strings.TrimSpace(info.ChanKey) == "" { return nil, gerror.New("卡通道关联已匹配,但未找到对应通道配置") } return info, nil } func (s *sAppCard) resolveCardChannelAssocByIccid(ctx context.Context, iccid string) (*appCardChannelAssocRecord, error) { iccid = strings.TrimSpace(iccid) if iccid == "" { return nil, nil } columns := dao.CardChannelAssoc.Columns() var exact *appCardChannelAssocRecord err := dao.CardChannelAssoc.Ctx(ctx). Fields(columns.Id, columns.ChannelId, columns.MatchType, columns.Iccid, columns.IccidStart, columns.IccidEnd, columns.Status). Where(columns.Status, 1). Where(columns.MatchType, 1). Where(columns.Iccid+" COLLATE utf8mb4_general_ci = ?", iccid). OrderDesc(columns.Id). Limit(1). Scan(&exact) if err != nil { return nil, gerror.Wrap(err, "查询卡通道单卡关联失败") } if exact != nil && strings.TrimSpace(exact.ChannelID) != "" { return exact, nil } var ranged *appCardChannelAssocRecord err = dao.CardChannelAssoc.Ctx(ctx). Fields(columns.Id, columns.ChannelId, columns.MatchType, columns.Iccid, columns.IccidStart, columns.IccidEnd, columns.Status). Where(columns.Status, 1). Where(columns.MatchType, 2). Where(columns.IccidStart+" COLLATE utf8mb4_general_ci <= ? AND "+columns.IccidEnd+" COLLATE utf8mb4_general_ci >= ?", iccid, iccid). OrderDesc(columns.Id). Limit(1). Scan(&ranged) if err != nil { return nil, gerror.Wrap(err, "查询卡通道号段关联失败") } if ranged != nil && strings.TrimSpace(ranged.ChannelID) != "" { return ranged, nil } return nil, nil } func (s *sAppCard) findCardChannelInfoByRef(ctx context.Context, tenantId string, channelRef string) (*appCardChannelInfo, error) { channelRef = strings.TrimSpace(channelRef) if channelRef == "" { return nil, nil } if id, err := strconv.ParseInt(channelRef, 10, 64); err == nil && id > 0 { if info, err := s.findCardChannelInfoByID(ctx, tenantId, id); err != nil || info != nil { return info, err } } return s.findLegacyCardChannelInfo(ctx, tenantId, channelRef) } func (s *sAppCard) findCardChannelInfoByID(ctx context.Context, tenantId string, channelID int64) (*appCardChannelInfo, error) { if channelID <= 0 { return nil, nil } if tenantId = strings.TrimSpace(tenantId); tenantId == "" { tenantId = contexts.GetTenantId(ctx) } if tenantId != "" { channel, err := s.findCardChannelEntityByID(ctx, tenantId, channelID) if err != nil || channel != nil { return appCardChannelInfoFromEntity(channel), err } } channel, err := s.findCardChannelEntityByID(ctx, "", channelID) return appCardChannelInfoFromEntity(channel), err } func (s *sAppCard) findCardChannelEntityByID(ctx context.Context, tenantId string, channelID int64) (*entity.TSimChannels, error) { var channel *entity.TSimChannels mod := dao.TSimChannels.Ctx(ctx). Where(dao.TSimChannels.Columns().Id, channelID) if tenantId = strings.TrimSpace(tenantId); tenantId != "" { mod = mod.Where(dao.TSimChannels.Columns().TenantId, tenantId) } err := mod.Limit(1).Scan(&channel) if err != nil { return nil, gerror.Wrap(err, "查询通道信息失败") } return channel, nil } func (s *sAppCard) findLegacyCardChannelInfo(ctx context.Context, tenantId string, chanKey string) (*appCardChannelInfo, error) { chanKey = strings.TrimSpace(chanKey) if chanKey == "" { return nil, nil } if tenantId = strings.TrimSpace(tenantId); tenantId == "" { tenantId = contexts.GetTenantId(ctx) } if tenantId != "" { channel, err := s.findCardChannelEntityByKey(ctx, tenantId, chanKey) if err != nil || channel != nil { return appCardChannelInfoFromEntity(channel), err } } channel, err := s.findCardChannelEntityByKey(ctx, "", chanKey) return appCardChannelInfoFromEntity(channel), err } func (s *sAppCard) findCardChannelEntityByKey(ctx context.Context, tenantId string, chanKey string) (*entity.TSimChannels, error) { var channel *entity.TSimChannels mod := dao.TSimChannels.Ctx(ctx). Where(dao.TSimChannels.Columns().ChanKey, chanKey). Fields(dao.TSimChannels.Columns().Id, dao.TSimChannels.Columns().ChanKey, dao.TSimChannels.Columns().ChanName, dao.TSimChannels.Columns().ChanAlias, dao.TSimChannels.Columns().TempKey) if tenantId = strings.TrimSpace(tenantId); tenantId != "" { mod = mod.Where(dao.TSimChannels.Columns().TenantId, tenantId) } err := mod.Limit(1).Scan(&channel) if err != nil { return nil, gerror.Wrap(err, "查询通道信息失败") } if channel == nil || channel.Id == 0 { return nil, nil } return channel, nil } func appCardChannelInfoFromEntity(channel *entity.TSimChannels) *appCardChannelInfo { if channel == nil || channel.Id == 0 || strings.TrimSpace(channel.ChanKey) == "" { return nil } return &appCardChannelInfo{ ChanKey: strings.TrimSpace(channel.ChanKey), ChanName: strings.TrimSpace(channel.ChanName), ChanAlias: strings.TrimSpace(channel.ChanAlias), TempKey: strings.TrimSpace(channel.TempKey), } }