package trafficcutoff import ( "context" "fmt" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/consts" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/dao" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchimport" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchmetadata" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/simcardbatch/common" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/logic/iot/simcardbatch/dataswitch" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model/do" "time" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gtime" ) func submitCutoffBatch(ctx context.Context, key cutoffBatchGroupKey, items []lockedCutoffCard, runTime time.Time) (*batchimport.Result, error) { if len(items) == 0 { return nil, nil } processor, err := dataswitch.NewProcessor(dataswitch.OperationDataCut) if err != nil { return nil, err } rows := make([]batchimport.Row, 0, len(items)) for index, item := range items { rows = append(rows, cutoffDataSwitchRow(index+1, item.Card, runTime)) } req := batchimport.SubmitRequest{ SourceChannel: batchmetadata.System, ExecutionMode: batchmetadata.Bulk, BizParams: &common.SubmitOptions{Remark: fmt.Sprintf("达量断网自动触发,触发卡数:%d", len(rows))}, SourceType: consts.BatchSourceTypeScheduled, Operator: batchimport.OperatorContext{ TenantId: key.TenantId, DeptId: key.CreatedDept, UserId: key.CreatedBy, }, } result, err := batchimport.CreatePendingRows(ctx, req, processor, rows, batchimport.PendingOptions{}) if err != nil { return nil, err } if err = common.PublishBatchMessageStrict(ctx, result, consts.QueueBatchExecute, "traffic_cutoff"); err != nil { if markErr := markCutoffBatchPublishFailed(ctx, result, err); markErr != nil { return nil, gerror.Wrapf(markErr, "publish cutoff batch failed: %v", err) } return nil, err } return result, nil } func markCutoffBatchPublishFailed(ctx context.Context, result *batchimport.Result, publishErr error) error { if result == nil || result.BatchNo == "" { return nil } reason := "publish batch message failed" if publishErr != nil { reason += ": " + publishErr.Error() } return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error { if _, err := tx.Ctx(ctx).Model(dao.BatchMain.Table()). Where(dao.BatchMain.Columns().BatchNo, result.BatchNo). Where(dao.BatchMain.Columns().BatchAsyncStatus, consts.BatchAsyncStatusPending). Data(do.BatchMain{ BatchAsyncStatus: consts.BatchAsyncStatusFailed, RunResult: consts.BatchRunResultFailed, FailReason: reason, EndTime: gtime.Now(), }).Update(); err != nil { return gerror.Wrap(err, "mark cutoff batch publish failure") } if _, err := tx.Ctx(ctx).Model(dao.BatchDetail.Table()). Where(dao.BatchDetail.Columns().BatchNo, result.BatchNo). Where(dao.BatchDetail.Columns().DetailStatus, consts.BatchDetailStatusPending). Data(do.BatchDetail{ DetailStatus: consts.BatchDetailStatusFailed, ErrorReason: reason, }).Update(); err != nil { return gerror.Wrap(err, "mark cutoff batch detail publish failure") } return nil }) } func cutoffDataSwitchRow(rowNo int, card cutoffCard, runTime time.Time) *dataswitch.Row { triggerReason := "达量断网:已用流量达到配置阈值,系统自动停用数据服务" if card.isCrossMonthHoldReapply() { triggerReason = "达量断网:跨月保持断网,系统重新停用已恢复的数据服务" } return &dataswitch.Row{ RowNo: rowNo, Iccid: card.Iccid, Msisdn: card.Msisdn, Imsi: card.Imsi, Authorized: true, CardID: card.Id, CutoffThreshold: roundCutoffFlow(card.TrafficCutoffThreshold), UsedFlowMb: roundCutoffFlow(card.UsedFlowMb), PackageTotalFlowMb: roundCutoffFlow(cutoffTotalFlowMb(card)), RemainFlowMb: roundCutoffFlow(cutoffRemainFlowMb(card)), DataServiceStatusBefore: card.DataServiceStatus, TrafficCutoffCrossMonthHold: card.TrafficCutoffCrossMonthHold, TriggeredAt: runTime.Format("2006-01-02 15:04:05"), TriggerReason: triggerReason, } }