feat(controller): 添加历史法院公告批量导入功能并优化Excel导入支持

- 新增批量导入历史法院公告接口,支持"历史法院公告"和"历史法庭公告"选项卡
- 实现数据库唯一索引约束防止重复数据导入
- 优化专利导入逻辑,优先读取"专利"选项卡并兼容多sheet格式
- 增强Excel导入头部匹配功能,支持括号标注的表头识别
- 添加全角半角括号统一处理和表头规范化映射
- 实现带括号后缀表头的智能匹配和剥离功能
- 新增专利导入相关单元测试验证括号表头处理
This commit is contained in:
2026-02-14 16:52:02 +08:00
parent 546027e7a4
commit d177555ef9
4 changed files with 355 additions and 26 deletions

View File

@@ -0,0 +1,93 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.credit.param.CreditPatentImportParam;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.junit.jupiter.api.Test;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
class ExcelImportSupportPatentImportTest {
@Test
void import_should_map_parentheses_headers() throws Exception {
MultipartFile file = buildPatentWorkbookFile("公开(公告)号", "申请(专利权)人");
ExcelImportSupport.ImportResult<CreditPatentImportParam> result = ExcelImportSupport.readAnySheet(
file,
CreditPatentImportParam.class,
p -> p == null || (ImportHelper.isBlank(p.getRegisterNo()) && ImportHelper.isBlank(p.getName()))
);
assertNotNull(result);
assertEquals(1, result.getData().size());
CreditPatentImportParam row = result.getData().get(0);
assertEquals("CN2024XXXXXXXX.X", row.getRegisterNo());
assertEquals("CN1XXXXXXXXX", row.getPublicNo());
assertEquals("示例科技有限公司", row.getPatentApplicant());
}
@Test
void import_should_handle_fullwidth_parentheses_headers() throws Exception {
MultipartFile file = buildPatentWorkbookFile("公开(公告)号", "申请(专利权)人");
ExcelImportSupport.ImportResult<CreditPatentImportParam> result = ExcelImportSupport.readAnySheet(
file,
CreditPatentImportParam.class,
p -> p == null || (ImportHelper.isBlank(p.getRegisterNo()) && ImportHelper.isBlank(p.getName()))
);
assertNotNull(result);
assertEquals(1, result.getData().size());
CreditPatentImportParam row = result.getData().get(0);
assertEquals("CN2024XXXXXXXX.X", row.getRegisterNo());
assertEquals("CN1XXXXXXXXX", row.getPublicNo());
assertEquals("示例科技有限公司", row.getPatentApplicant());
}
private static MultipartFile buildPatentWorkbookFile(String publicNoHeader, String applicantHeader) throws Exception {
try (Workbook workbook = new XSSFWorkbook()) {
Sheet sheet = workbook.createSheet("专利");
Row header = sheet.createRow(0);
header.createCell(0).setCellValue("发明名称");
header.createCell(1).setCellValue("专利类型");
header.createCell(2).setCellValue("法律状态");
header.createCell(3).setCellValue("申请号");
header.createCell(4).setCellValue("申请日");
header.createCell(5).setCellValue(publicNoHeader);
header.createCell(6).setCellValue("公开(公告)日期");
header.createCell(7).setCellValue("发明人");
header.createCell(8).setCellValue(applicantHeader);
header.createCell(9).setCellValue("备注");
Row row = sheet.createRow(1);
row.createCell(0).setCellValue("一种示例装置及方法");
row.createCell(1).setCellValue("发明专利");
row.createCell(2).setCellValue("有效");
row.createCell(3).setCellValue("CN2024XXXXXXXX.X");
row.createCell(4).setCellValue("2024-01-01");
row.createCell(5).setCellValue("CN1XXXXXXXXX");
row.createCell(6).setCellValue("2024-06-01");
row.createCell(7).setCellValue("张三;李四");
row.createCell(8).setCellValue("示例科技有限公司");
row.createCell(9).setCellValue("备注信息");
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
return new MockMultipartFile(
"file",
"patent.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
bos.toByteArray()
);
}
}
}
}