轻量化数据处理中间件 | RPA数据上传 → 本平台 → BI报表数据
  
报表数据处理平台是一个轻量化的数据处理中间件,作为RPA机器人数据上传和BI报表之间的中间处理环节。
┌─────────┐ ┌─────────┐ ┌───────────────┐ ┌─────────┐
│ RPA机器人 │ → │ FTP服务器 │ → │ 报表数据处理平台 │ → │ BI报表系统 │
└─────────┘ └─────────┘ └───────────────┘ └─────────┘
↑
本项目填补这个环节
痛点场景:
- RPA机器人抓取数据后上传到FTP
- BI系统需要标准化的数据库数据
- FTP中的Excel文件无法直接被BI系统使用
本平台价值:
- ✅ 自动监听FTP指定文件夹
- ✅ 读取并解析Excel文件
- ✅ 数据清洗和格式转换
- ✅ 生成BI报表可用的数据表
- ✅ 历史数据版本化管理
| 功能 | 说明 |
|---|---|
| FTP配置管理 | 管理多个外部FTP服务器连接 |
| 报表配置管理 | 配置报表模板、列映射、数据清洗规则 |
| 任务调度 | Quartz定时扫描FTP目录 |
| 手动触发 | 支持手动触发任务执行 |
| 数据清洗 | 支持值替换、空值处理等清洗规则 |
| 列映射JSON导入 | 批量导入列映射配置 |
| 任务监控 | 实时查看任务执行状态和进度 |
| 操作日志 | 记录所有操作便于追溯 |
| 内置FTP服务 | 内嵌FTP服务器,支持RPA直接上传 |
| 去重机制 | 避免重复处理相同文件 |
┌─────────────────────────────────────────────────────────────────┐
│ 报表数据处理平台 │
├─────────────────────────────────────────────────────────────────┤
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 前端 (Vue) │ │ 后端 (Spring Boot) │ │
│ │ ┌───────────┐ │ HTTP │ ┌─────────────┐ │ │
│ │ │FTP配置页面│ │ ←───────→ │ │FtpConfigController│ │
│ │ │报表配置页面│ │ │ │ReportConfigController│ │
│ │ │任务监控页面│ │ │ │TaskController │ │
│ │ │日志列表页面│ │ │ │BuiltInFtpConfigController│ │
│ │ └───────────┘ │ │ └─────────────┘ │ │
│ └─────────────────┘ └────────┬──────────┘ │
│ │ │
│ ┌───────────────────────────────────────▼───────────────────┐ │
│ │ 服务层 (Service) │ │
│ │ ┌────────────┐ ┌────────────┐ ┌────────────────┐ │ │
│ │ │FtpConfigService│ │ReportConfigService│ │TaskService │ │ │
│ │ │BuiltInFtpConfigService│ │DataProcessService│ │ │ │
│ │ └────────────┘ └────────────┘ └────────────────┘ │ │
│ └───────────────────────────────────────┬─────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────▼───────────────────┐ │
│ │ 数据层 (MyBatis-Plus) │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────────────┐ │ │
│ │ │FtpConfig│ │ReportConfig│ │TaskExecution│ │BuiltInFtpConfig│ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────────────┘ │ │
│ └───────────────────────────────────────┬─────────────────┘ │
│ │ │
│ ┌───────────────────────────────────────▼───────────────────┐ │
│ │ 任务调度 (Quartz) │ │
│ │ ┌────────────────┐ ┌─────────────────┐ │ │
│ │ │ FtpScanJob │ │ EmbeddedFtpServer │ │ │
│ │ │ 扫描外部FTP │ │ 内置FTP服务器 │ │ │
│ │ └────────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓ ↓
┌──────────────┐ ┌──────────────┐
│ MySQL数据库 │ │ FTP服务器 │
│ - ftp_config │ │ (外部FTP) │
│ - report_config│ └──────────────┘
│ - task_execution│
│ - built_in_ftp_config│
└──────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ 数据处理流程 │
└─────────────────────────────────────────────────────────────────────┘
1. FTP扫描
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ FTP目录 │ → │ FtpScanJob │ → │ 匹配文件名 │
│ /data/ │ │ 定时扫描 │ │ *.xlsx │
└──────────┘ └──────────────┘ └──────┬───────┘
↓
2. 文件处理
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 下载文件 │ → │ DataProcessJob │ → │ 解析Excel │
│ │ │ │ │ │
└──────────┘ └──────┬───────┘ └──────┬───────┘
↓
3. 数据清洗
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 列映射 │ → │ 数据类型转换 │ → │ 值替换清洗 │
│ A→order_id│ │ STRING/INTEGER│ │ '-' → '0' │
└──────────┘ └──────────────┘ └──────┬───────┘
↓
4. 数据入库
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 目标表 │ ← │ TableCreator │ ← │ INSERT数据 │
│ t_sales │ │ 自动建表 │ │ │
└──────────┘ └──────────────┘ └──────────────┘
↓
┌──────────────┐
│ 历史版本字段 │
│ pt_dt (分区) │
└──────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ 内置FTP服务架构 │
└─────────────────────────────────────────────────────────────────┘
┌─────────────┐ ┌──────────────────────────────────┐
│ RPA机器人 │ FTP │ EmbeddedFtpServer │
│ │ ──────→ │ ┌────────────────────────────┐ │
│ 客户端 │ │ │ Apache FtpServer 1.2.0 │ │
└─────────────┘ │ │ 被动模式 / 主动模式 │ │
│ └────────────┬───────────────┘ │
│ │ │
│ ┌────────────▼───────────────┐ │
│ │ BuiltInFtpConfig │ │
│ │ - 用户名: rpa_user │ │
│ │ - 密码: rpa_password │ │
│ │ - 端口: 2021 │ │
│ │ - 根目录: /data/ftp-root │ │
│ └────────────┬───────────────┘ │
└───────────────┼───────────────────┘
↓
┌────────────────┐
│ 本地文件系统 │
│ /data/ftp-root│
│ └── upload/ │
│ ├── *.xlsx│
│ └── *.xls │
└────────────────┘
| 技术 | 版本 | 说明 |
|---|---|---|
| Spring Boot | 2.1.2 | 应用框架 |
| MyBatis-Plus | 3.4.3 | ORM框架 |
| Apache FtpServer | 1.2.0 | 内置FTP服务 |
| Quartz | JDBC集群模式 | 任务调度 |
| Druid | 1.1.20 | 数据库连接池 |
| Apache POI | 4.1.2 | Excel解析 |
| Hutool | 5.8.25 | 工具库 |
| commons-net | 3.9.0 | FTP客户端 |
| JDK | 1.8 | Java运行时 |
| 技术 | 版本 | 说明 |
|---|---|---|
| Vue.js | 2.6 | 前端框架 |
| Vue Router | 3.x | 路由管理 |
| Vuex | 3.x | 状态管理 |
| Element UI | 2.x | UI组件库 |
| Axios | 0.21 | HTTP客户端 |
| 技术 | 版本 | 说明 |
|---|---|---|
| MySQL | 5.7+ | 关系数据库 |
- JDK 1.8+
- Node.js 14+ (前端开发)
- MySQL 5.7+
- Maven 3.6+
git clone https://github.com/ASSIN1024/report-front.git
cd report-front创建MySQL数据库:
CREATE DATABASE report_db DEFAULT CHARACTER SET utf8mb4;修改 report-backend/src/main/resources/application.yml:
spring:
datasource:
url: jdbc:mysql://localhost:3306/report_db?useUnicode=true&characterEncoding=utf-8
username: your_username
password: your_passwordmysql -u root -p report_db < report-backend/src/main/resources/schema.sqlcd report-backend
./mvnw spring-boot:run
# 或使用脚本
cd ../scripts && ./start.sh backend后端启动后运行在 http://localhost:8082
cd src
npm install
npm run serve前端启动后访问 http://localhost:8080
访问 http://localhost:8080,使用默认账号登录,查看系统是否正常运行。
编辑 application.yml 或创建 application-prod.yml:
spring:
profiles:
active: prod
datasource:
url: jdbc:mysql://生产数据库地址:3306/report_db
username: 生产用户名
password: 生产密码cd report-backend
mvn clean package -DskipTests生成的JAR包:target/report-backend-1.0.0.jar
java -jar target/report-backend-1.0.0.jar --spring.profiles.active=prodmkdir -p /data/ftp-root/upload
chmod 755 /data/ftp-rootcd src
npm run build生成的文件在 src/dist 目录
server {
listen 80;
server_name your-domain.com;
location / {
root /path/to/dist;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:8082;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}进入 FTP配置 页面,点击 新增配置:
| 字段 | 说明 | 示例 |
|---|---|---|
| 配置名称 | 标识名称 | 测试FTP |
| FTP地址 | 服务器IP | 192.168.1.100 |
| 端口 | FTP端口 | 21 |
| 用户名 | FTP用户名 | ftpuser |
| 密码 | FTP密码 | ftppass |
| 扫描路径 | 监控目录 | /data/reports |
| 文件匹配 | 文件名模式 | *.xlsx |
| 扫描间隔 | 扫描频率(秒) | 300 |
进入 报表配置 页面,点击 新增报表:
| 字段 | 说明 |
|---|---|
| 报表编码 | 唯一标识代码 |
| 报表名称 | 显示名称 |
| 关联FTP | 关联的FTP配置 |
| 文件匹配 | 匹配模式 |
| Sheet索引 | Excel Sheet序号 |
| 表头行 | 表头所在行 |
| 数据起始行 | 数据开始行 |
| 列映射 | 列与字段映射 |
| 输出表名 | 目标数据库表 |
| 输出模式 | 追加/覆盖 |
点击 列映射配置,设置Excel列与数据库字段的对应关系:
[
{"excelColumn": "A", "fieldName": "order_id", "fieldType": "STRING"},
{"excelColumn": "B", "fieldName": "product_name", "fieldType": "STRING"},
{"excelColumn": "C", "fieldName": "quantity", "fieldType": "INTEGER"},
{"excelColumn": "D", "fieldName": "amount", "fieldType": "DECIMAL"},
{"excelColumn": "E", "fieldName": "order_date", "fieldType": "DATE"}
]支持JSON导入,点击 导入JSON 按钮粘贴配置。
在列映射中可以配置清洗规则:
| 规则类型 | 示例 | 说明 |
|---|---|---|
| 值替换 | - → 0 |
将特定值替换 |
| 空值处理 | NULL → "" |
处理空值 |
| 去空格 | trim | 去除首尾空格 |
在 报表配置列表,点击对应报表的 立即扫描 按钮:
- 系统先检查FTP指定目录
- 匹配文件名模式的文件会被下载
- 解析Excel并进行数据清洗
- 写入目标数据库表
- 完成后可在任务监控查看结果
进入 任务监控 页面:
- 查看所有任务的执行状态
- 点击任务查看详细日志
- 支持按状态、时间筛选
进入 数据中心 页面,可以查看和管理所有业务数据表。
系统采用分层架构管理数据表:
| 分层 | 前缀 | 说明 |
|---|---|---|
| 原始数据层 | ods_ |
来自源系统的原始数据 |
| 明细数据层 | dwd_ |
标准化的明细数据 |
| 汇总数据层 | dws_ |
轻度汇总数据 |
| 应用数据层 | ads_ |
最终应用数据 |
| 维度表层 | dim_ |
维度表 |
| 中间数据层 | mid_ |
各层级之间的过渡/中间表 |
| 临时数据层 | tmp_ |
临时计算,用完即删 |
系统表统一使用 sys_ 前缀:
sys_ftp_config
sys_trigger_config
sys_task_execution
sys_operation_log
注意:系统表不纳入数据资产管理范围。
{分层前缀}_{业务域}_{主题}_{版本?}
示例:
ods_sales_202401 # 销售原始数据 2024年1月
dwd_customer_base # 客户明细基础表
dws_sales_daily # 销售每日汇总
ads_finance_monthly # 财务月度报表
dim_product # 产品维度表
mid_sales_clean # 销售数据清洗中间表
tmp_monthly_calc # 月度计算临时表
- 全小写,单词间用下划线分隔
- 不超过 50 字符
- 避免缩写
- ✅
amount,count,customer - ❌
amt,cnt,cust
- ✅
- 版本号用
_v1,_v2后缀 - 日期分区用
_YYYYMMDD后缀
| 前缀 | 用途 |
|---|---|
mid_ |
各层级之间的过渡/中间表,保留周期中等 |
tmp_ |
临时计算,用完即删 |
| 原表名 | 建议新名称 | 问题 |
|---|---|---|
osd_sales |
ods_sales |
拼写错误 |
osd_nanping |
ods_nanping |
拼写错误 |
layer_1_sales |
dws_sales_summary_v1 |
不规范前缀 |
layer_2_summary |
dws_summary_layer2 |
不规范前缀 |
t_sales_data |
ods_sales_data |
缺少分层前缀 |
t_customer_info |
dim_customer_info |
缺少分层前缀 |
数据中心模块扫描业务表时,只扫描以下前缀的表:
AND (
TABLE_NAME LIKE 'ods_%' OR
TABLE_NAME LIKE 'dwd_%' OR
TABLE_NAME LIKE 'dws_%' OR
TABLE_NAME LIKE 'ads_%' OR
TABLE_NAME LIKE 'dim_%' OR
TABLE_NAME LIKE 'mid_%' OR
TABLE_NAME LIKE 'tmp_%'
)本系统采用 Quartz JDBC 集群模式,支持多实例部署且任务不会重复执行。
| 特性 | 说明 |
|---|---|
| 集群模式 | isClustered: true |
| 集群心跳 | 20秒 |
| Misfire阈值 | 60秒 |
| 实例ID | 自动生成 (hostname-pid) |
| 并发控制 | @DisallowConcurrentExecution |
| 环境 | 配置文件 | 数据库 | 说明 |
|---|---|---|---|
| 开发 | application-dev.yml |
MySQL | 本地开发环境 |
| 生产 | application-prod.yml |
GaussDB | 内网生产环境 |
- 添加 GaussDB 驱动依赖:
<dependency>
<groupId>org.opengauss</groupId>
<artifactId>opengauss-jdbc</artifactId>
<version>5.0.0</version>
</dependency>- 配置环境变量:
export GAUSSDB_HOST=your-gaussdb-host
export GAUSSDB_PORT=5432
export GAUSSDB_DB=report_db
export GAUSSDB_USER=report_user
export GAUSSDB_PASSWORD=your-password- 启动生产环境:
java -jar report-backend-1.0.0.jar --spring.profiles.active=prod首次启动时会自动创建以下 Quartz 集群表:
| 表名 | 说明 |
|---|---|
QRTZ_JOB_DETAILS |
任务详情 |
QRTZ_TRIGGERS |
触发器 |
QRTZ_SIMPLE_TRIGGERS |
简单触发器 |
QRTZ_FIRED_TRIGGERS |
正在执行的触发器 |
QRTZ_SCHEDULER_STATE |
调度器状态 |
QRTZ_LOCKS |
分布式锁 |
| ... | (共11张表) |
通过页面配置,存储在 ftp_config 表:
| 配置项 | 说明 | 默认值 |
|---|---|---|
| enabled | 是否启用 | true |
| host | FTP服务器地址 | - |
| port | 端口 | 21 |
| username | 用户名 | - |
| password | 密码(加密存储) | - |
| scanPath | 扫描路径 | / |
| filePattern | 文件匹配模式 | *.xlsx |
| scanInterval | 扫描间隔(秒) | 300 |
通过页面配置或 built_in_ftp_config 表:
| 配置项 | 说明 | 默认值 |
|---|---|---|
| enabled | 是否启用 | false |
| port | 监听端口 | 2021 |
| username | 用户名 | rpa_user |
| password | 密码 | rpa_password |
| rootDirectory | 根目录 | /data/ftp-root |
| maxConnections | 最大连接数 | 10 |
| idleTimeout | 空闲超时(秒) | 300 |
| passiveMode | 被动模式 | true |
| passivePortStart | 被动端口起始 | 50000 |
| passivePortEnd | 被动端口结束 | 50100 |
存储在 report_config 表:
| 配置项 | 说明 |
|---|---|
| reportCode | 报表唯一编码 |
| reportName | 报表名称 |
| ftpConfigId | 关联的FTP配置ID |
| filePattern | 文件名匹配模式 |
| sheetIndex | Excel Sheet索引 |
| headerRow | 表头行号 |
| dataStartRow | 数据起始行 |
| columnMapping | 列映射JSON |
| outputTable | 输出表名 |
| outputMode | APPEND/OVERWRITE |
| 接口 | 方法 | 说明 |
|---|---|---|
/api/ftp-config/page |
GET | 分页查询FTP配置 |
/api/ftp-config/{id} |
GET | 获取配置详情 |
/api/ftp-config |
POST | 新增FTP配置 |
/api/ftp-config |
PUT | 更新FTP配置 |
/api/ftp-config/{id} |
DELETE | 删除FTP配置 |
/api/ftp-config/{id}/test |
POST | 测试连接 |
| 接口 | 方法 | 说明 |
|---|---|---|
/api/report-config/page |
GET | 分页查询报表配置 |
/api/report-config/{id} |
GET | 获取报表详情 |
/api/report-config |
POST | 新增报表配置 |
/api/report-config |
PUT | 更新报表配置 |
/api/report-config/{id} |
DELETE | 删除报表配置 |
/api/report-config/{id}/trigger |
POST | 手动触发任务 |
| 接口 | 方法 | 说明 |
|---|---|---|
/api/task/page |
GET | 分页查询任务 |
/api/task/{id} |
GET | 获取任务详情 |
/api/task/{id}/logs |
GET | 获取任务日志 |
| 接口 | 方法 | 说明 |
|---|---|---|
/api/built-in-ftp/config |
GET | 获取内置FTP配置 |
/api/built-in-ftp/config |
PUT | 更新内置FTP配置 |
/api/built-in-ftp/start |
POST | 启动内置FTP服务 |
/api/built-in-ftp/stop |
POST | 停止内置FTP服务 |
/api/built-in-ftp/status |
GET | 获取服务状态 |
内置FTP是本平台自带的FTP服务器功能,无需依赖外部FTP即可接收RPA文件上传。
- ✅ RPA机器人直接上传文件到本系统
- ✅ 作为外部FTP的备份方案
- ✅ 内网环境,简化部署
进入系统管理 → 内置FTP配置:
enabled: true
port: 2021
username: rpa_user
password: rpa_password
rootDirectory: /data/ftp-rootmkdir -p /data/ftp-root/upload点击 启动FTP服务 按钮,或调用API:
curl -X POST http://localhost:8082/api/built-in-ftp/startRPA端FTP连接配置:
| 配置项 | 值 |
|---|---|
| 服务器地址 | 本系统地址 |
| 端口 | 2021 |
| 用户名 | rpa_user |
| 密码 | rpa_password |
| 上传目录 | /upload |
| 特性 | 外部FTP | 内置FTP |
|---|---|---|
| 部署 | 需要单独FTP服务器 | 随系统启动 |
| 管理 | 外部管理 | 平台统一管理 |
| 适用 | 已有FTP基础设施 | 新建或备份方案 |
| 端口 | 21 | 2021 |
原因:FTP服务器不可达或配置错误
解决:
- 检查FTP服务器IP和端口
- 确认FTP服务已启动
- 测试用户名密码是否正确
- 检查防火墙是否开放FTP端口
原因:文件名不匹配或扫描未执行
解决:
- 确认文件名符合 filePattern(如
*.xlsx) - 检查任务监控是否有扫描记录
- 确认FTP配置已启用
- 手动触发一次扫描测试
原因:表头行号配置错误
解决:
- 检查报表配置的
headerRow是否正确 - 确认Excel文件格式完整
- 检查是否有多余的空行
原因:规则配置格式错误
解决:
- JSON格式必须正确
- 确认字段名匹配
- 查看任务日志中的清洗详情
原因:端口被占用或目录权限不足
解决:
- 检查端口2021是否被占用:
netstat -an | grep 2021 - 确认
/data/ftp-root目录存在且有权限 - 查看后台日志具体错误信息
方法:
- 页面日志:任务监控 → 点击任务 → 查看日志
- 文件日志:
tail -f logs/report-backend.log
- 数据库日志:
SELECT * FROM task_execution_log WHERE task_execution_id = #{taskId};
report-front/
├── report-backend/ # 后端项目
│ └── src/main/java/com/report/
│ ├── controller/ # 控制器层
│ ├── service/ # 服务层
│ │ └── impl/ # 服务实现
│ ├── job/ # 定时任务
│ ├── entity/ # 实体类
│ ├── mapper/ # 数据访问层
│ ├── util/ # 工具类
│ ├── config/ # 配置类
│ └── common/ # 公共类
├── src/ # 前端项目
│ ├── views/ # 页面组件
│ ├── api/ # API接口
│ ├── router/ # 路由配置
│ ├── store/ # 状态管理
│ └── components/ # 公共组件
├── scripts/ # 脚本
│ └── start.sh # 启动脚本
├── harness/ # 项目管理
└── docs/ # 项目文档
- 后端新增Controller
@RestController @RequestMapping("/api/your-feature") public class YourFeatureController { // 实现 }
- 新增Service
public interface YourService {} @Service public class YourServiceImpl implements YourService {}
- 前端新增页面
<template> <div>Your Feature Page</div> </template>
cd report-backend
mvn test- 控制器层只做参数校验和响应封装
- 业务逻辑在Service层
- 数据库操作在Mapper层
- 工具类放在util包
<type>(<scope>): <description>
- feat: 新功能
- fix: 修复bug
- docs: 文档变更
- refactor: 重构
- test: 测试相关
- chore: 构建/工具
示例:
feat(ftp): 添加内置FTP服务
添加Apache FtpServer实现内置FTP功能
关联任务: H-FTP-INTEGRATION
- Fork 本仓库
- 创建特性分支
git checkout -b feature/your-feature - 提交变更
git commit -m 'feat: add some feature' - 推送分支
git push origin feature/your-feature - 创建 Pull Request
- 新功能必须有单元测试
- 修改后需运行回归测试
- API接口需测试验证
本项目基于 MIT 许可证 开源。
- 项目主页:https://github.com/ASSIN1024/report-front
- 问题反馈:https://github.com/ASSIN1024/report-front/issues
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-04-05 | V1.0 | 初始版本发布 |
| 2026-04-05 | V1.1 | 新增内置FTP服务模块 |
| 2026-04-06 | V1.2 | 修复内置FTP MyBatis映射问题,新增配置驱动自动启动 |
| 2026-04-08 | V1.3 | 新增数据中心模块、表管理功能、表命名规范 |
| 2026-04-09 | V1.4 | Quartz JDBC集群模式迁移,支持多实例部署和MySQL/GaussDB环境隔离 |
| 2026-04-12 | V1.5 | 项目清理,删除测试文件和临时文件,为内网生产环境迁移做准备 |