package iot_card import ( "context" "strconv" cardapp "github.com/break/junhong_cmp_fiber/internal/application/cardobservation" "github.com/break/junhong_cmp_fiber/internal/gateway" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/pkg/constants" "github.com/break/junhong_cmp_fiber/pkg/errors" "go.uber.org/zap" ) // validateCardAccess 通过 ICCID 验证卡存在且当前用户有权限访问 // 利用 GORM 数据权限回调自动过滤,确保越权请求返回 404 func (s *Service) validateCardAccess(ctx context.Context, iccid string) error { _, err := s.iotCardStore.GetByICCID(ctx, iccid) if err != nil { return errors.New(errors.CodeNotFound, "卡不存在或无权限访问") } return nil } // GatewayQueryCardStatus 查询卡实时状态 func (s *Service) GatewayQueryCardStatus(ctx context.Context, iccid string) (*gateway.CardStatusResp, error) { if err := s.validateCardAccess(ctx, iccid); err != nil { return nil, err } return s.gatewayClient.QueryCardStatus(ctx, &gateway.CardStatusReq{ CardNo: iccid, }) } // GatewayQueryFlow 查询流量使用情况 func (s *Service) GatewayQueryFlow(ctx context.Context, iccid string) (*gateway.FlowUsageResp, error) { if err := s.validateCardAccess(ctx, iccid); err != nil { return nil, err } return s.gatewayClient.QueryFlow(ctx, &gateway.FlowQueryReq{ CardNo: iccid, }) } // GatewayQueryRealnameStatus 查询实名认证状态 func (s *Service) GatewayQueryRealnameStatus(ctx context.Context, iccid string) (*gateway.RealnameStatusResp, error) { if err := s.validateCardAccess(ctx, iccid); err != nil { return nil, err } return s.gatewayClient.QueryRealnameStatus(ctx, &gateway.CardStatusReq{ CardNo: iccid, }) } // GatewayGetRealnameLink 获取实名认证跳转链接 func (s *Service) GatewayGetRealnameLink(ctx context.Context, iccid string) (*gateway.RealnameLinkResp, error) { card, err := s.iotCardStore.GetByICCID(ctx, iccid) if err != nil { return nil, errors.New(errors.CodeNotFound, "卡不存在或无权限访问") } response, err := s.gatewayClient.GetRealnameLink(ctx, &gateway.CardStatusReq{ CardNo: iccid, }) if err != nil { return nil, err } s.dispatchAdminRealnameObservation(ctx, card) return response, nil } func (s *Service) dispatchAdminRealnameObservation(ctx context.Context, card *model.IotCard) { if s.observationSeries == nil || card == nil { return } requestID := requestIDFromContext(ctx) s.observationSeries.DispatchRealnameWithCapability(ctx, cardapp.RealnameCapabilitySeriesRequest{ CarrierID: card.CarrierID, Request: cardapp.SeriesRequest{ Scene: constants.CardObservationSceneAdminRealnameLink, ResourceType: constants.CardObservationResourceTypeCard, ResourceID: strconv.FormatUint(uint64(card.ID), 10), SyncType: constants.CardObservationSyncTypeRealname, ExpectedValue: "verified", Source: constants.CardObservationSourceBusinessEvent, RequestID: requestID, CorrelationID: requestID, }, }) } // GatewayStopCard 停止卡服务(通过 Gateway API) func (s *Service) GatewayStopCard(ctx context.Context, iccid string) error { if err := s.validateCardAccess(ctx, iccid); err != nil { return err } s.logger.Info("调用网关停机(手动)", zap.String("iccid", iccid)) if err := s.gatewayClient.StopCard(ctx, &gateway.CardOperationReq{ CardNo: iccid, }); err != nil { s.logger.Error("网关停机失败(手动)", zap.String("iccid", iccid), zap.Error(err)) return err } s.logger.Info("网关停机成功(手动)", zap.String("iccid", iccid)) return nil } // GatewayStartCard 恢复卡服务(通过 Gateway API) func (s *Service) GatewayStartCard(ctx context.Context, iccid string) error { if err := s.validateCardAccess(ctx, iccid); err != nil { return err } s.logger.Info("调用网关复机(手动)", zap.String("iccid", iccid)) if err := s.gatewayClient.StartCard(ctx, &gateway.CardOperationReq{ CardNo: iccid, }); err != nil { s.logger.Error("网关复机失败(手动)", zap.String("iccid", iccid), zap.Error(err)) return err } s.logger.Info("网关复机成功(手动)", zap.String("iccid", iccid)) return nil }