实现风险明细员工负面征信功能
This commit is contained in:
@@ -1,9 +1,11 @@
|
|||||||
package com.ruoyi.ccdi.project.controller;
|
package com.ruoyi.ccdi.project.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
|
||||||
@@ -115,6 +117,17 @@ public class CcdiProjectOverviewController extends BaseController {
|
|||||||
return AjaxResult.success(pageVO);
|
return AjaxResult.success(pageVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询项目员工负面征信
|
||||||
|
*/
|
||||||
|
@GetMapping("/employee-credit-negative")
|
||||||
|
@Operation(summary = "查询项目员工负面征信")
|
||||||
|
@PreAuthorize("@ss.hasPermi('ccdi:project:query')")
|
||||||
|
public AjaxResult getEmployeeCreditNegative(CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO) {
|
||||||
|
CcdiProjectEmployeeCreditNegativePageVO pageVO = overviewService.getEmployeeCreditNegative(queryDTO);
|
||||||
|
return AjaxResult.success(pageVO);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出涉疑交易明细
|
* 导出涉疑交易明细
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目员工负面征信查询 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectEmployeeCreditNegativeQueryDTO {
|
||||||
|
|
||||||
|
private Long projectId;
|
||||||
|
|
||||||
|
private Integer pageNum;
|
||||||
|
|
||||||
|
private Integer pageSize;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.vo;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目员工负面征信行
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectEmployeeCreditNegativeItemVO {
|
||||||
|
|
||||||
|
private String personName;
|
||||||
|
|
||||||
|
private String personId;
|
||||||
|
|
||||||
|
private String queryDate;
|
||||||
|
|
||||||
|
private Integer civilCnt;
|
||||||
|
|
||||||
|
private BigDecimal civilLmt;
|
||||||
|
|
||||||
|
private Integer enforceCnt;
|
||||||
|
|
||||||
|
private BigDecimal enforceLmt;
|
||||||
|
|
||||||
|
private Integer admCnt;
|
||||||
|
|
||||||
|
private BigDecimal admLmt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.ruoyi.ccdi.project.domain.vo;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 项目员工负面征信分页结果
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CcdiProjectEmployeeCreditNegativePageVO {
|
||||||
|
|
||||||
|
private List<CcdiProjectEmployeeCreditNegativeItemVO> rows = new ArrayList<>();
|
||||||
|
|
||||||
|
private Long total = 0L;
|
||||||
|
}
|
||||||
@@ -2,9 +2,11 @@ package com.ruoyi.ccdi.project.mapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeRiskAggregateVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisBasicInfoVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisBasicInfoVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisObjectRecordVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisObjectRecordVO;
|
||||||
@@ -79,6 +81,18 @@ public interface CcdiProjectOverviewMapper {
|
|||||||
@Param("query") CcdiProjectSuspiciousTransactionQueryDTO query
|
@Param("query") CcdiProjectSuspiciousTransactionQueryDTO query
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询项目员工负面征信
|
||||||
|
*
|
||||||
|
* @param page 分页参数
|
||||||
|
* @param query 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
Page<CcdiProjectEmployeeCreditNegativeItemVO> selectEmployeeCreditNegativePage(
|
||||||
|
Page<CcdiProjectEmployeeCreditNegativeItemVO> page,
|
||||||
|
@Param("query") CcdiProjectEmployeeCreditNegativeQueryDTO query
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询涉疑交易导出列表
|
* 查询涉疑交易导出列表
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package com.ruoyi.ccdi.project.service;
|
package com.ruoyi.ccdi.project.service;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectRiskModelCardsVO;
|
||||||
@@ -97,6 +99,18 @@ public interface ICcdiProjectOverviewService {
|
|||||||
return List.of();
|
return List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询项目员工负面征信
|
||||||
|
*
|
||||||
|
* @param queryDTO 查询条件
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
default CcdiProjectEmployeeCreditNegativePageVO getEmployeeCreditNegative(
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO
|
||||||
|
) {
|
||||||
|
return new CcdiProjectEmployeeCreditNegativePageVO();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重算结果总览员工结果并同步项目风险人数
|
* 重算结果总览员工结果并同步项目风险人数
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ruoyi.ccdi.project.service.impl;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
@@ -9,6 +10,8 @@ import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel
|
|||||||
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementHitTagVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementHitTagVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisAbnormalDetailVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisAbnormalDetailVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisAbnormalGroupVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisAbnormalGroupVO;
|
||||||
@@ -208,6 +211,25 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi
|
|||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CcdiProjectEmployeeCreditNegativePageVO getEmployeeCreditNegative(
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO
|
||||||
|
) {
|
||||||
|
ensureProjectExists(queryDTO.getProjectId());
|
||||||
|
|
||||||
|
Page<CcdiProjectEmployeeCreditNegativeItemVO> page = new Page<>(
|
||||||
|
defaultPageNum(queryDTO.getPageNum()),
|
||||||
|
defaultPageSize(queryDTO.getPageSize())
|
||||||
|
);
|
||||||
|
Page<CcdiProjectEmployeeCreditNegativeItemVO> resultPage =
|
||||||
|
overviewMapper.selectEmployeeCreditNegativePage(page, queryDTO);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativePageVO result = new CcdiProjectEmployeeCreditNegativePageVO();
|
||||||
|
result.setRows(defaultList(resultPage == null ? null : resultPage.getRecords()));
|
||||||
|
result.setTotal(resultPage == null ? 0L : resultPage.getTotal());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void refreshOverviewEmployeeResults(Long projectId, String operator) {
|
public void refreshOverviewEmployeeResults(Long projectId, String operator) {
|
||||||
|
|||||||
@@ -590,6 +590,25 @@
|
|||||||
order by final_result.trxDate desc, final_result.bankStatementId desc
|
order by final_result.trxDate desc, final_result.bankStatementId desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectEmployeeCreditNegativePage"
|
||||||
|
resultType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO">
|
||||||
|
select
|
||||||
|
coalesce(neg.person_name, result.staff_name) as personName,
|
||||||
|
neg.person_id as personId,
|
||||||
|
date_format(neg.query_date, '%Y-%m-%d') as queryDate,
|
||||||
|
ifnull(neg.civil_cnt, 0) as civilCnt,
|
||||||
|
ifnull(neg.civil_lmt, 0) as civilLmt,
|
||||||
|
ifnull(neg.enforce_cnt, 0) as enforceCnt,
|
||||||
|
ifnull(neg.enforce_lmt, 0) as enforceLmt,
|
||||||
|
ifnull(neg.adm_cnt, 0) as admCnt,
|
||||||
|
ifnull(neg.adm_lmt, 0) as admLmt
|
||||||
|
from ccdi_project_overview_employee_result result
|
||||||
|
inner join ccdi_credit_negative_info neg
|
||||||
|
on neg.person_id = result.staff_id_card
|
||||||
|
where result.project_id = #{query.projectId}
|
||||||
|
order by neg.query_date desc, neg.person_id asc
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
|
<select id="selectRiskModelNamesByScope" resultType="java.lang.String">
|
||||||
select
|
select
|
||||||
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName'))) as model_name
|
json_unquote(json_extract(result.model_hit_summary_json, concat('$[', idx.idx, '].modelName'))) as model_name
|
||||||
|
|||||||
@@ -110,6 +110,22 @@ class CcdiProjectOverviewControllerContractTest {
|
|||||||
assertEquals(AjaxResult.class, method.getReturnType());
|
assertEquals(AjaxResult.class, method.getReturnType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeEmployeeCreditNegativeEndpointContract() throws Exception {
|
||||||
|
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
||||||
|
Class<?> queryDtoClass =
|
||||||
|
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO");
|
||||||
|
Method method = controllerClass.getMethod("getEmployeeCreditNegative", queryDtoClass);
|
||||||
|
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||||
|
Operation operation = method.getAnnotation(Operation.class);
|
||||||
|
|
||||||
|
assertNotNull(getMapping);
|
||||||
|
assertEquals("/employee-credit-negative", getMapping.value()[0]);
|
||||||
|
assertNotNull(operation);
|
||||||
|
assertEquals(queryDtoClass, method.getParameterTypes()[0]);
|
||||||
|
assertEquals(AjaxResult.class, method.getReturnType());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExposeSuspiciousTransactionsExportEndpointContract() throws Exception {
|
void shouldExposeSuspiciousTransactionsExportEndpointContract() throws Exception {
|
||||||
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
Class<?> controllerClass = Class.forName("com.ruoyi.ccdi.project.controller.CcdiProjectOverviewController");
|
||||||
@@ -138,4 +154,15 @@ class CcdiProjectOverviewControllerContractTest {
|
|||||||
|
|
||||||
assertEquals(List.of("projectId", "suspiciousType", "pageNum", "pageSize"), fieldNames);
|
assertEquals(List.of("projectId", "suspiciousType", "pageNum", "pageSize"), fieldNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeEmployeeCreditNegativeQueryDtoFields() throws Exception {
|
||||||
|
Class<?> dtoClass = Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO");
|
||||||
|
|
||||||
|
List<String> fieldNames = Arrays.stream(dtoClass.getDeclaredFields())
|
||||||
|
.map(Field::getName)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
assertEquals(List.of("projectId", "pageNum", "pageSize"), fieldNames);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
package com.ruoyi.ccdi.project.controller;
|
package com.ruoyi.ccdi.project.controller;
|
||||||
|
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO;
|
||||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectOverviewDashboardVO;
|
||||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisBasicInfoVO;
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectPersonAnalysisBasicInfoVO;
|
||||||
@@ -15,6 +18,7 @@ import com.ruoyi.ccdi.project.service.ICcdiProjectOverviewService;
|
|||||||
import com.ruoyi.common.core.domain.AjaxResult;
|
import com.ruoyi.common.core.domain.AjaxResult;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
@@ -187,6 +191,45 @@ class CcdiProjectOverviewControllerTest {
|
|||||||
assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
|
assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeEmployeeCreditNegativeEndpoint() throws Exception {
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO = new CcdiProjectEmployeeCreditNegativeQueryDTO();
|
||||||
|
queryDTO.setProjectId(40L);
|
||||||
|
queryDTO.setPageNum(1);
|
||||||
|
queryDTO.setPageSize(5);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativeItemVO item = new CcdiProjectEmployeeCreditNegativeItemVO();
|
||||||
|
item.setPersonName("李四");
|
||||||
|
item.setPersonId("330000000000000001");
|
||||||
|
item.setCivilCnt(1);
|
||||||
|
item.setCivilLmt(new BigDecimal("10000.00"));
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativePageVO pageVO = new CcdiProjectEmployeeCreditNegativePageVO();
|
||||||
|
pageVO.setRows(List.of(item));
|
||||||
|
pageVO.setTotal(1L);
|
||||||
|
when(overviewService.getEmployeeCreditNegative(queryDTO)).thenReturn(pageVO);
|
||||||
|
|
||||||
|
AjaxResult result = controller.getEmployeeCreditNegative(queryDTO);
|
||||||
|
|
||||||
|
assertEquals(200, result.get("code"));
|
||||||
|
assertEquals(pageVO, result.get("data"));
|
||||||
|
verify(overviewService).getEmployeeCreditNegative(queryDTO);
|
||||||
|
|
||||||
|
Method method = CcdiProjectOverviewController.class.getMethod(
|
||||||
|
"getEmployeeCreditNegative",
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO.class
|
||||||
|
);
|
||||||
|
GetMapping getMapping = method.getAnnotation(GetMapping.class);
|
||||||
|
PreAuthorize preAuthorize = method.getAnnotation(PreAuthorize.class);
|
||||||
|
Operation operation = method.getAnnotation(Operation.class);
|
||||||
|
|
||||||
|
assertNotNull(getMapping);
|
||||||
|
assertEquals("/employee-credit-negative", getMapping.value()[0]);
|
||||||
|
assertNotNull(preAuthorize);
|
||||||
|
assertEquals("@ss.hasPermi('ccdi:project:query')", preAuthorize.value());
|
||||||
|
assertNotNull(operation);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void shouldExposeSuspiciousTransactionsExportEndpoint() throws Exception {
|
void shouldExposeSuspiciousTransactionsExportEndpoint() throws Exception {
|
||||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|||||||
@@ -84,6 +84,18 @@ class CcdiProjectOverviewMapperSqlTest {
|
|||||||
assertTrue(suspiciousSql.contains("hasNameListHit"), suspiciousSql);
|
assertTrue(suspiciousSql.contains("hasNameListHit"), suspiciousSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldExposeEmployeeCreditNegativeQuery() throws Exception {
|
||||||
|
String xml = Files.readString(Path.of("src/main/resources/mapper/ccdi/project/CcdiProjectOverviewMapper.xml"));
|
||||||
|
String employeeCreditSql = extractSelect(xml, "selectEmployeeCreditNegativePage");
|
||||||
|
|
||||||
|
assertTrue(employeeCreditSql.contains("from ccdi_project_overview_employee_result"), employeeCreditSql);
|
||||||
|
assertTrue(employeeCreditSql.contains("inner join ccdi_credit_negative_info"), employeeCreditSql);
|
||||||
|
assertTrue(employeeCreditSql.contains("result.project_id = #{query.projectId}"), employeeCreditSql);
|
||||||
|
assertTrue(employeeCreditSql.contains("order by neg.query_date desc, neg.person_id asc"), employeeCreditSql);
|
||||||
|
assertFalse(employeeCreditSql.contains("ccdi_debts_info"), employeeCreditSql);
|
||||||
|
}
|
||||||
|
|
||||||
private String extractSelect(String xml, String selectId) {
|
private String extractSelect(String xml, String selectId) {
|
||||||
String start = "<select id=\"" + selectId + "\"";
|
String start = "<select id=\"" + selectId + "\"";
|
||||||
int startIndex = xml.indexOf(start);
|
int startIndex = xml.indexOf(start);
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ class CcdiProjectOverviewServiceStructureTest {
|
|||||||
"getSuspiciousTransactions",
|
"getSuspiciousTransactions",
|
||||||
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO")
|
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO")
|
||||||
));
|
));
|
||||||
|
assertNotNull(clazz.getMethod(
|
||||||
|
"getEmployeeCreditNegative",
|
||||||
|
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO")
|
||||||
|
));
|
||||||
assertNotNull(clazz.getMethod(
|
assertNotNull(clazz.getMethod(
|
||||||
"exportSuspiciousTransactions",
|
"exportSuspiciousTransactions",
|
||||||
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO")
|
Class.forName("com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO")
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
package com.ruoyi.ccdi.project.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||||
|
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO;
|
||||||
|
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativePageVO;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper;
|
||||||
|
import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewMapper;
|
||||||
|
import com.ruoyi.common.exception.ServiceException;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@ExtendWith(MockitoExtension.class)
|
||||||
|
class CcdiProjectOverviewServiceEmployeeCreditNegativeTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private CcdiProjectOverviewServiceImpl service;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewMapper overviewMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectMapper projectMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewEmployeeResultMapper overviewEmployeeResultMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiBankTagResultMapper bankTagResultMapper;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private CcdiProjectOverviewEmployeeResultBuilder overviewEmployeeResultBuilder;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldReturnEmployeeCreditNegativePage() {
|
||||||
|
CcdiProject project = new CcdiProject();
|
||||||
|
project.setProjectId(40L);
|
||||||
|
when(projectMapper.selectById(40L)).thenReturn(project);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativeItemVO item = new CcdiProjectEmployeeCreditNegativeItemVO();
|
||||||
|
item.setPersonName("李四");
|
||||||
|
item.setPersonId("330000000000000001");
|
||||||
|
item.setQueryDate("2026-03-20");
|
||||||
|
item.setCivilCnt(1);
|
||||||
|
item.setCivilLmt(new BigDecimal("10000.00"));
|
||||||
|
|
||||||
|
Page<CcdiProjectEmployeeCreditNegativeItemVO> page = new Page<>(1, 5);
|
||||||
|
page.setRecords(List.of(item));
|
||||||
|
page.setTotal(1L);
|
||||||
|
when(overviewMapper.selectEmployeeCreditNegativePage(any(Page.class), any(CcdiProjectEmployeeCreditNegativeQueryDTO.class)))
|
||||||
|
.thenReturn(page);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO = new CcdiProjectEmployeeCreditNegativeQueryDTO();
|
||||||
|
queryDTO.setProjectId(40L);
|
||||||
|
queryDTO.setPageNum(1);
|
||||||
|
queryDTO.setPageSize(5);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativePageVO result = service.getEmployeeCreditNegative(queryDTO);
|
||||||
|
|
||||||
|
assertEquals(1, result.getRows().size());
|
||||||
|
assertEquals(1L, result.getTotal());
|
||||||
|
assertEquals("李四", result.getRows().getFirst().getPersonName());
|
||||||
|
verify(overviewMapper).selectEmployeeCreditNegativePage(
|
||||||
|
any(Page.class),
|
||||||
|
argThat(query -> query.getProjectId().equals(40L))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldThrowWhenEmployeeCreditNegativeProjectDoesNotExist() {
|
||||||
|
when(projectMapper.selectById(99L)).thenReturn(null);
|
||||||
|
|
||||||
|
CcdiProjectEmployeeCreditNegativeQueryDTO queryDTO = new CcdiProjectEmployeeCreditNegativeQueryDTO();
|
||||||
|
queryDTO.setProjectId(99L);
|
||||||
|
|
||||||
|
assertThrows(ServiceException.class, () -> service.getEmployeeCreditNegative(queryDTO));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
# 风险明细员工负面征信实施记录
|
||||||
|
|
||||||
|
## 本次改动
|
||||||
|
|
||||||
|
### 后端
|
||||||
|
|
||||||
|
- 新增项目员工负面征信查询 DTO:
|
||||||
|
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/dto/CcdiProjectEmployeeCreditNegativeQueryDTO.java`
|
||||||
|
- 新增项目员工负面征信分页 VO:
|
||||||
|
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativeItemVO.java`
|
||||||
|
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectEmployeeCreditNegativePageVO.java`
|
||||||
|
- 在结果总览链路新增接口:
|
||||||
|
- `GET /ccdi/project/overview/employee-credit-negative`
|
||||||
|
- 在 `CcdiProjectOverviewMapper.xml` 新增 `selectEmployeeCreditNegativePage`
|
||||||
|
- 查询口径固定为:
|
||||||
|
- 员工范围来自 `ccdi_project_overview_employee_result`
|
||||||
|
- 仅关联 `ccdi_credit_negative_info`
|
||||||
|
- 不接入 `ccdi_debts_info`
|
||||||
|
- 排序按 `query_date desc, person_id asc`
|
||||||
|
|
||||||
|
### 前端
|
||||||
|
|
||||||
|
- 在 `ruoyi-ui/src/api/ccdi/projectOverview.js` 新增 `getOverviewEmployeeCreditNegative`
|
||||||
|
- 在 `PreliminaryCheck.vue` 初次加载时并行拉取员工负面征信初始数据
|
||||||
|
- 在 `preliminaryCheck.mock.js` 补齐员工负面征信 mock 结构与归一化函数
|
||||||
|
- 在 `RiskDetailSection.vue` 新增 `员工负面征信信息` 区块
|
||||||
|
- 新区块支持独立分页、空态和金额展示
|
||||||
|
- 不新增详情弹窗,不做展开,不混入负债明细
|
||||||
|
|
||||||
|
## 测试与验证
|
||||||
|
|
||||||
|
### 后端验证
|
||||||
|
|
||||||
|
执行命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
mvn -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false \
|
||||||
|
-Dtest=CcdiProjectOverviewServiceStructureTest,CcdiProjectOverviewControllerContractTest,CcdiProjectOverviewControllerTest,CcdiProjectOverviewServiceEmployeeCreditNegativeTest,CcdiProjectOverviewMapperSqlTest \
|
||||||
|
test
|
||||||
|
```
|
||||||
|
|
||||||
|
结果:
|
||||||
|
|
||||||
|
- 通过
|
||||||
|
|
||||||
|
### 前端验证
|
||||||
|
|
||||||
|
执行命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
node ruoyi-ui/tests/unit/project-overview-api.test.js
|
||||||
|
node ruoyi-ui/tests/unit/preliminary-check-api-integration.test.js
|
||||||
|
node ruoyi-ui/tests/unit/preliminary-check-credit-negative-load.test.js
|
||||||
|
node ruoyi-ui/tests/unit/risk-detail-employee-credit-negative-layout.test.js
|
||||||
|
node ruoyi-ui/tests/unit/risk-detail-employee-credit-negative-pagination.test.js
|
||||||
|
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-layout.test.js
|
||||||
|
node ruoyi-ui/tests/unit/risk-detail-suspicious-transaction-detail-dialog.test.js
|
||||||
|
```
|
||||||
|
|
||||||
|
结果:
|
||||||
|
|
||||||
|
- 通过
|
||||||
|
|
||||||
|
### 构建验证
|
||||||
|
|
||||||
|
执行命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd ruoyi-ui && npm run build:prod
|
||||||
|
```
|
||||||
|
|
||||||
|
结果:
|
||||||
|
|
||||||
|
- 构建成功
|
||||||
|
- 存在仓库既有 bundle 体积告警,但无新增编译错误
|
||||||
|
|
||||||
|
## 备注
|
||||||
|
|
||||||
|
- 本次未启动前端 dev server 或后端本地服务,因此无需额外清理测试进程
|
||||||
|
- `.DS_Store` 与 `.superpowers/` 临时文件未纳入本次提交
|
||||||
@@ -63,3 +63,15 @@ export function getOverviewSuspiciousTransactions(params) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getOverviewEmployeeCreditNegative(params) {
|
||||||
|
return request({
|
||||||
|
url: '/ccdi/project/overview/employee-credit-negative',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
projectId: params.projectId,
|
||||||
|
pageNum: params.pageNum,
|
||||||
|
pageSize: params.pageSize
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import {
|
|||||||
} from "./preliminaryCheck.mock";
|
} from "./preliminaryCheck.mock";
|
||||||
import {
|
import {
|
||||||
getOverviewDashboard,
|
getOverviewDashboard,
|
||||||
|
getOverviewEmployeeCreditNegative,
|
||||||
getOverviewRiskPeople,
|
getOverviewRiskPeople,
|
||||||
getOverviewRiskModelCards,
|
getOverviewRiskModelCards,
|
||||||
getOverviewSuspiciousTransactions,
|
getOverviewSuspiciousTransactions,
|
||||||
@@ -198,7 +199,7 @@ export default {
|
|||||||
this.selectedModelCodes = [];
|
this.selectedModelCodes = [];
|
||||||
this.resetProjectAnalysisDialog();
|
this.resetProjectAnalysisDialog();
|
||||||
try {
|
try {
|
||||||
const [dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes] = await Promise.all([
|
const [dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes, creditNegativeRes] = await Promise.all([
|
||||||
getOverviewDashboard(this.projectId),
|
getOverviewDashboard(this.projectId),
|
||||||
getOverviewRiskPeople(this.projectId),
|
getOverviewRiskPeople(this.projectId),
|
||||||
getOverviewRiskModelCards(this.projectId),
|
getOverviewRiskModelCards(this.projectId),
|
||||||
@@ -208,11 +209,17 @@ export default {
|
|||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 5,
|
pageSize: 5,
|
||||||
}),
|
}),
|
||||||
|
getOverviewEmployeeCreditNegative({
|
||||||
|
projectId: this.projectId,
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 5,
|
||||||
|
}),
|
||||||
]);
|
]);
|
||||||
const dashboardData = (dashboardRes && dashboardRes.data) || {};
|
const dashboardData = (dashboardRes && dashboardRes.data) || {};
|
||||||
const riskPeopleData = (riskPeopleRes && riskPeopleRes.data) || {};
|
const riskPeopleData = (riskPeopleRes && riskPeopleRes.data) || {};
|
||||||
const riskModelCardsData = (riskModelCardsRes && riskModelCardsRes.data) || {};
|
const riskModelCardsData = (riskModelCardsRes && riskModelCardsRes.data) || {};
|
||||||
const suspiciousData = (suspiciousRes && suspiciousRes.data) || {};
|
const suspiciousData = (suspiciousRes && suspiciousRes.data) || {};
|
||||||
|
const creditNegativeData = (creditNegativeRes && creditNegativeRes.data) || {};
|
||||||
|
|
||||||
this.realData = createOverviewLoadedData({
|
this.realData = createOverviewLoadedData({
|
||||||
projectId: this.projectId,
|
projectId: this.projectId,
|
||||||
@@ -220,6 +227,7 @@ export default {
|
|||||||
riskPeopleData,
|
riskPeopleData,
|
||||||
riskModelCardsData,
|
riskModelCardsData,
|
||||||
suspiciousData,
|
suspiciousData,
|
||||||
|
creditNegativeData,
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasOverviewData = Boolean(
|
const hasOverviewData = Boolean(
|
||||||
|
|||||||
@@ -131,6 +131,60 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="block">
|
||||||
|
<div class="block-header">
|
||||||
|
<div>
|
||||||
|
<div class="block-title">员工负面征信信息</div>
|
||||||
|
<div class="block-subtitle">展示当前项目员工的负面征信信息</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-table
|
||||||
|
v-loading="employeeCreditNegativeLoading"
|
||||||
|
:data="employeeCreditNegativeList"
|
||||||
|
class="result-table"
|
||||||
|
>
|
||||||
|
<template slot="empty">
|
||||||
|
<el-empty :image-size="96" description="当前项目暂无员工负面征信信息" />
|
||||||
|
</template>
|
||||||
|
<el-table-column prop="personName" label="员工姓名" min-width="140" />
|
||||||
|
<el-table-column label="身份证号" min-width="180" show-overflow-tooltip>
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ formatIdCard(scope.row.personId) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="queryDate" label="最近征信查询日期" min-width="160" />
|
||||||
|
<el-table-column prop="civilCnt" label="民事案件笔数" min-width="120" align="center" />
|
||||||
|
<el-table-column label="民事案件金额" min-width="140" align="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ formatAmount(scope.row.civilLmt) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="enforceCnt" label="强制执行笔数" min-width="120" align="center" />
|
||||||
|
<el-table-column label="强制执行金额" min-width="140" align="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ formatAmount(scope.row.enforceLmt) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="admCnt" label="行政处罚笔数" min-width="120" align="center" />
|
||||||
|
<el-table-column label="行政处罚金额" min-width="140" align="right">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
{{ formatAmount(scope.row.admLmt) }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<pagination
|
||||||
|
v-show="employeeCreditNegativeTotal > 0"
|
||||||
|
:total="employeeCreditNegativeTotal"
|
||||||
|
:page.sync="employeeCreditNegativePageNum"
|
||||||
|
:limit.sync="employeeCreditNegativePageSize"
|
||||||
|
:page-sizes="[5]"
|
||||||
|
layout="total, prev, pager, next, jumper"
|
||||||
|
@pagination="handleEmployeeCreditNegativePageChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<div class="block-header">
|
<div class="block-header">
|
||||||
<div>
|
<div>
|
||||||
@@ -265,7 +319,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getOverviewSuspiciousTransactions } from "@/api/ccdi/projectOverview";
|
import {
|
||||||
|
getOverviewEmployeeCreditNegative,
|
||||||
|
getOverviewSuspiciousTransactions,
|
||||||
|
} from "@/api/ccdi/projectOverview";
|
||||||
import { getBankStatementDetail } from "@/api/ccdiProjectBankStatement";
|
import { getBankStatementDetail } from "@/api/ccdiProjectBankStatement";
|
||||||
|
|
||||||
const SUSPICIOUS_TYPE_OPTIONS = [
|
const SUSPICIOUS_TYPE_OPTIONS = [
|
||||||
@@ -335,6 +392,11 @@ export default {
|
|||||||
suspiciousPageSize: 5,
|
suspiciousPageSize: 5,
|
||||||
suspiciousTotal: 0,
|
suspiciousTotal: 0,
|
||||||
suspiciousTransactionList: [],
|
suspiciousTransactionList: [],
|
||||||
|
employeeCreditNegativeLoading: false,
|
||||||
|
employeeCreditNegativePageNum: 1,
|
||||||
|
employeeCreditNegativePageSize: 5,
|
||||||
|
employeeCreditNegativeTotal: 0,
|
||||||
|
employeeCreditNegativeList: [],
|
||||||
projectId: null,
|
projectId: null,
|
||||||
statementDetailCache: {},
|
statementDetailCache: {},
|
||||||
};
|
};
|
||||||
@@ -358,9 +420,15 @@ export default {
|
|||||||
this.suspiciousPageNum = 1;
|
this.suspiciousPageNum = 1;
|
||||||
this.suspiciousPageSize = 5;
|
this.suspiciousPageSize = 5;
|
||||||
this.suspiciousTotal = Number(value && value.total) || 0;
|
this.suspiciousTotal = Number(value && value.total) || 0;
|
||||||
|
this.employeeCreditNegativePageNum = 1;
|
||||||
|
this.employeeCreditNegativePageSize = 5;
|
||||||
|
this.employeeCreditNegativeTotal = Number(value && value.employeeCreditNegativeTotal) || 0;
|
||||||
const rows = Array.isArray(value && value.suspiciousTransactionList)
|
const rows = Array.isArray(value && value.suspiciousTransactionList)
|
||||||
? value.suspiciousTransactionList
|
? value.suspiciousTransactionList
|
||||||
: [];
|
: [];
|
||||||
|
this.employeeCreditNegativeList = Array.isArray(value && value.employeeCreditNegativeList)
|
||||||
|
? value.employeeCreditNegativeList
|
||||||
|
: [];
|
||||||
this.hydrateSuspiciousRows(rows);
|
this.hydrateSuspiciousRows(rows);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -380,6 +448,15 @@ export default {
|
|||||||
}
|
}
|
||||||
await this.loadSuspiciousTransactions();
|
await this.loadSuspiciousTransactions();
|
||||||
},
|
},
|
||||||
|
async handleEmployeeCreditNegativePageChange(pageInfo) {
|
||||||
|
if (typeof pageInfo === "number") {
|
||||||
|
this.employeeCreditNegativePageNum = pageInfo;
|
||||||
|
} else {
|
||||||
|
this.employeeCreditNegativePageNum = pageInfo.page;
|
||||||
|
this.employeeCreditNegativePageSize = 5;
|
||||||
|
}
|
||||||
|
await this.loadEmployeeCreditNegative();
|
||||||
|
},
|
||||||
async loadSuspiciousTransactions() {
|
async loadSuspiciousTransactions() {
|
||||||
if (!this.projectId) {
|
if (!this.projectId) {
|
||||||
this.suspiciousTransactionList = [];
|
this.suspiciousTransactionList = [];
|
||||||
@@ -407,6 +484,33 @@ export default {
|
|||||||
this.suspiciousLoading = false;
|
this.suspiciousLoading = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async loadEmployeeCreditNegative() {
|
||||||
|
if (!this.projectId) {
|
||||||
|
this.employeeCreditNegativeList = [];
|
||||||
|
this.employeeCreditNegativeTotal = 0;
|
||||||
|
this.employeeCreditNegativeLoading = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.employeeCreditNegativeLoading = true;
|
||||||
|
try {
|
||||||
|
const response = await getOverviewEmployeeCreditNegative({
|
||||||
|
projectId: this.projectId,
|
||||||
|
pageNum: this.employeeCreditNegativePageNum,
|
||||||
|
pageSize: 5,
|
||||||
|
});
|
||||||
|
const data = (response && response.data) || {};
|
||||||
|
this.employeeCreditNegativeList = Array.isArray(data.rows) ? data.rows : [];
|
||||||
|
this.employeeCreditNegativeTotal = Number(data.total) || 0;
|
||||||
|
} catch (error) {
|
||||||
|
this.employeeCreditNegativeList = [];
|
||||||
|
this.employeeCreditNegativeTotal = 0;
|
||||||
|
this.$message.error("加载员工负面征信信息失败");
|
||||||
|
console.error("加载员工负面征信信息失败", error);
|
||||||
|
} finally {
|
||||||
|
this.employeeCreditNegativeLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
async hydrateSuspiciousRows(rows) {
|
async hydrateSuspiciousRows(rows) {
|
||||||
const safeRows = Array.isArray(rows) ? rows : [];
|
const safeRows = Array.isArray(rows) ? rows : [];
|
||||||
if (!safeRows.length) {
|
if (!safeRows.length) {
|
||||||
@@ -526,6 +630,12 @@ export default {
|
|||||||
}
|
}
|
||||||
return String(value);
|
return String(value);
|
||||||
},
|
},
|
||||||
|
formatIdCard(value) {
|
||||||
|
if (value === null || value === undefined || value === "") {
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
return String(value);
|
||||||
|
},
|
||||||
formatAmount(value) {
|
formatAmount(value) {
|
||||||
if (value === null || value === undefined || value === "") {
|
if (value === null || value === undefined || value === "") {
|
||||||
return "-";
|
return "-";
|
||||||
|
|||||||
@@ -118,6 +118,31 @@ export const mockOverviewData = {
|
|||||||
actionLabel: "查看详情",
|
actionLabel: "查看详情",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
employeeCreditNegativeTotal: 2,
|
||||||
|
employeeCreditNegativeList: [
|
||||||
|
{
|
||||||
|
personName: "李四",
|
||||||
|
personId: "331081199003230321",
|
||||||
|
queryDate: "2026-03-20",
|
||||||
|
civilCnt: 1,
|
||||||
|
civilLmt: 120000,
|
||||||
|
enforceCnt: 0,
|
||||||
|
enforceLmt: 0,
|
||||||
|
admCnt: 0,
|
||||||
|
admLmt: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
personName: "王五",
|
||||||
|
personId: "331081199003231077",
|
||||||
|
queryDate: "2026-03-18",
|
||||||
|
civilCnt: 0,
|
||||||
|
civilLmt: 0,
|
||||||
|
enforceCnt: 2,
|
||||||
|
enforceLmt: 50000,
|
||||||
|
admCnt: 1,
|
||||||
|
admLmt: 2000,
|
||||||
|
},
|
||||||
|
],
|
||||||
transactionList: [
|
transactionList: [
|
||||||
{
|
{
|
||||||
tradeDate: "2024-01-15",
|
tradeDate: "2024-01-15",
|
||||||
@@ -392,7 +417,23 @@ function normalizeSuspiciousTransactions(rows) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createOverviewLoadedData({ projectId, dashboardData, riskPeopleData, riskModelCardsData, suspiciousData } = {}) {
|
function normalizeEmployeeCreditNegativeRows(rows) {
|
||||||
|
if (!Array.isArray(rows)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return rows.map((item) => ({
|
||||||
|
...item,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createOverviewLoadedData({
|
||||||
|
projectId,
|
||||||
|
dashboardData,
|
||||||
|
riskPeopleData,
|
||||||
|
riskModelCardsData,
|
||||||
|
suspiciousData,
|
||||||
|
creditNegativeData,
|
||||||
|
} = {}) {
|
||||||
return {
|
return {
|
||||||
...mockOverviewData,
|
...mockOverviewData,
|
||||||
summary: {
|
summary: {
|
||||||
@@ -420,6 +461,8 @@ export function createOverviewLoadedData({ projectId, dashboardData, riskPeopleD
|
|||||||
suspiciousTransactionList: normalizeSuspiciousTransactions(suspiciousData && suspiciousData.rows),
|
suspiciousTransactionList: normalizeSuspiciousTransactions(suspiciousData && suspiciousData.rows),
|
||||||
suspiciousType: "ALL",
|
suspiciousType: "ALL",
|
||||||
total: suspiciousData && suspiciousData.total ? suspiciousData.total : 0,
|
total: suspiciousData && suspiciousData.total ? suspiciousData.total : 0,
|
||||||
|
employeeCreditNegativeList: normalizeEmployeeCreditNegativeRows(creditNegativeData && creditNegativeData.rows),
|
||||||
|
employeeCreditNegativeTotal: creditNegativeData && creditNegativeData.total ? creditNegativeData.total : 0,
|
||||||
transactionList: normalizeSuspiciousTransactions(suspiciousData && suspiciousData.rows),
|
transactionList: normalizeSuspiciousTransactions(suspiciousData && suspiciousData.rows),
|
||||||
abnormalAccountList: [],
|
abnormalAccountList: [],
|
||||||
},
|
},
|
||||||
@@ -448,6 +491,8 @@ export const mockOverviewStateData = {
|
|||||||
suspiciousTransactionList: [],
|
suspiciousTransactionList: [],
|
||||||
suspiciousType: "ALL",
|
suspiciousType: "ALL",
|
||||||
total: 0,
|
total: 0,
|
||||||
|
employeeCreditNegativeList: [],
|
||||||
|
employeeCreditNegativeTotal: 0,
|
||||||
transactionList: [],
|
transactionList: [],
|
||||||
abnormalAccountList: [],
|
abnormalAccountList: [],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ const apiSource = fs.readFileSync(
|
|||||||
"getOverviewDashboard",
|
"getOverviewDashboard",
|
||||||
"getOverviewRiskPeople",
|
"getOverviewRiskPeople",
|
||||||
"getOverviewRiskModelCards",
|
"getOverviewRiskModelCards",
|
||||||
|
"getOverviewEmployeeCreditNegative",
|
||||||
"loadOverviewData",
|
"loadOverviewData",
|
||||||
"Promise.all",
|
"Promise.all",
|
||||||
].forEach((token) => assert(source.includes(token), token));
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
@@ -24,14 +25,16 @@ assert(!source.includes("topRiskPeopleRes"), "页面不应再处理TOP10响应")
|
|||||||
assert(!source.includes("topRiskPeopleData"), "页面不应再处理TOP10数据");
|
assert(!source.includes("topRiskPeopleData"), "页面不应再处理TOP10数据");
|
||||||
|
|
||||||
const loadOverviewDataBlock = source.match(
|
const loadOverviewDataBlock = source.match(
|
||||||
/const \[dashboardRes, riskPeopleRes, riskModelCardsRes\] = await Promise\.all\(\[([\s\S]*?)\]\);/m
|
/const \[dashboardRes, riskPeopleRes, riskModelCardsRes, suspiciousRes, creditNegativeRes\] = await Promise\.all\(\[([\s\S]*?)\]\);/m
|
||||||
);
|
);
|
||||||
|
|
||||||
assert(loadOverviewDataBlock, "入口页应继续并发请求仪表盘、风险人员和模型卡片");
|
assert(loadOverviewDataBlock, "入口页应继续并发请求仪表盘、风险人员、模型卡片、涉疑交易和员工负面征信");
|
||||||
[
|
[
|
||||||
"getOverviewDashboard(this.projectId)",
|
"getOverviewDashboard(this.projectId)",
|
||||||
"getOverviewRiskPeople(this.projectId)",
|
"getOverviewRiskPeople(this.projectId)",
|
||||||
"getOverviewRiskModelCards(this.projectId)",
|
"getOverviewRiskModelCards(this.projectId)",
|
||||||
|
"getOverviewSuspiciousTransactions({",
|
||||||
|
"getOverviewEmployeeCreditNegative({",
|
||||||
].forEach((token) => assert(loadOverviewDataBlock[0].includes(token), token));
|
].forEach((token) => assert(loadOverviewDataBlock[0].includes(token), token));
|
||||||
|
|
||||||
[
|
[
|
||||||
@@ -39,6 +42,7 @@ assert(loadOverviewDataBlock, "入口页应继续并发请求仪表盘、风险
|
|||||||
"dashboardData",
|
"dashboardData",
|
||||||
"riskPeopleData",
|
"riskPeopleData",
|
||||||
"riskModelCardsData",
|
"riskModelCardsData",
|
||||||
|
"creditNegativeData",
|
||||||
].forEach((token) => assert(source.includes(token), token));
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
|
|
||||||
["employeeResult", "resultTable", "topRiskList"].forEach((token) =>
|
["employeeResult", "resultTable", "topRiskList"].forEach((token) =>
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
const assert = require("assert");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const source = fs.readFileSync(
|
||||||
|
path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/PreliminaryCheck.vue"),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
const mockSource = fs.readFileSync(
|
||||||
|
path.resolve(__dirname, "../../src/views/ccdiProject/components/detail/preliminaryCheck.mock.js"),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
[
|
||||||
|
"getOverviewEmployeeCreditNegative",
|
||||||
|
"creditNegativeRes",
|
||||||
|
"creditNegativeData",
|
||||||
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
|
|
||||||
|
[
|
||||||
|
"normalizeEmployeeCreditNegativeRows",
|
||||||
|
"employeeCreditNegativeList",
|
||||||
|
"employeeCreditNegativeTotal",
|
||||||
|
].forEach((token) => assert(mockSource.includes(token), token));
|
||||||
@@ -13,11 +13,13 @@ const source = fs.readFileSync(
|
|||||||
"getOverviewRiskModelCards",
|
"getOverviewRiskModelCards",
|
||||||
"getOverviewRiskModelPeople",
|
"getOverviewRiskModelPeople",
|
||||||
"getOverviewSuspiciousTransactions",
|
"getOverviewSuspiciousTransactions",
|
||||||
|
"getOverviewEmployeeCreditNegative",
|
||||||
"/ccdi/project/overview/dashboard",
|
"/ccdi/project/overview/dashboard",
|
||||||
"/ccdi/project/overview/risk-people",
|
"/ccdi/project/overview/risk-people",
|
||||||
"/ccdi/project/overview/risk-models/cards",
|
"/ccdi/project/overview/risk-models/cards",
|
||||||
"/ccdi/project/overview/risk-models/people",
|
"/ccdi/project/overview/risk-models/people",
|
||||||
"/ccdi/project/overview/suspicious-transactions",
|
"/ccdi/project/overview/suspicious-transactions",
|
||||||
|
"/ccdi/project/overview/employee-credit-negative",
|
||||||
].forEach((token) => assert(source.includes(token), token));
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
|
|
||||||
[
|
[
|
||||||
@@ -54,6 +56,18 @@ assert(suspiciousTransactionsFn, "应新增涉疑交易接口参数透传逻辑"
|
|||||||
"pageSize: params.pageSize",
|
"pageSize: params.pageSize",
|
||||||
].forEach((token) => assert(suspiciousTransactionsFn[0].includes(token), token));
|
].forEach((token) => assert(suspiciousTransactionsFn[0].includes(token), token));
|
||||||
|
|
||||||
|
const employeeCreditNegativeFn = source.match(
|
||||||
|
/export function getOverviewEmployeeCreditNegative\(params\) \{[\s\S]*?params:\s*\{([\s\S]*?)\}\s*\}\s*\)/m
|
||||||
|
);
|
||||||
|
|
||||||
|
assert(employeeCreditNegativeFn, "应新增员工负面征信接口参数透传逻辑");
|
||||||
|
|
||||||
|
[
|
||||||
|
"projectId: params.projectId",
|
||||||
|
"pageNum: params.pageNum",
|
||||||
|
"pageSize: params.pageSize",
|
||||||
|
].forEach((token) => assert(employeeCreditNegativeFn[0].includes(token), token));
|
||||||
|
|
||||||
["employeeResult", "resultTable", "overview/result"].forEach((token) =>
|
["employeeResult", "resultTable", "overview/result"].forEach((token) =>
|
||||||
assert(!source.includes(token), `前端 API 契约不应感知结果表实现:${token}`)
|
assert(!source.includes(token), `前端 API 契约不应感知结果表实现:${token}`)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
const assert = require("assert");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const source = fs.readFileSync(
|
||||||
|
path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"../../src/views/ccdiProject/components/detail/RiskDetailSection.vue"
|
||||||
|
),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
[
|
||||||
|
"员工负面征信信息",
|
||||||
|
"展示当前项目员工的负面征信信息",
|
||||||
|
"员工姓名",
|
||||||
|
"身份证号",
|
||||||
|
"最近征信查询日期",
|
||||||
|
"民事案件笔数",
|
||||||
|
"民事案件金额",
|
||||||
|
"强制执行笔数",
|
||||||
|
"强制执行金额",
|
||||||
|
"行政处罚笔数",
|
||||||
|
"行政处罚金额",
|
||||||
|
"当前项目暂无员工负面征信信息",
|
||||||
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
const assert = require("assert");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
const source = fs.readFileSync(
|
||||||
|
path.resolve(
|
||||||
|
__dirname,
|
||||||
|
"../../src/views/ccdiProject/components/detail/RiskDetailSection.vue"
|
||||||
|
),
|
||||||
|
"utf8"
|
||||||
|
);
|
||||||
|
|
||||||
|
[
|
||||||
|
"employeeCreditNegativeList",
|
||||||
|
"employeeCreditNegativeTotal",
|
||||||
|
"employeeCreditNegativePageNum",
|
||||||
|
"employeeCreditNegativePageSize",
|
||||||
|
"employeeCreditNegativeLoading",
|
||||||
|
"loadEmployeeCreditNegative",
|
||||||
|
"handleEmployeeCreditNegativePageChange",
|
||||||
|
"getOverviewEmployeeCreditNegative",
|
||||||
|
].forEach((token) => assert(source.includes(token), token));
|
||||||
Reference in New Issue
Block a user