package device import ( "context" "github.com/break/junhong_cmp_fiber/internal/model" "github.com/break/junhong_cmp_fiber/internal/model/dto" "github.com/break/junhong_cmp_fiber/pkg/errors" "gorm.io/gorm" ) func (s *Service) ListBindings(ctx context.Context, deviceID uint) (*dto.ListDeviceCardsResponse, error) { device, err := s.deviceStore.GetByID(ctx, deviceID) if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeNotFound, "设备不存在") } return nil, err } bindings, err := s.deviceSimBindingStore.ListByDeviceID(ctx, device.ID) if err != nil { return nil, err } cardIDs := make([]uint, 0, len(bindings)) for _, binding := range bindings { cardIDs = append(cardIDs, binding.IotCardID) } var cards []*model.IotCard if len(cardIDs) > 0 { cards, err = s.iotCardStore.GetByIDs(ctx, cardIDs) if err != nil { return nil, err } } cardMap := make(map[uint]*model.IotCard) for _, card := range cards { cardMap[card.ID] = card } carrierMap := s.loadCarrierData(ctx, cards) responses := make([]*dto.DeviceCardBindingResponse, 0, len(bindings)) for _, binding := range bindings { card := cardMap[binding.IotCardID] if card == nil { continue } resp := &dto.DeviceCardBindingResponse{ ID: binding.ID, SlotPosition: binding.SlotPosition, IotCardID: binding.IotCardID, ICCID: card.ICCID, MSISDN: card.MSISDN, CarrierName: carrierMap[card.CarrierID], Status: card.Status, BindTime: binding.BindTime, } responses = append(responses, resp) } return &dto.ListDeviceCardsResponse{ Bindings: responses, }, nil } func (s *Service) BindCard(ctx context.Context, deviceID uint, req *dto.BindCardToDeviceRequest) (*dto.BindCardToDeviceResponse, error) { device, err := s.deviceStore.GetByID(ctx, deviceID) if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeNotFound, "设备不存在") } return nil, err } if req.SlotPosition > device.MaxSimSlots { return nil, errors.New(errors.CodeInvalidParam, "插槽位置超出设备最大插槽数") } existingBinding, err := s.deviceSimBindingStore.GetByDeviceAndSlot(ctx, device.ID, req.SlotPosition) if err != nil && err != gorm.ErrRecordNotFound { return nil, err } if existingBinding != nil { return nil, errors.New(errors.CodeConflict, "该插槽已有绑定的卡") } card, err := s.iotCardStore.GetByID(ctx, req.IotCardID) if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeIotCardNotFound) } return nil, err } activeBinding, err := s.deviceSimBindingStore.GetActiveBindingByCardID(ctx, card.ID) if err != nil && err != gorm.ErrRecordNotFound { return nil, err } if activeBinding != nil { return nil, errors.New(errors.CodeIotCardBoundToDevice, "该卡已绑定到其他设备") } binding := &model.DeviceSimBinding{ DeviceID: device.ID, IotCardID: card.ID, SlotPosition: req.SlotPosition, BindStatus: 1, } if err := s.deviceSimBindingStore.Create(ctx, binding); err != nil { return nil, err } return &dto.BindCardToDeviceResponse{ BindingID: binding.ID, Message: "绑定成功", }, nil } func (s *Service) UnbindCard(ctx context.Context, deviceID uint, cardID uint) (*dto.UnbindCardFromDeviceResponse, error) { device, err := s.deviceStore.GetByID(ctx, deviceID) if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeNotFound, "设备不存在") } return nil, err } binding, err := s.deviceSimBindingStore.GetByDeviceAndCard(ctx, device.ID, cardID) if err != nil { if err == gorm.ErrRecordNotFound { return nil, errors.New(errors.CodeNotFound, "该卡未绑定到此设备") } return nil, err } if err := s.deviceSimBindingStore.Unbind(ctx, binding.ID); err != nil { return nil, err } return &dto.UnbindCardFromDeviceResponse{ Message: "解绑成功", }, nil } func (s *Service) loadCarrierData(ctx context.Context, cards []*model.IotCard) map[uint]string { carrierIDs := make([]uint, 0) carrierIDSet := make(map[uint]bool) for _, card := range cards { if card.CarrierID > 0 && !carrierIDSet[card.CarrierID] { carrierIDs = append(carrierIDs, card.CarrierID) carrierIDSet[card.CarrierID] = true } } carrierMap := make(map[uint]string) if len(carrierIDs) > 0 { var carriers []model.Carrier s.db.WithContext(ctx).Where("id IN ?", carrierIDs).Find(&carriers) for _, c := range carriers { carrierMap[c.ID] = c.CarrierName } } return carrierMap }