【导入导出】配置保存方案

103 阅读2分钟

一、参考项目

1、项目地址

www.grapecity.com.cn/developer/s…

2、原型参考

2.1. 表单设计

image.png

2.2. 字段绑定

image.png

二、逻辑设计

1、设计器全景图

flowchart TD
    subgraph 前端设计器
        A[表单设计器UI] --> B[元数据加载器]
        A --> C[规则配置器]
        A --> D[预览生成器]
    end
    
    subgraph 后端服务
        B --> E[元数据服务]
        C --> F[配置存储服务]
        D --> G[模板生成服务]
    end
    
    subgraph 数据库
        F --> H[excel_config]
        F --> I[sheet_config]
        F --> J[column_config]
        E --> K[数据库元数据]
    end
    
    style A fill:#f9f,stroke:#333
    style E fill:#99f,stroke:#333

2、前端设计器类图

classDiagram
    class ExcelDesigner {
        +currentDesign: ExcelDesign
        +availableTables: TableMeta[]
        +loadTableMeta()
        +saveDesign()
        +generatePreview()
    }
    
    class ExcelDesign {
        +configId: String
        +sheets: SheetDesign[]
    }
    
    class SheetDesign {
        +sheetName: String
        +startRow: Integer
        +columns: ColumnMapping[]
        +validations: ValidationRule[]
    }
    
    class ColumnMapping {
        +excelCol: String
        +dbTable: String
        +dbColumn: String
        +dataType: String
        +format: String
    }
    
    class ValidationRule {
        +type: String
        +expression: String
        +errorMsg: String
    }
    
    class TableMeta {
        +tableName: String
        +columns: ColumnMeta[]
    }
    
    class ColumnMeta {
        +columnName: String
        +dataType: String
        +comment: String
    }
    
    ExcelDesigner "1" *-- "1" ExcelDesign
    ExcelDesign "1" *-- "*" SheetDesign
    SheetDesign "1" *-- "*" ColumnMapping
    SheetDesign "1" *-- "*" ValidationRule
    ExcelDesigner "1" *-- "*" TableMeta
    TableMeta "1" *-- "*" ColumnMeta

3、核心交互流程

sequenceDiagram
    participant 用户
    participant 前端设计器
    participant 元数据服务
    participant 配置存储服务
    
    用户->>前端设计器: 打开设计器
    前端设计器->>元数据服务: 获取表结构
    元数据服务-->>前端设计器: 返回数据库表列表
    用户->>前端设计器: 拖拽字段到Excel列
    用户->>前端设计器: 设置验证规则
    前端设计器->>配置存储服务: 提交配置数据
    配置存储服务-->>前端设计器: 返回保存结果
    用户->>前端设计器: 预览模板
    前端设计器->>配置存储服务: 获取配置
    配置存储服务-->>前端设计器: 返回配置详情

4、通用导入导出规则验证流程

flowchart TD
    A[开始] --> B{校验文件类型}
    B -->|通过| C{校验文件大小}
    B -->|失败| Z[返回错误]
    C -->|通过| D{校验Sheet结构}
    C -->|失败| Z
    D -->|通过| E{校验单元格格式}
    D -->|失败| Z
    E -->|通过| F{校验业务规则}
    E -->|失败| Z
    F -->|通过| G[执行导入/导出]
    F -->|失败| Z
    G --> H[结束]

5、数据库ER图

erDiagram
    excel_config ||--o{ sheet_config : "1:n"
    sheet_config ||--o{ column_config : "1:n"
    excel_config ||--o{ export_column_config : "1:n"
    excel_config ||--o{ export_condition : "1:n"
    sheet_config ||--o{ import_validation : "1:n"
    
    excel_config {
        BIGINT config_id PK
        VARCHAR(50) business_key
        BOOLEAN template_mode
        BOOLEAN import_mode
        BOOLEAN export_mode
        VARCHAR(20) sheet_strategy
    }
    
    sheet_config {
        BIGINT sheet_id PK
        BIGINT config_id FK
        VARCHAR(100) sheet_pattern
        INTEGER start_row
        VARCHAR(100) target_table
    }
    
    column_config {
        BIGINT column_id PK
        BIGINT sheet_id FK
        VARCHAR(5) excel_col
        VARCHAR(100) db_column
        VARCHAR(20) data_type
        VARCHAR(100) format_pattern
    }
    
    export_column_config {
        BIGINT export_id PK
        BIGINT config_id FK
        VARCHAR(100) db_column
        VARCHAR(100) excel_header
        INTEGER display_order
        VARCHAR(100) format_pattern
    }
    
    import_validation {
        BIGINT validation_id PK
        BIGINT sheet_id FK
        VARCHAR(20) rule_type
        TEXT rule_expression
        VARCHAR(255) error_message
    }
    
    export_condition {
        BIGINT condition_id PK
        BIGINT config_id FK
        VARCHAR(50) param_name
        VARCHAR(20) data_type
        BOOLEAN required
    }```

### 6、设计器操作流程图

```mermaid
flowchart TB
    subgraph 设计器操作流程
        A[选择数据库表] --> B[拖拽字段到Excel列]
        B --> C[设置单元格格式]
        C --> D[添加验证规则]
        D --> E{点击保存}
        E -->|是| F[存储配置到数据库]
        E -->|否| G[返回编辑界面]
        F --> H[生成配置预览]
    end

7、版本控制流程

sequenceDiagram
    participant 用户
    participant 前端设计器
    participant 版本服务
    
    用户->>前端设计器: 点击保存
    前端设计器->>版本服务: 生成版本快照
    版本服务-->>前端设计器: 返回版本ID
    用户->>前端设计器: 查看历史版本
    前端设计器->>版本服务: 获取版本列表
    版本服务-->>前端设计器: 返回版本数据
    用户->>前端设计器: 选择恢复版本
    前端设计器->>版本服务: 应用历史版本
    版本服务-->>前端设计器: 返回恢复结果

三、核心逻辑

1、后端接口设计

1.1. 元数据查询接口

 @RestController
 @RequestMapping("/api/meta")
 public class MetaController {
     
     @GetMapping("/tables")
     public List<TableMeta> listTables() {
         return jdbcTemplate.query("""
             SELECT table_name, table_comment 
             FROM information_schema.tables 
             WHERE table_schema = 'public'
             """, new TableMetaMapper());
     }
     
     @GetMapping("/columns/{table}")
     public List<ColumnMeta> listColumns(@PathVariable String table) {
         return jdbcTemplate.query("""
             SELECT column_name, data_type, column_comment
             FROM information_schema.columns
             WHERE table_name = ?
             """, new ColumnMetaMapper(), table);
     }
 }

1.2. 配置存储接口

@PostMapping("/config/save")
public ResponseEntity<?> saveDesign(@RequestBody ExcelDesignDTO dto) {
    return transactionTemplate.execute(status -> {
        // 保存主配置
        ExcelConfig config = new ExcelConfig();
        config.setBusinessKey(dto.getBusinessKey());
        excelConfigRepo.save(config);
        
        // 保存Sheet配置
        dto.getSheets().forEach(sheet -> {
            SheetConfig sheetConfig = new SheetConfig();
            sheetConfig.setConfigId(config.getId());
            sheetConfigRepo.save(sheetConfig);
            
            // 保存列映射
            sheet.getColumns().forEach(col -> {
                ColumnConfig colConfig = new ColumnConfig();
                colConfig.setSheetId(sheetConfig.getId());
                colConfig.setDbColumn(col.getDbColumn());
                columnConfigRepo.save(colConfig);
            });
        });
        
        return ResponseEntity.ok().build();
    });
}

2、前端设计器核心功能实现

2.1. 可视化布局设计

function ExcelDesigner() {
  const [tables, setTables] = useState([]);
  const [design, setDesign] = useState({
    sheets: [{
      name: 'Sheet1',
      startRow: 2,
      columns: []
    }]
  });

  // 加载元数据
  useEffect(() => {
    fetch('/api/meta/tables')
      .then(res => res.json())
      .then(setTables);
  }, []);

  // 拖拽处理
  const onDrop = (result) => {
    const { source, destination } = result;
    if (source.droppableId === 'tables' && destination.droppableId === 'sheet') {
      const column = tables
        .find(t => t.name === source.table)
        .columns.find(c => c.name === source.id);
      
      setDesign(prev => ({
        ...prev,
        sheets: prev.sheets.map(sheet => 
          sheet.id === destination.sheetId
            ? { ...sheet, columns: [...sheet.columns, column] }
            : sheet
        )
      }));
    }
  };

  return (
    <DragDropContext onDragEnd={onDrop}>
      <div className="designer-layout">
        <DatabasePanel tables={tables} />
        <ExcelPreview design={design} />
        <ValidationConfigPanel />
      </div>
    </DragDropContext>
  );
}

2.2. 字段映射配置组件

function ColumnMapping({ column, onUpdate }) {
  return (
    <div className="mapping-item">
      <label>Excel列:</label>
      <input 
        value={column.excelCol}
        onChange={e => onUpdate({ excelCol: e.target.value })}
      />
      
      <label>数据库字段:</label>
      <select
        value={column.dbColumn}
        onChange={e => onUpdate({ dbColumn: e.target.value })}
      >
        {column.availableColumns.map(col => (
          <option key={col.name} value={col.name}>
            {col.name} ({col.type})
          </option>
        ))}
      </select>
    </div>
  );
}

3、与现有系统的集成设计

3.1. 数据库表结构变更侦听

@Component
public class SchemaChangeListener {
    
    @EventListener
    public void handleSchemaChange(DataSourceEvent event) {
        if (event.getType() == EventType.TABLE_ALTER) {
            configService.markConfigDirty(event.getTableName());
        }
    }
    
    @Scheduled(fixedDelay = 3600000)
    public void refreshMetadataCache() {
        metaService.refreshCache();
    }
}

3.2. 配置版本控制实现

-- 新增历史版本表
CREATE TABLE config_history (
  id BIGSERIAL PRIMARY KEY,
  config_id BIGINT REFERENCES excel_config(config_id),
  config_data JSONB NOT NULL,
  created_by VARCHAR(50),
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 快速回滚查询
SELECT *
FROM config_history
WHERE config_id = 123
ORDER BY created_at DESC
LIMIT 5;

4、测试方案

4.1. 功能测试用例

测试场景测试步骤预期结果
字段映射1. 拖拽字段到Excel列 2. 设置格式规则Excel与数据库字段正确关联
验证规则添加正则表达式验证导入时触发规则校验
版本恢复回滚到历史版本配置恢复至指定版本状态

4.2. 压力测试指标

测试类型指标合格标准
元数据查询500并发请求平均响应 < 800ms
配置保存1MB配置数据提交存储时间 < 1s
设计器渲染1000字段加载页面加载 < 3s

4.3. 安全测试项

测试XSS注入:

```java

const testPayload = "<script>alert('xss')</script>";
await saveConfig({ comment: testPayload });

```

SQL注入测试:

```java
 String tableName = "users; DROP TABLE excel_config;";
 metaService.getColumns(tableName);
```