完成员工与亲属资产导入后端拆分
This commit is contained in:
@@ -109,11 +109,11 @@ class CcdiAssetInfoControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void importTemplate_shouldUseGenericAssetTemplateName() {
|
||||
void importTemplate_shouldUseFamilyAssetTemplateName() {
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
controller.importTemplate(null);
|
||||
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(null, CcdiAssetInfoExcel.class, "资产信息"));
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(null, CcdiAssetInfoExcel.class, "亲属资产信息"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
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.CcdiBaseStaffAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.BaseStaffAssetImportFailureVO;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportResultVO;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||
import com.ruoyi.info.collection.service.ICcdiBaseStaffAssetImportService;
|
||||
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.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mockStatic;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiBaseStaffAssetImportControllerTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiBaseStaffAssetImportController controller;
|
||||
|
||||
@Mock
|
||||
private ICcdiBaseStaffAssetImportService baseStaffAssetImportService;
|
||||
|
||||
@Test
|
||||
void importData_shouldReturnWarnWhenExcelHasNoRows() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"base-staff-asset-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(CcdiBaseStaffAssetInfoExcel.class)))
|
||||
.thenReturn(List.of());
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.WARN, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("至少需要一条数据", result.get(AjaxResult.MSG_TAG));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void importData_shouldReturnSuccessWhenTaskCreated() throws Exception {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"file",
|
||||
"base-staff-asset.xlsx",
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
"asset".getBytes(StandardCharsets.UTF_8)
|
||||
);
|
||||
CcdiBaseStaffAssetInfoExcel excel = new CcdiBaseStaffAssetInfoExcel();
|
||||
excel.setPersonId("320101199001010011");
|
||||
when(baseStaffAssetImportService.importAssetInfo(List.of(excel))).thenReturn("task-1");
|
||||
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
mocked.when(() -> EasyExcelUtil.importExcel(any(InputStream.class), eq(CcdiBaseStaffAssetInfoExcel.class)))
|
||||
.thenReturn(List.of(excel));
|
||||
|
||||
AjaxResult result = controller.importData(file);
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals("导入任务已提交,正在后台处理", result.get(AjaxResult.MSG_TAG));
|
||||
ImportResultVO data = (ImportResultVO) result.get(AjaxResult.DATA_TAG);
|
||||
assertEquals("task-1", data.getTaskId());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportStatus_shouldDelegateToImportService() {
|
||||
ImportStatusVO statusVO = new ImportStatusVO();
|
||||
statusVO.setTaskId("task-2");
|
||||
when(baseStaffAssetImportService.getImportStatus("task-2")).thenReturn(statusVO);
|
||||
|
||||
AjaxResult result = controller.getImportStatus("task-2");
|
||||
|
||||
assertEquals(HttpStatus.SUCCESS, result.get(AjaxResult.CODE_TAG));
|
||||
assertEquals(statusVO, result.get(AjaxResult.DATA_TAG));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportFailures_shouldReturnPagedRows() {
|
||||
BaseStaffAssetImportFailureVO failure1 = new BaseStaffAssetImportFailureVO();
|
||||
failure1.setPersonId("A1");
|
||||
BaseStaffAssetImportFailureVO failure2 = new BaseStaffAssetImportFailureVO();
|
||||
failure2.setPersonId("A2");
|
||||
when(baseStaffAssetImportService.getImportFailures("task-3")).thenReturn(List.of(failure1, failure2));
|
||||
|
||||
TableDataInfo result = controller.getImportFailures("task-3", 2, 1);
|
||||
|
||||
assertEquals(2, result.getTotal());
|
||||
assertEquals(1, result.getRows().size());
|
||||
assertEquals("A2", ((BaseStaffAssetImportFailureVO) result.getRows().get(0)).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importTemplate_shouldUseBaseStaffAssetTemplateName() {
|
||||
try (MockedStatic<EasyExcelUtil> mocked = mockStatic(EasyExcelUtil.class)) {
|
||||
controller.importTemplate(null);
|
||||
|
||||
mocked.verify(() -> EasyExcelUtil.importTemplateWithDictDropdown(null, CcdiBaseStaffAssetInfoExcel.class, "员工资产信息"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,19 +97,21 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldResolveFamilyIdFromEmployeeIdCardBeforeFamilyRelation() {
|
||||
void importAssetInfoAsync_shouldFailWhenEmployeeIdCardIsUsedForFamilyAssetImport() {
|
||||
CcdiAssetInfoExcel excel = buildExcel("320101199001010011", "房产");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByPersonIds(List.of("320101199001010011")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199001010011")));
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByRelationCertNos(List.of("320101199001010011")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-self", "tester");
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getPersonId());
|
||||
verify(assetInfoMapper, never()).selectOwnerCandidatesByRelationCertNos(any());
|
||||
verify(assetInfoMapper, never()).insertBatch(any());
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:assetInfo:task-self:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
AssetImportFailureVO failure = (AssetImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertEquals("320101199001010011", failure.getPersonId());
|
||||
assertTrue(failure.getErrorMessage().contains("未找到亲属资产归属员工"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -150,7 +152,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
assertEquals(1, failures.size());
|
||||
AssetImportFailureVO failure = (AssetImportFailureVO) failures.get(0);
|
||||
assertEquals("320101199001010099", failure.getPersonId());
|
||||
assertTrue(failure.getErrorMessage().contains("未找到资产归属员工"));
|
||||
assertTrue(failure.getErrorMessage().contains("未找到亲属资产归属员工"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -170,7 +172,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:assetInfo:task-4:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
AssetImportFailureVO failure = (AssetImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertTrue(failure.getErrorMessage().contains("资产归属员工不唯一"));
|
||||
assertTrue(failure.getErrorMessage().contains("亲属资产归属员工不唯一"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -191,7 +193,7 @@ class CcdiAssetInfoImportServiceImplTest {
|
||||
));
|
||||
AssetImportFailureVO failureVO = new AssetImportFailureVO();
|
||||
failureVO.setPersonId("320101199001010099");
|
||||
failureVO.setErrorMessage("未找到资产归属员工");
|
||||
failureVO.setErrorMessage("未找到亲属资产归属员工");
|
||||
when(valueOperations.get("import:assetInfo:task-5:failures")).thenReturn(List.of(failureVO));
|
||||
|
||||
ImportStatusVO statusVO = service.getImportStatus("task-5");
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.CcdiAssetInfo;
|
||||
import com.ruoyi.info.collection.domain.excel.CcdiBaseStaffAssetInfoExcel;
|
||||
import com.ruoyi.info.collection.domain.vo.BaseStaffAssetImportFailureVO;
|
||||
import com.ruoyi.info.collection.domain.vo.ImportStatusVO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiAssetInfoMapper;
|
||||
import com.ruoyi.info.collection.service.impl.CcdiBaseStaffAssetImportServiceImpl;
|
||||
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.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiBaseStaffAssetImportServiceImplTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiBaseStaffAssetImportServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private CcdiAssetInfoMapper assetInfoMapper;
|
||||
|
||||
@Mock
|
||||
private RedisTemplate<String, Object> redisTemplate;
|
||||
|
||||
@Mock
|
||||
private ICcdiBaseStaffAssetImportService baseStaffAssetImportService;
|
||||
|
||||
@Mock
|
||||
private HashOperations<String, Object, Object> hashOperations;
|
||||
|
||||
@Mock
|
||||
private ValueOperations<String, Object> valueOperations;
|
||||
|
||||
@Test
|
||||
void importAssetInfo_shouldUseDedicatedBaseStaffAssetTaskKeys() {
|
||||
List<CcdiBaseStaffAssetInfoExcel> excelList = List.of(buildExcel("320101199001010011", "房产"));
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
|
||||
String taskId = service.importAssetInfo(excelList);
|
||||
|
||||
verify(hashOperations).putAll(eq("import:baseStaffAsset:" + taskId), anyMap());
|
||||
verify(redisTemplate).expire("import:baseStaffAsset:" + taskId, 7, TimeUnit.DAYS);
|
||||
verify(baseStaffAssetImportService).importAssetInfoAsync(eq(excelList), eq(taskId), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldImportWhenEmployeeIdCardExists() {
|
||||
CcdiBaseStaffAssetInfoExcel excel = buildExcel("320101199001010011", "房产");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByBaseStaffIdCards(List.of("320101199001010011")))
|
||||
.thenReturn(List.of(owner("320101199001010011", "320101199001010011")));
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-1", "tester");
|
||||
|
||||
ArgumentCaptor<List<CcdiAssetInfo>> captor = ArgumentCaptor.forClass(List.class);
|
||||
verify(assetInfoMapper).insertBatch(captor.capture());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getFamilyId());
|
||||
assertEquals("320101199001010011", captor.getValue().get(0).getPersonId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importAssetInfoAsync_shouldFailWhenFamilyCertificateIsUsed() {
|
||||
CcdiBaseStaffAssetInfoExcel excel = buildExcel("320101199201010022", "车辆");
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(assetInfoMapper.selectOwnerCandidatesByBaseStaffIdCards(List.of("320101199201010022")))
|
||||
.thenReturn(List.of());
|
||||
|
||||
service.importAssetInfoAsync(List.of(excel), "task-2", "tester");
|
||||
|
||||
verify(assetInfoMapper, never()).insertBatch(any());
|
||||
ArgumentCaptor<Object> failureCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(valueOperations).set(eq("import:baseStaffAsset:task-2:failures"), failureCaptor.capture(), eq(7L), eq(TimeUnit.DAYS));
|
||||
BaseStaffAssetImportFailureVO failure = (BaseStaffAssetImportFailureVO) ((List<?>) failureCaptor.getValue()).get(0);
|
||||
assertEquals("320101199201010022", failure.getPersonId());
|
||||
assertTrue(failure.getErrorMessage().contains("员工资产导入仅支持员工本人证件号"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getImportStatusAndFailures_shouldUseBaseStaffAssetPrefixes() {
|
||||
when(redisTemplate.opsForHash()).thenReturn(hashOperations);
|
||||
when(redisTemplate.opsForValue()).thenReturn(valueOperations);
|
||||
when(redisTemplate.hasKey("import:baseStaffAsset:task-3")).thenReturn(true);
|
||||
when(hashOperations.entries("import:baseStaffAsset:task-3")).thenReturn(Map.of(
|
||||
"taskId", "task-3",
|
||||
"status", "SUCCESS",
|
||||
"totalCount", 1,
|
||||
"successCount", 1,
|
||||
"failureCount", 0,
|
||||
"progress", 100,
|
||||
"startTime", 1L,
|
||||
"endTime", 2L,
|
||||
"message", "全部成功"
|
||||
));
|
||||
BaseStaffAssetImportFailureVO failureVO = new BaseStaffAssetImportFailureVO();
|
||||
failureVO.setPersonId("320101199001010099");
|
||||
failureVO.setErrorMessage("员工资产导入仅支持员工本人证件号");
|
||||
when(valueOperations.get("import:baseStaffAsset:task-3:failures")).thenReturn(List.of(failureVO));
|
||||
|
||||
ImportStatusVO statusVO = service.getImportStatus("task-3");
|
||||
List<BaseStaffAssetImportFailureVO> failures = service.getImportFailures("task-3");
|
||||
|
||||
assertEquals("task-3", statusVO.getTaskId());
|
||||
assertEquals("SUCCESS", statusVO.getStatus());
|
||||
assertNotNull(failures);
|
||||
assertEquals(1, failures.size());
|
||||
assertEquals("320101199001010099", failures.get(0).getPersonId());
|
||||
}
|
||||
|
||||
private CcdiBaseStaffAssetInfoExcel buildExcel(String personId, String assetMainType) {
|
||||
CcdiBaseStaffAssetInfoExcel excel = new CcdiBaseStaffAssetInfoExcel();
|
||||
excel.setPersonId(personId);
|
||||
excel.setAssetMainType(assetMainType);
|
||||
excel.setAssetSubType(assetMainType + "小类");
|
||||
excel.setAssetName(assetMainType + "名称");
|
||||
excel.setCurrentValue(new BigDecimal("100.00"));
|
||||
excel.setAssetStatus("正常");
|
||||
return excel;
|
||||
}
|
||||
|
||||
private Map<String, String> owner(String personId, String familyId) {
|
||||
return Map.of("personId", personId, "familyId", familyId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user