Files
wucaixing-backend/REPORT_SYSTEM_GUIDE.md
2026-05-13 16:14:53 +08:00

140 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 报表打印系统架构与使用说明
本文档详细介绍了当前报表打印系统的架构设计、核心组件及其使用方法。
## 1. 架构设计概览
本系统采用 **Provider 模式****流式任务构建 (Builder Pattern)** 相结合的设计,旨在实现报表生成的解耦、灵活配置与高扩展性。
### 核心组件
1. **IReportDataProvider (报表数据提供者)**
* **职责**:定义单一报表的元数据(模版、标题、类型)和数据准备逻辑。
* **优势**:将业务逻辑从 Service 层剥离,每个报表对应一个 Provider互不干扰易于维护。
* **关键方法**
* `getReportType()`: 唯一标识(如 `APPLICATION_FORM`)。
* `prepareData(params)`: 准备模版所需的数据。
* `getCoverProviderType()`: 定义关联的封面类型(支持自动封面)。
2. **ReportPrintJob (打印任务构建器)**
* **职责**:负责组装打印任务。它像一条流水线,可以按需添加封面、报表片段、设置公章/水印等。
* **特性**
* **链式调用**`createJob().addCover().addBatch().render()`
* **混合布局**:自动处理横向 (Landscape) 与纵向 (Portrait) 页面的合并。
* **上下文注入**:支持注入 CompanyId 用于公章/水印生成。
3. **ReportRenderService (渲染服务)**
* **职责**:底层的渲染引擎。
* **功能**
* 解析 Velocity 模版。
* 调用 Gotenberg 进行 HTML 转 PDF。
* 处理水印 (Watermark) 和电子公章 (Seal)。
* 合并多个 PDF 片段。
## 2. 现有报表类型
目前系统已实现的 Provider 如下:
| 报表类型 (Type) | Provider 类 | 描述 |
| :--- | :--- | :--- |
| `APPLICATION_FORM` | `DriverApplicationFormProvider` | 驾驶员应聘申请表 |
| `ID_CARD_SCAN` | `IdCardScanProvider` | 身份证扫描件 |
| `DRIVER_LICENSE_COPY` | `DriverLicenseCopyProvider` | 驾驶证复印件 |
| `QUALIFICATION_CERTIFICATE_COPY` | `QualificationCertificateCopyProvider` | 从业资格证复印件 |
| `QUALIFICATION_REVIEW` | `QualificationReviewProvider` | 资格审查及技能考核登记表 |
| `ACCIDENT_RECORD` | `AccidentRecordProvider` | 安全行车事故记录 (横向) |
| `VIOLATION_RECORD` | `ViolationRecordProvider` | 违章记录 (横向) |
| `ANNUAL_ASSESSMENT_RECORD` | `AnnualAssessmentRecordProvider` | 年度考核记录 |
| `MEDICAL_EXAMINATION_REPORT` | `MedicalExaminationReportProvider` | 体检报告 |
| `REWARD_PUNISHMENT_RECORD` | `RewardPunishmentRecordProvider` | 奖惩记录表 |
## 3. 使用方法 (开发指南)
### 3.1 创建新报表
1. **定义 Provider**
新建一个类实现 `IReportDataProvider`,并注册为 Spring Bean (`@Component`)。
```java
@Component
public class MyReportProvider implements IReportDataProvider {
@Override
public String getReportType() { return "MY_REPORT"; }
@Override
public String getTemplateCode() { return "templates/my/report.html.vm"; }
@Override
public Map<String, Object> prepareData(Map<String, Object> params) {
// 准备数据...
return Map.of("data", "value");
}
}
```
2. **创建 Velocity 模版**
在 `src/main/resources/templates/my/report.html.vm` 中编写 HTML。
### 3.2 调用打印服务
在业务 Service 中注入 `ReportRenderService` 和 `providerMap`,然后使用链式调用:
#### 场景 A单个报表打印 (带自动封面)
```java
public byte[] printMyReport(List<String> ids) {
// 1. 获取 Provider
IReportDataProvider provider = providerMap.get("MY_REPORT");
// 2. 构建任务
return reportRenderService.createJob(providerMap::get) // 传入查找器以支持自动封面
.withCompanyId(companyId) // 设置公司ID用于公章
.addCover(provider) // 自动添加关联封面
.addBatch(provider, ids, "id") // 批量添加报表内容
.useSeal(true) // 启用公章
.render(); // 渲染并返回 PDF
}
```
#### 场景 B一键打印 (多报表合并)
```java
public byte[] printAll(List<String> driverIds, List<String> types) {
var job = reportRenderService.createJob(providerMap::get)
.withCompanyId(companyId)
.useSeal(false); // 全局公章开关
for (String id : driverIds) {
// 1. 为每个驾驶员添加一个独立封面
job.addCover("COMMON_COVER", Map.of(
"title", "驾驶员档案",
"subtitle", "张三"
));
// 2. 依次添加选中的报表
for (String type : types) {
job.add(providerMap.get(type), Map.of("driverId", id));
}
}
return job.render();
}
```
### 3.3 进阶配置
* **横向布局**:在 Provider 中重写 `isLandscape()` 返回 `true`,或者在 Job 中调用 `.isLandscape(true)` (通常由 Provider
决定)。
* **自定义封面**Provider 可重写 `getCoverProviderType()` 指定特定封面,或重写 `getCoverData()` 自定义封面参数。
* **水印控制**`job.useWatermark(true).watermarkText("自定义水印")`。
## 4. 模版工具支持
模版中内置了 `$tool` 工具类 (`ReportVelocityTool`),提供常用功能:
* `$tool.getDictLabel('type', value)`: 字典翻译
* `$tool.formatDate(date, 'yyyy-MM-dd')`: 日期格式化
* `$tool.getOssUrls(urlStr)`: 解析 OSS 图片链接
* `$tool.numberToChinese(num)`: 数字转中文大写
---
*文档生成日期2026-03-01*