test
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
package com.ruoyi.info.collection.controller;
|
||||
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.BaseStaffImportSubmitResultVO;
|
||||
import com.ruoyi.info.collection.service.ICcdiBaseStaffAssetImportService;
|
||||
import com.ruoyi.info.collection.service.ICcdiBaseStaffImportService;
|
||||
import com.ruoyi.info.collection.service.ICcdiBaseStaffService;
|
||||
import com.ruoyi.info.collection.utils.EasyExcelUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiBaseStaffControllerTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiBaseStaffController controller;
|
||||
|
||||
@Mock
|
||||
private ICcdiBaseStaffService baseStaffService;
|
||||
|
||||
@Mock
|
||||
private ICcdiBaseStaffImportService importAsyncService;
|
||||
|
||||
@Mock
|
||||
private ICcdiBaseStaffAssetImportService baseStaffAssetImportService;
|
||||
|
||||
@Test
|
||||
void importTemplate_shouldDownloadDualSheetTemplate() {
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
controller.importTemplate(null);
|
||||
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(
|
||||
null,
|
||||
CcdiBaseStaffExcel.class,
|
||||
"员工信息",
|
||||
CcdiBaseStaffAssetInfoExcel.class,
|
||||
"员工资产信息",
|
||||
"员工信息维护导入模板"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldWarnWhenBothSheetsAreEmpty() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"base-staff-empty.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"empty".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffExcel.class), eq("员工信息")))
|
||||
.thenReturn(List.of());
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffAssetInfoExcel.class), eq("员工资产信息")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.ERROR, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("至少需要一条数据", result.get(AjaxResult.MSG_TAG));
|
||||
verifyNoInteractions(baseStaffService);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldSubmitOnlyStaffTaskWhenOnlyStaffSheetHasRows() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"base-staff.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"staff".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
CcdiBaseStaffExcel staffExcel = new CcdiBaseStaffExcel();
|
||||
staffExcel.setStaffId(1001L);
|
||||
BaseStaffImportSubmitResultVO submitResult = new BaseStaffImportSubmitResultVO();
|
||||
submitResult.setStaffTaskId("staff-task-1");
|
||||
when(baseStaffService.importBaseStaffWithAssets(List.of(staffExcel), List.of())).thenReturn(submitResult);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffExcel.class), eq("员工信息")))
|
||||
.thenReturn(List.of(staffExcel));
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffAssetInfoExcel.class), eq("员工资产信息")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("导入任务已提交,正在后台处理", result.get(AjaxResult.MSG_TAG));
|
||||
Object data = result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("staff-task-1", data.getClass().getMethod("getStaffTaskId").invoke(data));
|
||||
assertNull(data.getClass().getMethod("getAssetTaskId").invoke(data));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldSubmitTwoTasksWhenBothSheetsHaveRows() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"base-staff-both.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"both".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
CcdiBaseStaffExcel staffExcel = new CcdiBaseStaffExcel();
|
||||
staffExcel.setStaffId(1002L);
|
||||
CcdiBaseStaffAssetInfoExcel assetExcel = new CcdiBaseStaffAssetInfoExcel();
|
||||
assetExcel.setPersonId("320101199001010011");
|
||||
BaseStaffImportSubmitResultVO submitResult = new BaseStaffImportSubmitResultVO();
|
||||
submitResult.setStaffTaskId("staff-task-2");
|
||||
submitResult.setAssetTaskId("asset-task-2");
|
||||
when(baseStaffService.importBaseStaffWithAssets(List.of(staffExcel), List.of(assetExcel))).thenReturn(submitResult);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffExcel.class), eq("员工信息")))
|
||||
.thenReturn(List.of(staffExcel));
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffAssetInfoExcel.class), eq("员工资产信息")))
|
||||
.thenReturn(List.of(assetExcel));
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
Object data = result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("staff-task-2", data.getClass().getMethod("getStaffTaskId").invoke(data));
|
||||
assertEquals("asset-task-2", data.getClass().getMethod("getAssetTaskId").invoke(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ruoyi.info.collection.controller;
|
||||
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.info.collection.domain.vo.EnumOptionVO;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
|
||||
class CcdiEnumControllerTest {
|
||||
|
||||
private final CcdiEnumController controller = new CcdiEnumController();
|
||||
|
||||
@Test
|
||||
void getEnterpriseRiskLevelOptions_shouldReturnConfiguredOptions() {
|
||||
AjaxResult result = controller.getEnterpriseRiskLevelOptions();
|
||||
List<?> data = (List<?>) result.get("data");
|
||||
|
||||
assertEquals(3, data.size());
|
||||
EnumOptionVO first = (EnumOptionVO) data.get(0);
|
||||
assertEquals("1", first.getValue());
|
||||
assertEquals("高风险", first.getLabel());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getEnterpriseSourceOptions_shouldReturnConfiguredOptions() {
|
||||
AjaxResult result = controller.getEnterpriseSourceOptions();
|
||||
List<?> data = (List<?>) result.get("data");
|
||||
|
||||
assertFalse(data.isEmpty());
|
||||
EnumOptionVO first = (EnumOptionVO) data.get(0);
|
||||
assertEquals("GENERAL", first.getValue());
|
||||
assertEquals("一般企业", first.getLabel());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.ruoyi.info.collection.controller;
|
||||
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiStaffFmyRelationExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.StaffFmyRelationImportSubmitResultVO;
|
||||
import com.ruoyi.info.collection.domain.vo.StaffFmyRelationImportFailureVO;
|
||||
import com.ruoyi.info.collection.service.ICcdiAssetInfoImportService;
|
||||
import com.ruoyi.info.collection.service.ICcdiStaffFmyRelationImportService;
|
||||
import com.ruoyi.info.collection.service.ICcdiStaffFmyRelationService;
|
||||
import com.ruoyi.info.collection.utils.EasyExcelUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiStaffFmyRelationControllerTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiStaffFmyRelationController controller;
|
||||
|
||||
@Mock
|
||||
private ICcdiStaffFmyRelationService relationService;
|
||||
|
||||
@Mock
|
||||
private ICcdiStaffFmyRelationImportService relationImportService;
|
||||
|
||||
@Mock
|
||||
private ICcdiAssetInfoImportService assetInfoImportService;
|
||||
|
||||
@Test
|
||||
void importTemplate_shouldDownloadDualSheetTemplate() {
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
controller.importTemplate(null);
|
||||
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(
|
||||
null,
|
||||
CcdiStaffFmyRelationExcel.class,
|
||||
"员工亲属关系信息",
|
||||
CcdiAssetInfoExcel.class,
|
||||
"亲属资产信息",
|
||||
"员工亲属关系维护导入模板"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldErrorWhenBothSheetsAreEmpty() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"staff-family-empty.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"empty".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiStaffFmyRelationExcel.class), eq("员工亲属关系信息")))
|
||||
.thenReturn(List.of());
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiAssetInfoExcel.class), eq("亲属资产信息")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.ERROR, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("至少需要一条数据", result.get(AjaxResult.MSG_TAG));
|
||||
verifyNoInteractions(relationService, assetInfoImportService);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldSubmitOnlyRelationTaskWhenOnlyRelationSheetHasRows() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"staff-family-relation.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"relation".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
CcdiStaffFmyRelationExcel relationExcel = new CcdiStaffFmyRelationExcel();
|
||||
relationExcel.setPersonId("320101199001010011");
|
||||
StaffFmyRelationImportSubmitResultVO submitResult = new StaffFmyRelationImportSubmitResultVO();
|
||||
submitResult.setRelationTaskId("relation-task-1");
|
||||
when(relationService.importRelationWithAssets(List.of(relationExcel), List.of())).thenReturn(submitResult);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiStaffFmyRelationExcel.class), eq("员工亲属关系信息")))
|
||||
.thenReturn(List.of(relationExcel));
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiAssetInfoExcel.class), eq("亲属资产信息")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("导入任务已提交,正在后台处理", result.get(AjaxResult.MSG_TAG));
|
||||
Object data = result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("relation-task-1", data.getClass().getMethod("getRelationTaskId").invoke(data));
|
||||
assertNull(data.getClass().getMethod("getAssetTaskId").invoke(data));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldSubmitTwoTasksWhenBothSheetsHaveRows() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"staff-family-both.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"both".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
CcdiStaffFmyRelationExcel relationExcel = new CcdiStaffFmyRelationExcel();
|
||||
relationExcel.setPersonId("320101199001010012");
|
||||
CcdiAssetInfoExcel assetExcel = new CcdiAssetInfoExcel();
|
||||
assetExcel.setPersonId("320101199001010099");
|
||||
StaffFmyRelationImportSubmitResultVO submitResult = new StaffFmyRelationImportSubmitResultVO();
|
||||
submitResult.setRelationTaskId("relation-task-2");
|
||||
submitResult.setAssetTaskId("asset-task-2");
|
||||
when(relationService.importRelationWithAssets(List.of(relationExcel), List.of(assetExcel))).thenReturn(submitResult);
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiStaffFmyRelationExcel.class), eq("员工亲属关系信息")))
|
||||
.thenReturn(List.of(relationExcel));
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiAssetInfoExcel.class), eq("亲属资产信息")))
|
||||
.thenReturn(List.of(assetExcel));
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
Object data = result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("relation-task-2", data.getClass().getMethod("getRelationTaskId").invoke(data));
|
||||
assertEquals("asset-task-2", data.getClass().getMethod("getAssetTaskId").invoke(data));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportFailures_shouldReturnPagedRowsWithSheetAndRowInfo() {
|
||||
StaffFmyRelationImportFailureVO failure1 = new StaffFmyRelationImportFailureVO();
|
||||
failure1.setSheetName("员工亲属关系信息");
|
||||
failure1.setRowNum(2);
|
||||
failure1.setPersonId("A1");
|
||||
|
||||
StaffFmyRelationImportFailureVO failure2 = new StaffFmyRelationImportFailureVO();
|
||||
failure2.setSheetName("员工亲属关系信息");
|
||||
failure2.setRowNum(3);
|
||||
failure2.setPersonId("A2");
|
||||
|
||||
when(relationImportService.getImportFailures("task-1")).thenReturn(List.of(failure1, failure2));
|
||||
|
||||
TableDataInfo result = controller.getImportFailures("task-1", 2, 1);
|
||||
|
||||
assertEquals(2, result.getTotal());
|
||||
assertEquals(1, result.getRows().size());
|
||||
StaffFmyRelationImportFailureVO row = (StaffFmyRelationImportFailureVO) result.getRows().get(0);
|
||||
assertEquals("员工亲属关系信息", row.getSheetName());
|
||||
assertEquals(3, row.getRowNum());
|
||||
assertEquals("A2", row.getPersonId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ruoyi.info.collection.mapper;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiEnterpriseBaseInfoMapperTest {
|
||||
|
||||
@Test
|
||||
void mapperXml_shouldContainPageQueryAndImportColumns() throws Exception {
|
||||
try (InputStream inputStream = getClass().getClassLoader()
|
||||
.getResourceAsStream("mapper/info/collection/CcdiEnterpriseBaseInfoMapper.xml")) {
|
||||
String xml = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
|
||||
assertTrue(xml.contains("selectEnterpriseBaseInfoPage"), xml);
|
||||
assertTrue(xml.contains("risk_level"), xml);
|
||||
assertTrue(xml.contains("ent_source"), xml);
|
||||
assertTrue(xml.contains("data_source"), xml);
|
||||
assertTrue(xml.contains("ORDER BY create_time DESC"), xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ruoyi.info.collection.mapper;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiIntermediaryMapperTest {
|
||||
|
||||
@Test
|
||||
void mapperXml_shouldContainThreeRecordTypesAndRelatedKeywordQuery() throws Exception {
|
||||
try (InputStream inputStream = getClass().getClassLoader()
|
||||
.getResourceAsStream("mapper/info/collection/CcdiIntermediaryMapper.xml")) {
|
||||
String xml = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
|
||||
assertTrue(xml.contains("INTERMEDIARY"), xml);
|
||||
assertTrue(xml.contains("RELATIVE"), xml);
|
||||
assertTrue(xml.contains("ENTERPRISE_RELATION"), xml);
|
||||
assertTrue(xml.contains("relatedIntermediaryKeyword"), xml);
|
||||
assertTrue(xml.contains("related_intermediary_name"), xml);
|
||||
assertTrue(xml.contains("relation_text"), xml);
|
||||
assertTrue(xml.contains("CAST('实体'"), xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.common.core.domain.entity.SysDept;
|
||||
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportFailureVO;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiBaseStaffImportServiceImpl;
|
||||
import com.ruoyi.system.mapper.SysDeptMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.HashOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ValueOperations;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiBaseStaffDualImportServiceTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiBaseStaffImportServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper baseStaffMapper;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Mock
|
||||
private HashOperations<String, Object, Object> hashOperations;
|
||||
|
||||
@Mock
|
||||
private ValueOperations<String, Object> valueOperations;
|
||||
|
||||
@Mock
|
||||
private SysDeptMapper deptMapper;
|
||||
|
||||
@Test
|
||||
void importBaseStaffAsync_shouldTreatExistingEmployeeAsFailureInsteadOfUpdate() {
|
||||
CcdiBaseStaffExcel excel = new CcdiBaseStaffExcel();
|
||||
excel.setStaffId(1001L);
|
||||
excel.setName("张三");
|
||||
excel.setDeptId(10L);
|
||||
excel.setIdCard("11010519491231002X");
|
||||
excel.setPhone("13812345678");
|
||||
excel.setStatus("0");
|
||||
excel.setPartyMember(1);
|
||||
|
||||
CcdiBaseStaff existing = new CcdiBaseStaff();
|
||||
existing.setStaffId(1001L);
|
||||
existing.setIdCard("11010519491231002X");
|
||||
|
||||
when(baseStaffMapper.selectBatchIds(List.of(1001L))).thenReturn(List.of(existing));
|
||||
when(baseStaffMapper.selectList(any())).thenReturn(List.of(existing));
|
||||
lenient().when(deptMapper.selectDeptById(10L)).thenReturn(buildDept(10L, "0", "0"));
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
|
||||
service.importBaseStaffAsync(List.of(excel), "task-existing");
|
||||
|
||||
verify(baseStaffMapper, never()).insertBatch(any());
|
||||
verify(baseStaffMapper, never()).insertOrUpdateBatch(any());
|
||||
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:baseStaff:task-existing:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
ImportFailureVO failure = (ImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertEquals("员工信息", failure.getSheetName());
|
||||
assertEquals(2, failure.getRowNum());
|
||||
assertEquals(1001L, failure.getStaffId());
|
||||
assertEquals("该员工ID已存在", failure.getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void validateStaffData_shouldRejectExistingIdCardWhenStaffIdDoesNotExist() {
|
||||
when(deptMapper.selectDeptById(10L)).thenReturn(buildDept(10L, "0", "0"));
|
||||
|
||||
RuntimeException exception = org.junit.jupiter.api.Assertions.assertThrows(
|
||||
RuntimeException.class,
|
||||
() -> service.validateStaffData(buildExcelDto(), Set.of(), Set.of("11010519491231002X"))
|
||||
);
|
||||
|
||||
assertEquals("该身份证号已存在", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importBaseStaffAsync_shouldSaveFailureWhenDeptIsInvalid() {
|
||||
CcdiBaseStaffExcel validExcel = buildExcel(1001L, 10L, "11010519491231002X");
|
||||
CcdiBaseStaffExcel invalidExcel = buildExcel(1002L, 99L, "320101199001010014");
|
||||
|
||||
when(baseStaffMapper.selectBatchIds(List.of(1001L, 1002L))).thenReturn(List.of());
|
||||
when(baseStaffMapper.selectList(any())).thenReturn(List.of());
|
||||
when(deptMapper.selectDeptById(10L)).thenReturn(buildDept(10L, "0", "0"));
|
||||
when(deptMapper.selectDeptById(99L)).thenReturn(null);
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
|
||||
service.importBaseStaffAsync(List.of(validExcel, invalidExcel), "task-invalid-dept");
|
||||
|
||||
verify(baseStaffMapper).insertBatch(any());
|
||||
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:baseStaff:task-invalid-dept:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
ImportFailureVO failure = (ImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertEquals("员工信息", failure.getSheetName());
|
||||
assertEquals(3, failure.getRowNum());
|
||||
assertEquals(1002L, failure.getStaffId());
|
||||
assertEquals("所属部门ID[99]不存在或已停用/删除,请检查机构号", failure.getErrorMessage());
|
||||
|
||||
ArgumentCaptor<Map<String, Object>> statusCaptor = ArgumentCaptor.forClass(Map.class);
|
||||
verify(hashOperations).putAll(eq("import:baseStaff:task-invalid-dept"), statusCaptor.capture());
|
||||
assertEquals("PARTIAL_SUCCESS", statusCaptor.getValue().get("status"));
|
||||
assertEquals(1, statusCaptor.getValue().get("successCount"));
|
||||
assertEquals(1, statusCaptor.getValue().get("failureCount"));
|
||||
}
|
||||
|
||||
private com.ruoyi.info.collection.domain.dto.CcdiBaseStaffAddDTO buildExcelDto() {
|
||||
com.ruoyi.info.collection.domain.dto.CcdiBaseStaffAddDTO dto = new com.ruoyi.info.collection.domain.dto.CcdiBaseStaffAddDTO();
|
||||
dto.setName("李四");
|
||||
dto.setStaffId(2001L);
|
||||
dto.setDeptId(10L);
|
||||
dto.setIdCard("11010519491231002X");
|
||||
dto.setPhone("13812345678");
|
||||
dto.setStatus("0");
|
||||
dto.setPartyMember(1);
|
||||
return dto;
|
||||
}
|
||||
|
||||
private CcdiBaseStaffExcel buildExcel(Long staffId, Long deptId, String idCard) {
|
||||
CcdiBaseStaffExcel excel = new CcdiBaseStaffExcel();
|
||||
excel.setStaffId(staffId);
|
||||
excel.setName("张三");
|
||||
excel.setDeptId(deptId);
|
||||
excel.setIdCard(idCard);
|
||||
excel.setPhone("13812345678");
|
||||
excel.setStatus("0");
|
||||
excel.setPartyMember(1);
|
||||
return excel;
|
||||
}
|
||||
|
||||
private SysDept buildDept(Long deptId, String status, String delFlag) {
|
||||
SysDept dept = new SysDept();
|
||||
dept.setDeptId(deptId);
|
||||
dept.setDeptName("测试部门");
|
||||
dept.setStatus(status);
|
||||
dept.setDelFlag(delFlag);
|
||||
return dept;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.CcdiBizIntermediary;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiIntermediaryRelativeAddDTO;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiIntermediaryPersonAddDTO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiBizIntermediaryMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiIntermediaryEnterpriseRelationMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiIntermediaryMapper;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiIntermediaryServiceImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiIntermediaryServiceImplTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiIntermediaryServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private CcdiBizIntermediaryMapper bizIntermediaryMapper;
|
||||
|
||||
@Mock
|
||||
private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper;
|
||||
|
||||
@Mock
|
||||
private CcdiIntermediaryMapper intermediaryMapper;
|
||||
|
||||
@Mock
|
||||
private CcdiIntermediaryEnterpriseRelationMapper enterpriseRelationMapper;
|
||||
|
||||
@Mock
|
||||
private ICcdiIntermediaryPersonImportService personImportService;
|
||||
|
||||
@Mock
|
||||
private ICcdiIntermediaryEntityImportService entityImportService;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Test
|
||||
void insertIntermediaryPerson_shouldForceBenrenAndClearRelatedNumId() {
|
||||
CcdiIntermediaryPersonAddDTO addDTO = new CcdiIntermediaryPersonAddDTO();
|
||||
addDTO.setName("测试中介");
|
||||
addDTO.setPersonId("320101199001010011");
|
||||
addDTO.setPersonSubType("配偶");
|
||||
addDTO.setRelatedNumId("parent-id");
|
||||
|
||||
when(bizIntermediaryMapper.selectCount(any())).thenReturn(0L);
|
||||
when(bizIntermediaryMapper.insert(any(CcdiBizIntermediary.class))).thenReturn(1);
|
||||
|
||||
int result = service.insertIntermediaryPerson(addDTO);
|
||||
|
||||
assertEquals(1, result);
|
||||
ArgumentCaptor<CcdiBizIntermediary> captor = ArgumentCaptor.forClass(CcdiBizIntermediary.class);
|
||||
verify(bizIntermediaryMapper).insert(captor.capture());
|
||||
assertEquals("本人", captor.getValue().getPersonSubType());
|
||||
assertNull(captor.getValue().getRelatedNumId());
|
||||
assertEquals("MANUAL", captor.getValue().getDataSource());
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertIntermediaryRelative_shouldRejectBenrenSubType() {
|
||||
CcdiBizIntermediary owner = new CcdiBizIntermediary();
|
||||
owner.setBizId("biz-1");
|
||||
owner.setPersonSubType("本人");
|
||||
|
||||
CcdiIntermediaryRelativeAddDTO addDTO = new CcdiIntermediaryRelativeAddDTO();
|
||||
addDTO.setName("测试亲属");
|
||||
addDTO.setPersonId("320101199001010022");
|
||||
addDTO.setPersonSubType("本人");
|
||||
|
||||
when(bizIntermediaryMapper.selectById("biz-1")).thenReturn(owner);
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class,
|
||||
() -> service.insertIntermediaryRelative("biz-1", addDTO));
|
||||
|
||||
assertEquals("亲属关系不能为本人", exception.getMessage());
|
||||
verify(bizIntermediaryMapper, never()).insert(any(CcdiBizIntermediary.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteIntermediaryByIds_shouldDeleteRelativesAndEnterpriseRelationsWhenRemovingOwner() {
|
||||
CcdiBizIntermediary owner = new CcdiBizIntermediary();
|
||||
owner.setBizId("biz-1");
|
||||
owner.setPersonSubType("本人");
|
||||
|
||||
when(bizIntermediaryMapper.selectById("biz-1")).thenReturn(owner);
|
||||
when(bizIntermediaryMapper.delete(any())).thenReturn(2);
|
||||
when(enterpriseRelationMapper.delete(any())).thenReturn(1);
|
||||
when(bizIntermediaryMapper.deleteById("biz-1")).thenReturn(1);
|
||||
|
||||
int result = service.deleteIntermediaryByIds(new String[]{"biz-1"});
|
||||
|
||||
assertEquals(1, result);
|
||||
verify(bizIntermediaryMapper).delete(any());
|
||||
verify(enterpriseRelationMapper).delete(any());
|
||||
verify(bizIntermediaryMapper).deleteById("biz-1");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class CcdiPurchaseTransactionFeatureContractTest {
|
||||
|
||||
@Test
|
||||
void shouldExposeSupplierListContractsAcrossPurchaseTransactionModels() throws Exception {
|
||||
assertHasField(
|
||||
"com.ruoyi.info.collection.domain.dto.CcdiPurchaseTransactionAddDTO",
|
||||
"supplierList"
|
||||
);
|
||||
assertHasField(
|
||||
"com.ruoyi.info.collection.domain.dto.CcdiPurchaseTransactionEditDTO",
|
||||
"supplierList"
|
||||
);
|
||||
assertHasField(
|
||||
"com.ruoyi.info.collection.domain.vo.CcdiPurchaseTransactionVO",
|
||||
"supplierList"
|
||||
);
|
||||
assertHasField(
|
||||
"com.ruoyi.info.collection.domain.vo.CcdiPurchaseTransactionVO",
|
||||
"supplierCount"
|
||||
);
|
||||
assertNotNull(Class.forName("com.ruoyi.info.collection.domain.CcdiPurchaseTransactionSupplier"));
|
||||
assertNotNull(Class.forName("com.ruoyi.info.collection.domain.dto.CcdiPurchaseTransactionSupplierDTO"));
|
||||
assertNotNull(Class.forName("com.ruoyi.info.collection.domain.vo.CcdiPurchaseTransactionSupplierVO"));
|
||||
assertNotNull(Class.forName("com.ruoyi.info.collection.domain.excel.CcdiPurchaseTransactionSupplierExcel"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDefineSupplierSubTableAndBiddingMigrationScripts() throws Exception {
|
||||
String initSql = Files.readString(repoPath("sql/ccdi_purchase_transaction.sql"));
|
||||
assertTrue(initSql.contains("CREATE TABLE `ccdi_purchase_transaction_supplier`"));
|
||||
assertTrue(initSql.contains("`is_bid_winner`"));
|
||||
assertTrue(initSql.contains("`sort_order`"));
|
||||
assertTrue(initSql.contains("utf8mb4_general_ci"));
|
||||
|
||||
String menuSql = Files.readString(repoPath("sql/ccdi_purchase_transaction_menu.sql"));
|
||||
assertTrue(menuSql.contains("招投标信息维护"));
|
||||
|
||||
Path migrationPath = repoPath("sql/migration/2026-04-22-bidding-info-maintenance-supplier-detail.sql");
|
||||
assertTrue(Files.exists(migrationPath), "应提供招投标供应商明细迁移脚本");
|
||||
|
||||
String migrationSql = Files.readString(migrationPath);
|
||||
assertTrue(migrationSql.contains("ccdi_purchase_transaction_supplier"));
|
||||
assertTrue(migrationSql.contains("INSERT INTO ccdi_purchase_transaction_supplier"));
|
||||
assertTrue(migrationSql.contains("UPDATE sys_menu"));
|
||||
assertTrue(migrationSql.contains("招投标信息维护"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseTwoSheetTemplateForBiddingImport() throws Exception {
|
||||
assertNotNull(Class.forName("com.ruoyi.info.collection.domain.excel.CcdiPurchaseTransactionSupplierExcel"));
|
||||
|
||||
String controller = Files.readString(
|
||||
Path.of("src/main/java/com/ruoyi/info/collection/controller/CcdiPurchaseTransactionController.java")
|
||||
);
|
||||
assertTrue(controller.contains("招投标主信息"));
|
||||
assertTrue(controller.contains("供应商明细"));
|
||||
}
|
||||
|
||||
private void assertHasField(String className, String fieldName) throws Exception {
|
||||
Class<?> clazz = Class.forName(className);
|
||||
Field field = clazz.getDeclaredField(fieldName);
|
||||
assertNotNull(field);
|
||||
}
|
||||
|
||||
private Path repoPath(String relativePath) {
|
||||
return Path.of("..", relativePath);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
package com.ruoyi.info.collection.utils;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffExcel;
|
||||
import org.apache.poi.ss.usermodel.CellType;
|
||||
import org.apache.poi.ss.usermodel.DataValidation;
|
||||
import org.apache.poi.ss.usermodel.DataValidationConstraint;
|
||||
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
||||
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.ss.util.CellRangeAddressList;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class EasyExcelUtilImportDropdownValidationTest {
|
||||
|
||||
@Test
|
||||
void importExcel_shouldPassWhenAllDictDropdownColumnsKeepListValidation() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(true, true, true, 2);
|
||||
|
||||
List<CcdiBaseStaffExcel> rows = EasyExcelUtil.importExcel(
|
||||
new ByteArrayInputStream(bytes),
|
||||
CcdiBaseStaffExcel.class,
|
||||
"员工信息"
|
||||
);
|
||||
|
||||
assertEquals(2, rows.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldFailWhenPartyMemberDropdownIsMissing() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(false, true, true, 2);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffExcel.class, "员工信息")
|
||||
);
|
||||
|
||||
assertTrue(exception.getMessage().contains("是否党员 列缺少下拉框"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldFailWhenStatusDropdownIsMissing() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(true, false, true, 2);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffExcel.class, "员工信息")
|
||||
);
|
||||
|
||||
assertEquals("员工信息 Sheet 的 状态 列缺少下拉框,请下载最新导入模板填写后重新导入", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldReportAllMissingDropdownColumnsInSameSheet() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(false, false, true, 2);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffExcel.class, "员工信息")
|
||||
);
|
||||
|
||||
assertEquals("员工信息 Sheet 的 是否党员、状态 列缺少下拉框,请下载最新导入模板填写后重新导入", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldFailWhenValidationIsNotListType() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(true, true, false, 2);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffExcel.class, "员工信息")
|
||||
);
|
||||
|
||||
assertTrue(exception.getMessage().contains("状态 列缺少下拉框"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldFailWhenListValidationDoesNotCoverEveryActualDataRow() throws Exception {
|
||||
byte[] bytes = baseStaffWorkbook(true, true, true, 1);
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffExcel.class, "员工信息")
|
||||
);
|
||||
|
||||
assertTrue(exception.getMessage().contains("状态 列缺少下拉框"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldFailWhenSecondSheetDropdownIsMissing() throws Exception {
|
||||
byte[] bytes = baseStaffDualSheetWorkbookWithMissingAssetStatusDropdown();
|
||||
|
||||
ServiceException exception = assertThrows(ServiceException.class, () ->
|
||||
EasyExcelUtil.importExcel(new ByteArrayInputStream(bytes), CcdiBaseStaffAssetInfoExcel.class, "员工资产信息")
|
||||
);
|
||||
|
||||
assertEquals("员工资产信息 Sheet 的 资产状态 列缺少下拉框,请下载最新导入模板填写后重新导入", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importExcel_shouldSkipDropdownStructureValidationWhenClassHasNoDictDropdownFields() throws Exception {
|
||||
byte[] bytes = plainWorkbookWithoutDropdown();
|
||||
|
||||
List<PlainExcel> rows = EasyExcelUtil.importExcel(
|
||||
new ByteArrayInputStream(bytes),
|
||||
PlainExcel.class,
|
||||
"普通信息"
|
||||
);
|
||||
|
||||
assertEquals(1, rows.size());
|
||||
}
|
||||
|
||||
private byte[] baseStaffWorkbook(boolean partyDropdown, boolean statusDropdown, boolean statusAsList,
|
||||
int statusLastRow) throws Exception {
|
||||
try (Workbook workbook = new XSSFWorkbook();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
Sheet sheet = workbook.createSheet("员工信息");
|
||||
Row header = sheet.createRow(0);
|
||||
String[] headers = {"姓名", "员工ID", "所属部门ID", "身份证号", "电话", "年收入(元/年)",
|
||||
"入职时间", "是否党员", "状态"};
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
header.createCell(i).setCellValue(headers[i]);
|
||||
}
|
||||
createBaseStaffRow(sheet, 1, "张三", 9020001L, "33010619850202101X", "0", "1");
|
||||
createBaseStaffRow(sheet, 2, "李四", 9020002L, "330106198603031022", "1", "1");
|
||||
|
||||
if (partyDropdown) {
|
||||
addListValidation(sheet, 7, 1, 2, "0", "1");
|
||||
}
|
||||
if (statusDropdown) {
|
||||
if (statusAsList) {
|
||||
addListValidation(sheet, 8, 1, statusLastRow, "0", "1");
|
||||
} else {
|
||||
addIntegerValidation(sheet, 8, 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
workbook.write(outputStream);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] baseStaffDualSheetWorkbookWithMissingAssetStatusDropdown() throws Exception {
|
||||
try (Workbook workbook = new XSSFWorkbook();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
Sheet staffSheet = workbook.createSheet("员工信息");
|
||||
Row staffHeader = staffSheet.createRow(0);
|
||||
String[] staffHeaders = {"姓名", "员工ID", "所属部门ID", "身份证号", "电话", "年收入(元/年)",
|
||||
"入职时间", "是否党员", "状态"};
|
||||
for (int i = 0; i < staffHeaders.length; i++) {
|
||||
staffHeader.createCell(i).setCellValue(staffHeaders[i]);
|
||||
}
|
||||
createBaseStaffRow(staffSheet, 1, "张三", 9020001L, "33010619850202101X", "0", "1");
|
||||
addListValidation(staffSheet, 7, 1, 1, "0", "1");
|
||||
addListValidation(staffSheet, 8, 1, 1, "0", "1");
|
||||
|
||||
Sheet assetSheet = workbook.createSheet("员工资产信息");
|
||||
Row assetHeader = assetSheet.createRow(0);
|
||||
String[] assetHeaders = {"员工身份证号*", "资产大类*", "资产小类*", "资产名称*", "产权占比",
|
||||
"购买/评估日期", "资产原值", "当前估值*", "估值截止日期", "资产状态*", "备注"};
|
||||
for (int i = 0; i < assetHeaders.length; i++) {
|
||||
assetHeader.createCell(i).setCellValue(assetHeaders[i]);
|
||||
}
|
||||
Row assetRow = assetSheet.createRow(1);
|
||||
assetRow.createCell(0).setCellValue("33010619850202101X");
|
||||
assetRow.createCell(1).setCellValue("房产");
|
||||
assetRow.createCell(2).setCellValue("住宅");
|
||||
assetRow.createCell(3).setCellValue("测试住宅");
|
||||
assetRow.createCell(7).setCellValue(1000000D);
|
||||
assetRow.createCell(9).setCellValue("正常");
|
||||
|
||||
workbook.write(outputStream);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private void createBaseStaffRow(Sheet sheet, int rowIndex, String name, long staffId, String idCard,
|
||||
String partyMember, String status) {
|
||||
Row row = sheet.createRow(rowIndex);
|
||||
row.createCell(0).setCellValue(name);
|
||||
row.createCell(1).setCellValue(staffId);
|
||||
row.createCell(2).setCellValue(103L);
|
||||
row.createCell(3, CellType.STRING).setCellValue(idCard);
|
||||
row.createCell(4, CellType.STRING).setCellValue("13370000001");
|
||||
row.createCell(5).setCellValue(new BigDecimal("180000").doubleValue());
|
||||
row.createCell(6).setCellValue("2026-04-30");
|
||||
row.createCell(7, CellType.STRING).setCellValue(partyMember);
|
||||
row.createCell(8, CellType.STRING).setCellValue(status);
|
||||
}
|
||||
|
||||
private void addListValidation(Sheet sheet, int columnIndex, int firstRow, int lastRow, String... options) {
|
||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||
DataValidationConstraint constraint = helper.createExplicitListConstraint(options);
|
||||
DataValidation validation = helper.createValidation(
|
||||
constraint,
|
||||
new CellRangeAddressList(firstRow, lastRow, columnIndex, columnIndex)
|
||||
);
|
||||
sheet.addValidationData(validation);
|
||||
}
|
||||
|
||||
private void addIntegerValidation(Sheet sheet, int columnIndex, int firstRow, int lastRow) {
|
||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||
DataValidationConstraint constraint = helper.createIntegerConstraint(
|
||||
DataValidationConstraint.OperatorType.BETWEEN,
|
||||
"0",
|
||||
"1"
|
||||
);
|
||||
DataValidation validation = helper.createValidation(
|
||||
constraint,
|
||||
new CellRangeAddressList(firstRow, lastRow, columnIndex, columnIndex)
|
||||
);
|
||||
sheet.addValidationData(validation);
|
||||
}
|
||||
|
||||
private byte[] plainWorkbookWithoutDropdown() throws Exception {
|
||||
try (Workbook workbook = new XSSFWorkbook();
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
|
||||
Sheet sheet = workbook.createSheet("普通信息");
|
||||
Row header = sheet.createRow(0);
|
||||
header.createCell(0).setCellValue("名称");
|
||||
Row row = sheet.createRow(1);
|
||||
row.createCell(0).setCellValue("张三");
|
||||
workbook.write(outputStream);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlainExcel {
|
||||
@ExcelProperty(value = "名称", index = 0)
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user