feat(credit): 添加原告/上诉人字段支持

- 在CreditUser实体中新增plaintiffAppellant字段用于存储原告/上诉人信息
- 更新CreditUserController中的数据映射逻辑以包含新字段
- 在CreditUserImportParam中添加Excel导入支持和字段映射
- 在CreditUserParam中定义查询参数结构包含新字段
- 新增CreditBankruptcyImportSheetSelectionTest测试类验证多工作表选择逻辑
- 实现破产重整数据导入时优先选择正确工作表的功能
This commit is contained in:
2026-03-03 15:02:05 +08:00
parent f016acda91
commit a4dbe758e3
5 changed files with 115 additions and 0 deletions

View File

@@ -432,6 +432,7 @@ public class CreditUserController extends BaseController {
entity.setRole(param.getRole()); entity.setRole(param.getRole());
entity.setInfoType(param.getInfoType()); entity.setInfoType(param.getInfoType());
entity.setAddress(param.getAddress()); entity.setAddress(param.getAddress());
entity.setPlaintiffAppellant(param.getPlaintiffAppellant());
entity.setProcurementName(param.getProcurementName()); entity.setProcurementName(param.getProcurementName());
entity.setWinningName(param.getWinningName()); entity.setWinningName(param.getWinningName());
entity.setWinningPrice(param.getWinningPrice()); entity.setWinningPrice(param.getWinningPrice());

View File

@@ -39,6 +39,9 @@ public class CreditUser implements Serializable {
@Schema(description = "类型, 0普通用户, 1招投标") @Schema(description = "类型, 0普通用户, 1招投标")
private Integer type; private Integer type;
@Schema(description = "原告/上诉人")
private String plaintiffAppellant;
@Schema(description = "企业角色") @Schema(description = "企业角色")
private String role; private String role;

View File

@@ -63,6 +63,9 @@ public class CreditUserImportParam implements Serializable {
@Excel(name = "中标金额") @Excel(name = "中标金额")
private String winningPrice; private String winningPrice;
@Excel(name = "原告/上诉人")
private String plaintiffAppellant;
// @Excel(name = "备注") // @Excel(name = "备注")
// private String comments; // private String comments;
// //

View File

@@ -102,4 +102,7 @@ public class CreditUserParam extends BaseParam {
@QueryField(type = QueryType.EQ) @QueryField(type = QueryType.EQ)
private Integer userId; private Integer userId;
@Schema(description = "申请人")
private String plaintiffAppellant;
} }

View File

@@ -0,0 +1,105 @@
package com.gxwebsoft.credit.controller;
import com.gxwebsoft.common.core.web.ApiResult;
import com.gxwebsoft.credit.entity.CreditBankruptcy;
import com.gxwebsoft.credit.service.CreditBankruptcyService;
import com.gxwebsoft.credit.service.CreditCompanyRecordCountService;
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.mockito.Mockito;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CreditBankruptcyImportSheetSelectionTest {
@Test
void import_should_prefer_sheet_named_bankruptcy_reorganization() throws Exception {
MultipartFile file = buildWorkbookWithTwoSheets();
CreditBankruptcyController controller = new CreditBankruptcyController();
CreditBankruptcyService creditBankruptcyService = Mockito.mock(CreditBankruptcyService.class);
BatchImportSupport batchImportSupport = Mockito.mock(BatchImportSupport.class);
CreditCompanyRecordCountService recordCountService = Mockito.mock(CreditCompanyRecordCountService.class);
// Capture inserted entities; controller clears the chunk list after calling persistInsertOnlyChunk.
List<CreditBankruptcy> inserted = new ArrayList<>();
Mockito.when(batchImportSupport.persistInsertOnlyChunk(
Mockito.eq(creditBankruptcyService),
Mockito.anyList(),
Mockito.anyList(),
Mockito.anyInt(),
Mockito.any(),
Mockito.anyString(),
Mockito.anyList()
))
.thenAnswer(invocation -> {
@SuppressWarnings("unchecked")
List<CreditBankruptcy> items = new ArrayList<>((List<CreditBankruptcy>) invocation.getArgument(1));
inserted.addAll(items);
return items.size();
});
ReflectionTestUtils.setField(controller, "creditBankruptcyService", creditBankruptcyService);
ReflectionTestUtils.setField(controller, "batchImportSupport", batchImportSupport);
ReflectionTestUtils.setField(controller, "creditCompanyRecordCountService", recordCountService);
ApiResult<List<String>> result = controller.importBatch(file, null);
assertNotNull(result);
assertEquals(0, result.getCode());
assertTrue(result.getMessage().contains("成功导入1条"), "message=" + result.getMessage());
assertEquals(1, inserted.size());
// "历史破产重整" sheet is first; we should import from "破产重整" instead.
assertEquals("R1", inserted.get(0).getCode());
}
private static MultipartFile buildWorkbookWithTwoSheets() throws Exception {
try (Workbook workbook = new XSSFWorkbook()) {
// Put "历史破产重整" first to ensure old readAnySheet() behavior would import the wrong sheet.
writeBankruptcySheet(workbook.createSheet("历史破产重整"), "H1");
writeBankruptcySheet(workbook.createSheet("破产重整"), "R1");
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
workbook.write(bos);
return new MockMultipartFile(
"file",
"bankruptcy.xlsx",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
bos.toByteArray()
);
}
}
}
private static void writeBankruptcySheet(Sheet sheet, String code) {
// Keep it simple: a single header row + single data row.
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("备注");
Row row = sheet.createRow(1);
row.createCell(0).setCellValue(code);
row.createCell(1).setCellValue("破产重整");
row.createCell(2).setCellValue("示例公司");
row.createCell(3).setCellValue("示例法院");
row.createCell(4).setCellValue("2026-01-01");
row.createCell(5).setCellValue("备注");
}
}