This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model/dto"
|
||||
assetSvc "github.com/break/junhong_cmp_fiber/internal/service/asset"
|
||||
iotCardSvc "github.com/break/junhong_cmp_fiber/internal/service/iot_card"
|
||||
orderSvc "github.com/break/junhong_cmp_fiber/internal/service/order"
|
||||
packageSvc "github.com/break/junhong_cmp_fiber/internal/service/package"
|
||||
shopCommissionSvc "github.com/break/junhong_cmp_fiber/internal/service/shop_commission"
|
||||
@@ -26,6 +27,7 @@ type Service struct {
|
||||
packageService *packageSvc.Service
|
||||
orderService *orderSvc.Service
|
||||
shopCommissionService *shopCommissionSvc.Service
|
||||
stopResumeService *iotCardSvc.StopResumeService
|
||||
iotCardStore *postgres.IotCardStore
|
||||
packageUsageStore *postgres.PackageUsageStore
|
||||
packageStore *postgres.PackageStore
|
||||
@@ -39,6 +41,7 @@ func New(
|
||||
packageService *packageSvc.Service,
|
||||
orderService *orderSvc.Service,
|
||||
shopCommissionService *shopCommissionSvc.Service,
|
||||
stopResumeService *iotCardSvc.StopResumeService,
|
||||
iotCardStore *postgres.IotCardStore,
|
||||
packageUsageStore *postgres.PackageUsageStore,
|
||||
packageStore *postgres.PackageStore,
|
||||
@@ -50,6 +53,7 @@ func New(
|
||||
packageService: packageService,
|
||||
orderService: orderService,
|
||||
shopCommissionService: shopCommissionService,
|
||||
stopResumeService: stopResumeService,
|
||||
iotCardStore: iotCardStore,
|
||||
packageUsageStore: packageUsageStore,
|
||||
packageStore: packageStore,
|
||||
@@ -140,6 +144,27 @@ func (s *Service) GetRealnameStatus(ctx context.Context, req *dto.AgentOpenAPICa
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ResumeCard 调用上游复机机卡分离停机卡
|
||||
func (s *Service) ResumeCard(ctx context.Context, req *dto.AgentOpenAPICardResumeRequest) (*dto.AgentOpenAPICardResumeResponse, error) {
|
||||
card, err := s.resolveOpenAPICard(ctx, req.CardNo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if s.stopResumeService == nil {
|
||||
return nil, errors.New(errors.CodeInternalError, "开放接口复机依赖未配置")
|
||||
}
|
||||
if err := s.stopResumeService.StartMachineSeparatedCard(ctx, card); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &dto.AgentOpenAPICardResumeResponse{
|
||||
CardNo: req.CardNo,
|
||||
CardStatus: constants.AgentOpenAPICardStatusNormal,
|
||||
CardStatusName: constants.AgentOpenAPICardStatusName(constants.AgentOpenAPICardStatusNormal),
|
||||
GatewayExtend: "",
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ListPackages 查询开放接口代理可购买套餐列表
|
||||
func (s *Service) ListPackages(ctx context.Context, req *dto.AgentOpenAPIPackageListRequest) ([]*dto.AgentOpenAPIPackageItem, int64, int, int, error) {
|
||||
status := constants.StatusEnabled
|
||||
|
||||
@@ -3,6 +3,7 @@ package iot_card
|
||||
import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/gateway"
|
||||
@@ -1421,13 +1422,14 @@ func (s *Service) RefreshCardDataFromGateway(ctx context.Context, iccid string)
|
||||
if err != nil {
|
||||
s.logger.Warn("刷新卡数据:查询网络状态失败", zap.String("iccid", iccid), zap.Error(err))
|
||||
} else {
|
||||
updates["gateway_extend"] = statusResp.Extend
|
||||
networkStatus, ok := gateway.ParseCardNetworkStatus(statusResp.CardStatus, statusResp.Extend)
|
||||
gatewayExtend := strings.TrimSpace(statusResp.Extend)
|
||||
updates["gateway_extend"] = gatewayExtend
|
||||
networkStatus, ok := gateway.ParseCardNetworkStatus(statusResp.CardStatus, gatewayExtend)
|
||||
if !ok {
|
||||
s.logger.Warn("刷新卡数据:未知 Gateway 卡状态",
|
||||
zap.String("iccid", iccid),
|
||||
zap.String("card_status", statusResp.CardStatus),
|
||||
zap.String("extend", statusResp.Extend))
|
||||
zap.String("extend", gatewayExtend))
|
||||
} else {
|
||||
updates["network_status"] = networkStatus
|
||||
}
|
||||
|
||||
@@ -2,14 +2,14 @@ package iot_card
|
||||
|
||||
import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
|
||||
stderrors "errors"
|
||||
|
||||
"github.com/break/junhong_cmp_fiber/internal/gateway"
|
||||
"github.com/break/junhong_cmp_fiber/internal/model"
|
||||
assetAuditSvc "github.com/break/junhong_cmp_fiber/internal/service/asset_audit"
|
||||
@@ -672,6 +672,108 @@ func (s *StopResumeService) resumeCardWithRetry(ctx context.Context, card *model
|
||||
return lastErr
|
||||
}
|
||||
|
||||
// StartMachineSeparatedCard 对机卡分离停机卡执行复机
|
||||
// 调用上游复机前检查本地落库的 Gateway extend,只有“机卡分离停机”才允许复机。
|
||||
func (s *StopResumeService) StartMachineSeparatedCard(ctx context.Context, card *model.IotCard) error {
|
||||
if card == nil {
|
||||
return errors.New(errors.CodeInvalidParam)
|
||||
}
|
||||
if s.gatewayClient == nil {
|
||||
return errors.New(errors.CodeInternalError, "Gateway 未配置,停复机操作不可用")
|
||||
}
|
||||
|
||||
gatewayExtend := strings.TrimSpace(card.GatewayExtend)
|
||||
if gatewayExtend != constants.GatewayCardExtendMachineSeparated {
|
||||
denyErr := errors.New(errors.CodeForbidden, constants.AgentOpenAPIResumeOnlyMachineSeparatedMessage)
|
||||
errorCode, errorMsg := assetAuditSvc.BuildErrorInfo(denyErr)
|
||||
s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{
|
||||
OperationType: constants.AssetAuditOpCardManualStart,
|
||||
OperationDesc: "机卡分离复机被拒绝",
|
||||
ResultStatus: constants.AssetAuditResultDenied,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMsg: errorMsg,
|
||||
AssetID: card.ID,
|
||||
AssetIdentifier: card.ICCID,
|
||||
BeforeData: cardSnapshot(card),
|
||||
AfterData: map[string]any{
|
||||
"gateway_extend": gatewayExtend,
|
||||
},
|
||||
})
|
||||
return denyErr
|
||||
}
|
||||
|
||||
if err := s.resumeCardWithRetry(ctx, card); err != nil {
|
||||
wrapErr := errors.Wrap(errors.CodeGatewayError, err, "调用运营商复机失败,请稍后重试")
|
||||
errorCode, errorMsg := assetAuditSvc.BuildErrorInfo(wrapErr)
|
||||
s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{
|
||||
OperationType: constants.AssetAuditOpCardManualStart,
|
||||
OperationDesc: "机卡分离复机执行失败",
|
||||
ResultStatus: constants.AssetAuditResultFailed,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMsg: errorMsg,
|
||||
AssetID: card.ID,
|
||||
AssetIdentifier: card.ICCID,
|
||||
BeforeData: cardSnapshot(card),
|
||||
AfterData: map[string]any{
|
||||
"gateway_extend": gatewayExtend,
|
||||
},
|
||||
})
|
||||
return wrapErr
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
if err := s.iotCardStore.UpdateFields(ctx, card.ID, map[string]any{
|
||||
"network_status": constants.NetworkStatusOnline,
|
||||
"resumed_at": now,
|
||||
"stop_reason": "",
|
||||
"gateway_extend": "",
|
||||
}); err != nil {
|
||||
wrapErr := errors.Wrap(errors.CodeDatabaseError, err, "更新卡状态失败")
|
||||
errorCode, errorMsg := assetAuditSvc.BuildErrorInfo(wrapErr)
|
||||
s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{
|
||||
OperationType: constants.AssetAuditOpCardManualStart,
|
||||
OperationDesc: "机卡分离复机执行失败",
|
||||
ResultStatus: constants.AssetAuditResultFailed,
|
||||
ErrorCode: errorCode,
|
||||
ErrorMsg: errorMsg,
|
||||
AssetID: card.ID,
|
||||
AssetIdentifier: card.ICCID,
|
||||
BeforeData: map[string]any{
|
||||
"network_status": card.NetworkStatus,
|
||||
"stop_reason": card.StopReason,
|
||||
"gateway_extend": gatewayExtend,
|
||||
},
|
||||
AfterData: map[string]any{
|
||||
"network_status": constants.NetworkStatusOnline,
|
||||
"stop_reason": "",
|
||||
"gateway_extend": "",
|
||||
},
|
||||
})
|
||||
return wrapErr
|
||||
}
|
||||
|
||||
s.invalidatePollingCache(ctx, card.ID)
|
||||
s.logCardAudit(ctx, assetAuditSvc.BuildLogParams{
|
||||
OperationType: constants.AssetAuditOpCardManualStart,
|
||||
OperationDesc: "机卡分离复机",
|
||||
ResultStatus: constants.AssetAuditResultSuccess,
|
||||
AssetID: card.ID,
|
||||
AssetIdentifier: card.ICCID,
|
||||
BeforeData: map[string]any{
|
||||
"network_status": card.NetworkStatus,
|
||||
"stop_reason": card.StopReason,
|
||||
"gateway_extend": gatewayExtend,
|
||||
},
|
||||
AfterData: map[string]any{
|
||||
"network_status": constants.NetworkStatusOnline,
|
||||
"stop_reason": "",
|
||||
"gateway_extend": "",
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ManualStopCard 手动停机单张卡(通过ICCID)
|
||||
func (s *StopResumeService) ManualStopCard(ctx context.Context, iccid string) error {
|
||||
card, err := s.iotCardStore.GetByICCID(ctx, iccid)
|
||||
|
||||
Reference in New Issue
Block a user