package addpackage import ( "context" "errors" "strings" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchimport" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/excel" "git.5iot.com/iotlcm-public/iotlcm-admin-svr/internal/library/batchinput/text" "github.com/gogf/gf/v2/errors/gerror" ) const ( headerPackageCode = "加油包套餐编码" headerEffectiveMode = "生效方式" headerRemark = "备注" ) func parseExcelRows(ctx context.Context, filePath string, cfg Config, options SubmitOptions) ([]batchimport.Row, error) { parsedRows, err := excel.ParseFile(ctx, filePath, excel.ParseOptions{ RequiredHeaders: []string{cfg.TargetHeader, headerPackageCode}, SingleSheet: true, }) if err != nil { return nil, err } rows := make([]batchimport.Row, 0, len(parsedRows)) for _, parsed := range parsedRows { row := &Row{ RowNo: parsed.RowNo, TargetCode: fieldValue(parsed, targetAliases(cfg)...), PackageCode: fieldValue(parsed, headerPackageCode, "加油包编码", "packageCode", "套餐编码"), EffectiveMode: fieldValue(parsed, headerEffectiveMode, "effectiveMode", "生效模式"), Remark: fieldValue(parsed, headerRemark, "remark"), } applyDefaultOptions(row, options) rows = append(rows, row) } return rows, nil } func parseInputRows(ctx context.Context, input string, options SubmitOptions) ([]batchimport.Row, error) { lines, err := text.ParseNonEmptyLines(ctx, input) if err != nil { if errors.Is(err, text.ErrEmptyInput) { return nil, gerror.New("批量输入内容不能为空") } return nil, err } rows := make([]batchimport.Row, 0, len(lines)) for _, line := range lines { row := &Row{RowNo: line.RowNo} fields := parseInputFields(line.Text) if len(fields) != 1 { row.AddErrorReason("格式错误,应为目标编码") } else { row.TargetCode = fields[0] } applyDefaultOptions(row, options) rows = append(rows, row) } return rows, nil } func fieldValue(row excel.ParsedRow, names ...string) string { for _, name := range names { if value := strings.TrimSpace(excel.Field(row, name)); value != "" { return value } } return "" } func targetAliases(cfg Config) []string { if cfg.Operation == OperationPool { return []string{cfg.TargetHeader, "流量池编码", "流量池编号", "poolNo", "flowPoolCode", "targetCode"} } return []string{cfg.TargetHeader, "卡号", "iccid", "targetCode"} } func parseInputFields(value string) []string { value = strings.TrimSpace(value) if value == "" { return nil } if strings.Contains(value, "|") { return splitAndTrim(value, "|") } if strings.Contains(value, "\t") { return splitAndTrim(value, "\t") } return strings.Fields(value) } func splitAndTrim(value, sep string) []string { parts := strings.Split(value, sep) out := make([]string, 0, len(parts)) for _, part := range parts { out = append(out, strings.TrimSpace(part)) } return out } func applyDefaultOptions(row *Row, options SubmitOptions) { if row == nil { return } row.TargetCode = strings.TrimSpace(row.TargetCode) row.PackageCode = strings.TrimSpace(row.PackageCode) row.Remark = strings.TrimSpace(row.Remark) row.EffectiveMode = strings.TrimSpace(row.EffectiveMode) if options.PackageCode != "" { if row.PackageCode != "" && row.PackageCode != options.PackageCode { row.AddErrorReason("行内加油包编码与页面选择不一致") } row.PackageCode = options.PackageCode } if row.EffectiveMode == "" && options.EffectiveMode != "" { row.EffectiveMode = options.EffectiveMode } if row.Remark == "" { row.Remark = strings.TrimSpace(options.Remark) } } func normalizeOptions(options SubmitOptions) (SubmitOptions, error) { options.PackageCode = strings.TrimSpace(options.PackageCode) options.Remark = strings.TrimSpace(options.Remark) mode, err := NormalizeEffectiveMode(options.EffectiveMode) if err != nil { return SubmitOptions{}, err } options.EffectiveMode = mode options.PaymentMode = strings.TrimSpace(options.PaymentMode) if options.PaymentMode == "" { options.PaymentMode = "balance" } switch options.PaymentMode { case "balance": options.OfflineContractCompleted = false case "offline": if !options.OfflineContractCompleted { return SubmitOptions{}, gerror.New("请确认线下合同、销售和走账已完成") } default: return SubmitOptions{}, gerror.New("加油包付款方式不正确") } return options, nil }