package unsub import ( "context" "strings" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/service/batchresult" "git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/service/packagecustomer" ) const ( cascadeFailureReason = "same batch has invalid unsubscribe rows; this row was skipped" validationSkipReason = "batch validation failed; unsub request was skipped" emptyICCIDReason = "ICCID cannot be empty" duplicateICCIDReason = "duplicate ICCID in batch" ) type executor struct { repository Repository } func NewExecutor(repository Repository) Executor { return &executor{repository: repository} } func (e *executor) Execute(ctx context.Context, batchNo string) error { task, err := e.repository.Load(ctx, strings.TrimSpace(batchNo)) if err != nil { return gerror.Wrap(err, "load unsub batch failed") } if !validateTask(task) { if err = e.repository.SaveValidationFailure(ctx, task); err != nil { return gerror.Wrap(err, "save unsub validation failure failed") } e.saveResultFile(ctx, task) return nil } if err = e.repository.CommitBusiness(ctx, task); err != nil { return gerror.Wrap(err, "commit unsub business failed") } packagecustomer.PublishSyncForDeptsSafe(ctx, task.Batch.TenantID, task.Batch.CreatedBy, unsubPackageSyncDeptIDs(task), "unsub", task.Batch.BatchNo) e.saveResultFile(ctx, task) return nil } func unsubPackageSyncDeptIDs(task *Task) []int64 { if task == nil { return nil } deptIds := []int64{task.Batch.DeptID, task.Batch.CreatedDept} for _, detail := range task.Details { if detail == nil || strings.TrimSpace(detail.Reason) != "" { continue } if detail.CardDeptID > 0 { deptIds = append(deptIds, detail.CardDeptID) } } return deptIds } func (e *executor) saveResultFile(ctx context.Context, task *Task) { request := batchresult.Request{ BatchNo: task.Batch.BatchNo, BatchType: task.Batch.BatchType, TenantID: task.Batch.TenantID, Rows: task.ResultRows(), } if err := e.repository.SaveResultFile(ctx, task, request); err != nil { g.Log().Errorf(ctx, "save unsub result file status failed, batchNo:%s, err:%+v", task.Batch.BatchNo, err) } } func validateTask(task *Task) bool { if task == nil || len(task.Details) == 0 { if task != nil { task.FailureReason = "unsub batch has no valid details" } return false } hasFailure := false iccids := make(map[string]int, len(task.Details)) for _, detail := range task.Details { if detail == nil { hasFailure = true continue } if detail.Reason != "" { hasFailure = true continue } iccid := strings.TrimSpace(detail.ICCID) if iccid == "" { detail.Reason = emptyICCIDReason hasFailure = true continue } iccids[iccid]++ } for _, detail := range task.Details { if detail == nil { continue } if detail.Reason != "" { continue } if iccids[strings.TrimSpace(detail.ICCID)] > 1 { detail.Reason = duplicateICCIDReason hasFailure = true } } if !hasFailure { return true } for _, detail := range task.Details { if detail != nil && detail.Reason == "" { detail.Reason = cascadeFailureReason } } task.FailureReason = validationSkipReason return false }