package change import ( "context" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/excel" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/model" ) type ExcelSubmitOptions struct { NewPackageCode string DurationMonths int GiftDurationMonths int EffectiveMode string OfflineContractCompleted bool } func ExcelTemplateHeaders() []string { return []string{ "ICCID", "MSISDN", "IMSI", "newPackageCode", "durationMonths", "giftDurationMonths", "effectiveMode", "offlineContractCompleted", } } func (o *ExcelSubmitOptions) ToBatchSubmitParam() *model.TSimCardChangeBatchSubmitParam { if o == nil { return &model.TSimCardChangeBatchSubmitParam{} } return &model.TSimCardChangeBatchSubmitParam{ NewPackageCode: strings.TrimSpace(o.NewPackageCode), DurationMonths: o.DurationMonths, GiftDurationMonths: o.GiftDurationMonths, EffectiveMode: strings.TrimSpace(o.EffectiveMode), OfflineContractCompleted: o.OfflineContractCompleted, } } func (o *ExcelSubmitOptions) ToBatchSubmitParamWithBatchNo(batchNo string) *model.TSimCardChangeBatchSubmitParam { param := o.ToBatchSubmitParam() param.BatchNo = strings.TrimSpace(batchNo) return param } func ParseExcelFileRows(ctx context.Context, filePath string) ([]*Row, *ExcelSubmitOptions, error) { parsedRows, err := excel.ParseFile(ctx, filePath, excel.ParseOptions{ RequiredHeaders: ExcelTemplateHeaders(), SingleSheet: true, }) if err != nil { return nil, nil, err } rows := make([]*Row, 0, len(parsedRows)) var options *ExcelSubmitOptions inconsistent := false for _, parsed := range parsedRows { row := &Row{ RowNo: parsed.RowNo, Iccid: excel.Field(parsed, "ICCID"), Msisdn: excel.Field(parsed, "MSISDN"), Imsi: excel.Field(parsed, "IMSI"), RawFields: map[string]string{ "ICCID": excel.Field(parsed, "ICCID"), "MSISDN": excel.Field(parsed, "MSISDN"), "IMSI": excel.Field(parsed, "IMSI"), "newPackageCode": excel.Field(parsed, "newPackageCode"), "durationMonths": excel.Field(parsed, "durationMonths"), "giftDurationMonths": excel.Field(parsed, "giftDurationMonths"), "effectiveMode": excel.Field(parsed, "effectiveMode"), "offlineContractCompleted": excel.Field(parsed, "offlineContractCompleted"), }, } rowOptions, reasons := parseExcelSubmitOptions(parsed) if len(reasons) > 0 { row.AddReason(strings.Join(reasons, "; ")) rows = append(rows, row) continue } row.NewPackageCode = rowOptions.NewPackageCode row.DurationMonths = rowOptions.DurationMonths row.GiftDurationMonths = rowOptions.GiftDurationMonths row.EffectiveMode = rowOptions.EffectiveMode row.OfflineContractCompleted = rowOptions.OfflineContractCompleted if options == nil { options = rowOptions } else if !sameExcelSubmitOptions(options, rowOptions) { row.AddReason("same excel batch change params must be consistent") inconsistent = true } rows = append(rows, row) } if inconsistent { markRowsWithoutReason(rows, "same excel batch change params must be consistent") } return rows, options, nil } func parseExcelSubmitOptions(row excel.ParsedRow) (*ExcelSubmitOptions, []string) { var reasons []string newPackageCode := strings.TrimSpace(excel.Field(row, "newPackageCode")) if newPackageCode == "" { reasons = append(reasons, "newPackageCode is required") } durationMonths, err := excel.ParsePositiveInt(excel.Field(row, "durationMonths")) if err != nil { reasons = append(reasons, "durationMonths must be a positive integer") } giftDurationValue := strings.TrimSpace(excel.Field(row, "giftDurationMonths")) giftDurationMonths := 0 if giftDurationValue != "" { giftDurationMonths, err = excel.ParseNonNegativeInt(giftDurationValue) if err != nil { reasons = append(reasons, "giftDurationMonths must be a non-negative integer") } } effectiveMode := strings.TrimSpace(excel.Field(row, "effectiveMode")) if effectiveMode == "" { reasons = append(reasons, "effectiveMode is required") } offlineContractCompleted, err := excel.ParseBool(excel.Field(row, "offlineContractCompleted")) if err != nil { reasons = append(reasons, "offlineContractCompleted format is invalid") } else if !offlineContractCompleted { reasons = append(reasons, "offlineContractCompleted must be true") } if len(reasons) > 0 { return nil, reasons } return &ExcelSubmitOptions{ NewPackageCode: newPackageCode, DurationMonths: durationMonths, GiftDurationMonths: giftDurationMonths, EffectiveMode: effectiveMode, OfflineContractCompleted: offlineContractCompleted, }, nil } func sameExcelSubmitOptions(left, right *ExcelSubmitOptions) bool { if left == nil || right == nil { return false } return strings.TrimSpace(left.NewPackageCode) == strings.TrimSpace(right.NewPackageCode) && left.DurationMonths == right.DurationMonths && left.GiftDurationMonths == right.GiftDurationMonths && strings.TrimSpace(left.EffectiveMode) == strings.TrimSpace(right.EffectiveMode) && left.OfflineContractCompleted == right.OfflineContractCompleted }