Compare commits
3 Commits
8fa1b6e098
...
fa9673c8c4
| Author | SHA1 | Date | |
|---|---|---|---|
| fa9673c8c4 | |||
| 6b0c83024e | |||
| a95258fe81 |
@@ -15,7 +15,5 @@ public class CcdiCreditInfoQueryDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String name;
|
||||
private String staffId;
|
||||
private String idCard;
|
||||
private String maintained;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,8 @@ public class CreditInfoListVO implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Long staffId;
|
||||
private String name;
|
||||
private String idCard;
|
||||
private String deptName;
|
||||
private Date queryDate;
|
||||
private Long debtCount;
|
||||
private BigDecimal debtTotalAmount;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
package com.ruoyi.info.collection.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
||||
import com.ruoyi.info.collection.domain.CcdiCreditNegativeInfo;
|
||||
import com.ruoyi.info.collection.domain.CcdiDebtsInfo;
|
||||
import com.ruoyi.info.collection.domain.dto.CcdiCreditInfoQueryDTO;
|
||||
@@ -12,7 +10,6 @@ import com.ruoyi.info.collection.domain.vo.CreditInfoListVO;
|
||||
import com.ruoyi.info.collection.domain.vo.CreditInfoNegativeVO;
|
||||
import com.ruoyi.info.collection.domain.vo.CreditInfoUploadFailureVO;
|
||||
import com.ruoyi.info.collection.domain.vo.CreditInfoUploadResultVO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiCreditInfoQueryMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiCreditNegativeInfoMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiDebtsInfoMapper;
|
||||
@@ -45,9 +42,6 @@ public class CcdiCreditInfoServiceImpl implements ICcdiCreditInfoService {
|
||||
@Resource
|
||||
private CreditInfoPayloadAssembler assembler;
|
||||
|
||||
@Resource
|
||||
private CcdiBaseStaffMapper baseStaffMapper;
|
||||
|
||||
@Resource
|
||||
private CcdiDebtsInfoMapper debtsInfoMapper;
|
||||
|
||||
@@ -156,7 +150,7 @@ public class CcdiCreditInfoServiceImpl implements ICcdiCreditInfoService {
|
||||
String personId = stringValue(header.get("query_cert_no"));
|
||||
String personName = stringValue(header.get("query_cust_name"));
|
||||
LocalDate queryDate = parseQueryDate(stringValue(header.get("report_time")));
|
||||
ensureStaffExists(personId);
|
||||
ensurePersonIdPresent(personId);
|
||||
ensureLatestQueryDate(personId, queryDate);
|
||||
|
||||
List<CcdiDebtsInfo> debts = assembler.buildDebts(personId, personName, queryDate, payload);
|
||||
@@ -209,15 +203,9 @@ public class CcdiCreditInfoServiceImpl implements ICcdiCreditInfoService {
|
||||
return header;
|
||||
}
|
||||
|
||||
private void ensureStaffExists(String personId) {
|
||||
private void ensurePersonIdPresent(String personId) {
|
||||
if (isBlank(personId)) {
|
||||
throw new RuntimeException("征信解析结果缺少员工身份证号");
|
||||
}
|
||||
CcdiBaseStaff staff = baseStaffMapper.selectOne(new LambdaQueryWrapper<CcdiBaseStaff>()
|
||||
.eq(CcdiBaseStaff::getIdCard, personId)
|
||||
.last("LIMIT 1"));
|
||||
if (staff == null) {
|
||||
throw new RuntimeException("未找到对应员工信息");
|
||||
throw new RuntimeException("征信解析结果缺少身份证号");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,68 +6,76 @@
|
||||
|
||||
<select id="selectCreditInfoPage" resultType="com.ruoyi.info.collection.domain.vo.CreditInfoListVO">
|
||||
SELECT
|
||||
s.staff_id,
|
||||
s.name,
|
||||
s.id_card,
|
||||
d.dept_name,
|
||||
debt_agg.query_date,
|
||||
COALESCE(debt_agg.person_name, neg.person_name) AS name,
|
||||
credit_keys.person_id AS id_card,
|
||||
COALESCE(debt_agg.query_date, neg.query_date) AS query_date,
|
||||
IFNULL(debt_agg.debt_count, 0) AS debt_count,
|
||||
IFNULL(debt_agg.debt_total_amount, 0) AS debt_total_amount,
|
||||
IFNULL(neg.civil_cnt, 0) AS civil_cnt,
|
||||
IFNULL(neg.enforce_cnt, 0) AS enforce_cnt,
|
||||
IFNULL(neg.adm_cnt, 0) AS adm_cnt
|
||||
FROM ccdi_base_staff s
|
||||
LEFT JOIN sys_dept d ON s.dept_id = d.dept_id
|
||||
FROM (
|
||||
SELECT person_id
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
UNION
|
||||
SELECT person_id
|
||||
FROM ccdi_credit_negative_info
|
||||
GROUP BY person_id
|
||||
) credit_keys
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
person_id,
|
||||
MAX(person_name) AS person_name,
|
||||
MAX(query_date) AS query_date,
|
||||
COUNT(*) AS debt_count,
|
||||
SUM(debt_total_amount) AS debt_total_amount
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
) debt_agg ON debt_agg.person_id = s.id_card
|
||||
LEFT JOIN ccdi_credit_negative_info neg ON neg.person_id = s.id_card
|
||||
) debt_agg ON debt_agg.person_id = credit_keys.person_id
|
||||
LEFT JOIN ccdi_credit_negative_info neg ON neg.person_id = credit_keys.person_id
|
||||
<where>
|
||||
AND (debt_agg.person_id IS NOT NULL OR neg.person_id IS NOT NULL)
|
||||
<if test="query != null and query.name != null and query.name != ''">
|
||||
AND s.name LIKE CONCAT('%', #{query.name}, '%')
|
||||
</if>
|
||||
<if test="query != null and query.staffId != null and query.staffId != ''">
|
||||
AND CAST(s.staff_id AS CHAR) = #{query.staffId}
|
||||
AND COALESCE(debt_agg.person_name, neg.person_name) LIKE CONCAT('%', #{query.name}, '%')
|
||||
</if>
|
||||
<if test="query != null and query.idCard != null and query.idCard != ''">
|
||||
AND s.id_card LIKE CONCAT('%', #{query.idCard}, '%')
|
||||
AND credit_keys.person_id LIKE CONCAT('%', #{query.idCard}, '%')
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY debt_agg.query_date DESC, s.staff_id DESC
|
||||
ORDER BY COALESCE(debt_agg.query_date, neg.query_date) DESC, credit_keys.person_id DESC
|
||||
</select>
|
||||
|
||||
<select id="selectCreditInfoSummaryByPersonId" resultType="com.ruoyi.info.collection.domain.vo.CreditInfoListVO">
|
||||
SELECT
|
||||
s.staff_id,
|
||||
s.name,
|
||||
s.id_card,
|
||||
d.dept_name,
|
||||
debt_agg.query_date,
|
||||
COALESCE(debt_agg.person_name, neg.person_name) AS name,
|
||||
credit_keys.person_id AS id_card,
|
||||
COALESCE(debt_agg.query_date, neg.query_date) AS query_date,
|
||||
IFNULL(debt_agg.debt_count, 0) AS debt_count,
|
||||
IFNULL(debt_agg.debt_total_amount, 0) AS debt_total_amount,
|
||||
IFNULL(neg.civil_cnt, 0) AS civil_cnt,
|
||||
IFNULL(neg.enforce_cnt, 0) AS enforce_cnt,
|
||||
IFNULL(neg.adm_cnt, 0) AS adm_cnt
|
||||
FROM ccdi_base_staff s
|
||||
LEFT JOIN sys_dept d ON s.dept_id = d.dept_id
|
||||
FROM (
|
||||
SELECT person_id
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
UNION
|
||||
SELECT person_id
|
||||
FROM ccdi_credit_negative_info
|
||||
GROUP BY person_id
|
||||
) credit_keys
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
person_id,
|
||||
MAX(person_name) AS person_name,
|
||||
MAX(query_date) AS query_date,
|
||||
COUNT(*) AS debt_count,
|
||||
SUM(debt_total_amount) AS debt_total_amount
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
) debt_agg ON debt_agg.person_id = s.id_card
|
||||
LEFT JOIN ccdi_credit_negative_info neg ON neg.person_id = s.id_card
|
||||
WHERE s.id_card = #{personId}
|
||||
) debt_agg ON debt_agg.person_id = credit_keys.person_id
|
||||
LEFT JOIN ccdi_credit_negative_info neg ON neg.person_id = credit_keys.person_id
|
||||
WHERE credit_keys.person_id = #{personId}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
|
||||
@@ -34,12 +34,15 @@ class CcdiCreditInfoControllerTest {
|
||||
request.addParameter("pageNum", "1");
|
||||
request.addParameter("pageSize", "10");
|
||||
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request));
|
||||
when(service.selectCreditInfoPage(any(), any())).thenReturn(new Page<CreditInfoListVO>(1, 10, 0));
|
||||
try {
|
||||
when(service.selectCreditInfoPage(any(), any())).thenReturn(new Page<CreditInfoListVO>(1, 10, 0));
|
||||
|
||||
TableDataInfo result = controller.list(new CcdiCreditInfoQueryDTO());
|
||||
TableDataInfo result = controller.list(new CcdiCreditInfoQueryDTO());
|
||||
|
||||
assertEquals(0L, result.getTotal());
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
assertEquals(0L, result.getTotal());
|
||||
} finally {
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -12,13 +12,19 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
class CcdiCreditInfoQueryMapperXmlTest {
|
||||
|
||||
@Test
|
||||
void selectCreditInfoPage_shouldOnlyQueryMaintainedCreditInfo() throws Exception {
|
||||
void selectCreditInfoPage_shouldAggregateByCreditObject() throws Exception {
|
||||
Path xmlPath = Path.of("src/main/resources/mapper/info/collection/CcdiCreditInfoQueryMapper.xml");
|
||||
String source = Files.readString(xmlPath, StandardCharsets.UTF_8);
|
||||
|
||||
assertTrue(source.contains("AND (debt_agg.person_id IS NOT NULL OR neg.person_id IS NOT NULL)"),
|
||||
"征信维护列表必须默认只返回已维护征信的员工");
|
||||
assertFalse(source.contains("query.maintained == '0'"),
|
||||
"征信维护列表不应再支持未维护员工列表");
|
||||
assertFalse(source.contains("FROM ccdi_base_staff"),
|
||||
"征信维护列表不应再从员工表驱动查询");
|
||||
assertFalse(source.contains("query.staffId"),
|
||||
"征信维护列表不应再接收柜员号筛选");
|
||||
assertFalse(source.contains("query.maintained"),
|
||||
"征信维护列表不应再接收是否已维护筛选");
|
||||
assertFalse(source.contains(") keys"),
|
||||
"征信维护列表不应使用 MySQL 保留字作为派生表别名");
|
||||
assertTrue(source.contains("person_id"),
|
||||
"征信维护列表必须按征信对象证件号聚合");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.ruoyi.info.collection.service;
|
||||
|
||||
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
|
||||
import com.ruoyi.info.collection.domain.CcdiCreditNegativeInfo;
|
||||
import com.ruoyi.info.collection.domain.CcdiDebtsInfo;
|
||||
import com.ruoyi.info.collection.domain.vo.CreditInfoUploadResultVO;
|
||||
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiCreditInfoQueryMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiCreditNegativeInfoMapper;
|
||||
import com.ruoyi.info.collection.mapper.CcdiDebtsInfoMapper;
|
||||
@@ -24,7 +22,6 @@ import java.io.File;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -47,9 +44,6 @@ class CcdiCreditInfoServiceImplTest {
|
||||
@Mock
|
||||
private CreditInfoPayloadAssembler assembler;
|
||||
|
||||
@Mock
|
||||
private CcdiBaseStaffMapper baseStaffMapper;
|
||||
|
||||
@Mock
|
||||
private CcdiDebtsInfoMapper debtsInfoMapper;
|
||||
|
||||
@@ -60,28 +54,23 @@ class CcdiCreditInfoServiceImplTest {
|
||||
private CcdiCreditInfoQueryMapper queryMapper;
|
||||
|
||||
@Test
|
||||
void uploadHtmlFiles_shouldIsolateFailuresPerEmployee() {
|
||||
MockMultipartFile successFile = new MockMultipartFile("files", "a.html", "text/html", "<html>a</html>".getBytes(StandardCharsets.UTF_8));
|
||||
MockMultipartFile failFile = new MockMultipartFile("files", "b.html", "text/html", "<html>b</html>".getBytes(StandardCharsets.UTF_8));
|
||||
void uploadHtmlFiles_shouldStoreCreditObjectWithoutStaffBinding() {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"files", "family.html", "text/html", "<html>ok</html>".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
when(creditParseClient.parse(anyString(), anyString(), any(File.class)))
|
||||
.thenReturn(successResponse("330101199001010011", "张三", "2026-03-03"))
|
||||
.thenThrow(new RuntimeException("征信解析失败"));
|
||||
when(baseStaffMapper.selectOne(any())).thenReturn(baseStaff("330101199001010011", "张三"));
|
||||
.thenReturn(successResponse("330101199202020022", "李四", "2026-03-24"));
|
||||
when(assembler.buildDebts(anyString(), anyString(), any(LocalDate.class), any(CreditParsePayload.class)))
|
||||
.thenReturn(List.of(buildDebt()));
|
||||
.thenReturn(List.of(buildDebt("330101199202020022")));
|
||||
when(assembler.buildNegative(anyString(), anyString(), any(LocalDate.class), any(CreditParsePayload.class)))
|
||||
.thenReturn(buildNegative());
|
||||
.thenReturn(buildNegative("330101199202020022"));
|
||||
|
||||
CreditInfoUploadResultVO result = service.upload(Arrays.asList(successFile, failFile));
|
||||
CreditInfoUploadResultVO result = service.upload(List.of(file));
|
||||
|
||||
assertEquals(1, result.getSuccessCount());
|
||||
assertEquals(1, result.getFailureCount());
|
||||
assertEquals("征信解析失败", result.getFailures().get(0).getReason());
|
||||
verify(debtsInfoMapper).deleteByPersonId("330101199001010011");
|
||||
verify(negativeInfoMapper).deleteByPersonId("330101199001010011");
|
||||
verify(debtsInfoMapper).insertBatch(any());
|
||||
verify(negativeInfoMapper).insert(any(CcdiCreditNegativeInfo.class));
|
||||
assertEquals(0, result.getFailureCount());
|
||||
verify(debtsInfoMapper).deleteByPersonId("330101199202020022");
|
||||
verify(negativeInfoMapper).deleteByPersonId("330101199202020022");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -90,7 +79,6 @@ class CcdiCreditInfoServiceImplTest {
|
||||
|
||||
when(creditParseClient.parse(anyString(), anyString(), any(File.class)))
|
||||
.thenReturn(successResponse("330101199001010011", "张三", "2026-03-03"));
|
||||
when(baseStaffMapper.selectOne(any())).thenReturn(baseStaff("330101199001010011", "张三"));
|
||||
when(queryMapper.selectLatestQueryDate("330101199001010011"))
|
||||
.thenReturn(LocalDate.parse("2026-03-05"));
|
||||
|
||||
@@ -116,23 +104,16 @@ class CcdiCreditInfoServiceImplTest {
|
||||
return response;
|
||||
}
|
||||
|
||||
private CcdiBaseStaff baseStaff(String idCard, String name) {
|
||||
CcdiBaseStaff staff = new CcdiBaseStaff();
|
||||
staff.setIdCard(idCard);
|
||||
staff.setName(name);
|
||||
return staff;
|
||||
}
|
||||
|
||||
private CcdiDebtsInfo buildDebt() {
|
||||
private CcdiDebtsInfo buildDebt(String personId) {
|
||||
CcdiDebtsInfo debt = new CcdiDebtsInfo();
|
||||
debt.setPersonId("330101199001010011");
|
||||
debt.setPersonId(personId);
|
||||
debt.setDebtTotalAmount(new BigDecimal("100"));
|
||||
return debt;
|
||||
}
|
||||
|
||||
private CcdiCreditNegativeInfo buildNegative() {
|
||||
private CcdiCreditNegativeInfo buildNegative(String personId) {
|
||||
CcdiCreditNegativeInfo info = new CcdiCreditNegativeInfo();
|
||||
info.setPersonId("330101199001010011");
|
||||
info.setPersonId(personId);
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
253
docs/design/2026-03-24-credit-info-direct-storage-design.md
Normal file
253
docs/design/2026-03-24-credit-info-direct-storage-design.md
Normal file
@@ -0,0 +1,253 @@
|
||||
# 征信维护直接入库改造设计文档
|
||||
|
||||
## 1. 背景
|
||||
|
||||
现有征信维护功能按员工维度设计:
|
||||
|
||||
- 上传时要求征信对象身份证号必须存在于 `ccdi_base_staff`
|
||||
- 页面列表从 `ccdi_base_staff` 出发聚合,只展示员工本人
|
||||
- 查询区保留了“柜员号”“是否已维护”两个员工口径字段
|
||||
|
||||
当前需求调整为:
|
||||
|
||||
- 征信维护页面移除“是否已维护”
|
||||
- 导入时不需要关联柜员或亲属,解析后直接入库
|
||||
- 页面允许展示导入的柜员亲属征信文件
|
||||
- 页面不再展示“柜员号”
|
||||
|
||||
本次改造的核心是把“员工征信维护”收敛为“征信对象维护”。
|
||||
|
||||
## 2. 已确认约束
|
||||
|
||||
- 导入时不关联柜员,也不关联亲属
|
||||
- 解析出征信对象后直接入库
|
||||
- 页面按征信对象本人维度展示,一行一条征信对象记录
|
||||
- 柜员亲属征信文件导入后需要单独展示
|
||||
- 查询区移除“是否已维护”
|
||||
- 列表移除“柜员号”
|
||||
- 保持最短路径实现,不新增征信主表,不拆新页面
|
||||
- 仍然只保留同一证件号的最新征信数据
|
||||
|
||||
## 3. 目标
|
||||
|
||||
- 将征信维护页从员工口径调整为征信对象口径
|
||||
- 让任意征信对象在解析成功后都可以直接落库
|
||||
- 保留现有上传、详情、删除的基本交互
|
||||
- 保持现有两张征信业务表结构与覆盖写入模式
|
||||
|
||||
## 4. 非目标
|
||||
|
||||
- 不新增柜员与亲属归属映射字段
|
||||
- 不新增征信主表或上传历史表
|
||||
- 不新增异步任务、补偿任务或兜底逻辑
|
||||
- 不扩展多版本征信存储
|
||||
|
||||
## 5. 方案对比
|
||||
|
||||
### 5.1 方案 A:页面和上传都彻底去员工化
|
||||
|
||||
- 上传时只校验文件合法性和解析结果完整性
|
||||
- 解析成功后按征信对象本人证件号直接写入
|
||||
- 页面直接从征信表聚合,不再依赖员工表
|
||||
|
||||
优点:
|
||||
|
||||
- 完全符合当前需求
|
||||
- 前后端语义一致
|
||||
- 实现路径最短
|
||||
|
||||
缺点:
|
||||
|
||||
- 页面不再补充员工属性
|
||||
|
||||
### 5.2 方案 B:上传去员工化,列表保留员工补充信息
|
||||
|
||||
- 上传时不校验员工存在
|
||||
- 列表查询时若命中员工表则补柜员信息,否则为空
|
||||
|
||||
优点:
|
||||
|
||||
- 能部分保留旧页面字段
|
||||
|
||||
缺点:
|
||||
|
||||
- 同一页面内记录语义不一致
|
||||
- 会继续引入“员工口径”和“征信对象口径”混用问题
|
||||
|
||||
### 5.3 方案 C:新增征信对象主表
|
||||
|
||||
- 上传后先写征信对象主表,再关联两张明细表
|
||||
|
||||
优点:
|
||||
|
||||
- 后续扩展空间更大
|
||||
|
||||
缺点:
|
||||
|
||||
- 超出当前需求,属于过度设计
|
||||
|
||||
## 6. 最终方案
|
||||
|
||||
采用方案 A:页面和上传都彻底去员工化。
|
||||
|
||||
选择原因:
|
||||
|
||||
- 直接满足“导入时不需要关联柜员或者亲属,直接入库”
|
||||
- 直接满足“柜员亲属征信文件可独立展示”
|
||||
- 不新增表,不改菜单结构,保持最短路径
|
||||
- 能一次性消除“柜员号”“是否已维护”这类旧口径残留
|
||||
|
||||
## 7. 总体链路
|
||||
|
||||
改造后的链路如下:
|
||||
|
||||
`征信维护页面 -> 征信维护接口 -> 征信维护服务 -> 征信解析接口 -> 两张征信业务表`
|
||||
|
||||
职责定义:
|
||||
|
||||
- 页面负责上传文件、查询列表、查看详情、删除记录
|
||||
- 接口负责暴露统一的上传、列表、详情、删除能力
|
||||
- 服务负责解析结果校验、最新日期判断、覆盖写入
|
||||
- 数据库继续仅使用 `ccdi_debts_info` 与 `ccdi_credit_negative_info`
|
||||
|
||||
## 8. 数据口径设计
|
||||
|
||||
### 8.1 主键口径
|
||||
|
||||
- 统一以解析结果中的 `query_cert_no` 作为征信对象唯一标识,即 `person_id`
|
||||
- `query_cust_name` 作为征信对象姓名,即 `person_name`
|
||||
- `report_time` 作为征信查询日期,即 `query_date`
|
||||
|
||||
### 8.2 入库口径
|
||||
|
||||
- 不校验 `person_id` 是否存在于 `ccdi_base_staff`
|
||||
- 不校验 `person_id` 是否存在于 `ccdi_staff_fmy_relation`
|
||||
- 只要解析结果具备完整主键字段,即可继续写入
|
||||
|
||||
### 8.3 列表口径
|
||||
|
||||
- 页面主列表按征信对象维度展示
|
||||
- 每个 `person_id` 对应一条摘要记录
|
||||
- 不再要求该征信对象属于员工或亲属数据域
|
||||
|
||||
## 9. 前端页面设计
|
||||
|
||||
### 9.1 查询区
|
||||
|
||||
保留:
|
||||
|
||||
- 姓名
|
||||
- 身份证号
|
||||
|
||||
移除:
|
||||
|
||||
- 柜员号
|
||||
- 是否已维护
|
||||
|
||||
### 9.2 列表区
|
||||
|
||||
保留字段:
|
||||
|
||||
- 姓名
|
||||
- 身份证号
|
||||
- 最近征信查询日期
|
||||
- 负债笔数
|
||||
- 负债总额
|
||||
- 民事案件笔数
|
||||
- 强制执行笔数
|
||||
- 行政处罚笔数
|
||||
- 操作
|
||||
|
||||
移除字段:
|
||||
|
||||
- 柜员号
|
||||
|
||||
### 9.3 详情与删除
|
||||
|
||||
- 详情继续按 `person_id` 展示征信摘要、负面信息、负债明细
|
||||
- 删除继续按 `person_id` 删除该征信对象的全部征信数据
|
||||
|
||||
## 10. 后端改造设计
|
||||
|
||||
### 10.1 上传服务
|
||||
|
||||
现状:
|
||||
|
||||
- 上传时调用 `ensureStaffExists(personId)`,非员工身份证号会失败
|
||||
|
||||
改造后:
|
||||
|
||||
- 删除员工存在性校验
|
||||
- 解析出 `personId/personName/queryDate` 后直接进入最新日期判断
|
||||
- 通过后继续覆盖写入两张业务表
|
||||
|
||||
### 10.2 列表查询
|
||||
|
||||
现状:
|
||||
|
||||
- 查询 SQL 从 `ccdi_base_staff` 出发
|
||||
- 强依赖员工表字段
|
||||
|
||||
改造后:
|
||||
|
||||
- 查询 SQL 直接从征信表聚合
|
||||
- 以 `ccdi_debts_info` 的聚合结果为主
|
||||
- 结合 `ccdi_credit_negative_info` 的负面统计
|
||||
- 按 `person_id` 汇总一条摘要记录
|
||||
- 支持姓名、身份证号筛选
|
||||
- 不再接收或使用 `staffId`、`maintained`
|
||||
|
||||
### 10.3 DTO 与 VO
|
||||
|
||||
- `CcdiCreditInfoQueryDTO` 删除 `staffId`
|
||||
- `CcdiCreditInfoQueryDTO` 删除 `maintained`
|
||||
- 列表 VO 不再要求返回柜员号
|
||||
|
||||
## 11. 覆盖写入规则
|
||||
|
||||
系统继续只保留同一证件号下的最新征信数据:
|
||||
|
||||
- 若库中不存在当前 `person_id` 记录,直接写入
|
||||
- 若新 `query_date` 大于等于库中最新 `query_date`,覆盖旧数据
|
||||
- 若新 `query_date` 小于库中最新 `query_date`,当前文件失败
|
||||
|
||||
覆盖步骤保持不变:
|
||||
|
||||
1. 删除 `ccdi_debts_info` 中该 `person_id` 的旧记录
|
||||
2. 删除 `ccdi_credit_negative_info` 中该 `person_id` 的旧记录
|
||||
3. 插入新的负债明细
|
||||
4. 插入新的负面信息
|
||||
|
||||
以上步骤在同一事务内完成。
|
||||
|
||||
## 12. 测试设计
|
||||
|
||||
### 12.1 前端测试
|
||||
|
||||
- 查询区不再包含“柜员号”
|
||||
- 查询区不再包含“是否已维护”
|
||||
- 列表列定义不再包含“柜员号”
|
||||
- 页面仍支持姓名、身份证号检索
|
||||
|
||||
### 12.2 后端测试
|
||||
|
||||
- 非员工身份证号征信可以上传成功
|
||||
- 查询 DTO 不再包含 `staffId`、`maintained`
|
||||
- 列表 SQL 不再依赖 `ccdi_base_staff`
|
||||
- 详情和删除对纯征信对象记录仍然生效
|
||||
- 旧日期上传仍会失败
|
||||
|
||||
## 13. 实施边界
|
||||
|
||||
本次改造只覆盖征信维护功能现有页面与接口:
|
||||
|
||||
- 不调整菜单权限编码
|
||||
- 不改造征信解析接口协议
|
||||
- 不补录柜员或亲属关系字段
|
||||
- 不新增历史数据迁移脚本
|
||||
|
||||
## 14. 后续动作
|
||||
|
||||
- 待用户审阅本设计文档后,输出两份实施计划:
|
||||
- `docs/plans/backend/` 后端实施计划
|
||||
- `docs/plans/frontend/` 前端实施计划
|
||||
@@ -0,0 +1,392 @@
|
||||
# Credit Info Direct Storage Backend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将征信维护后端从“员工征信口径”调整为“征信对象口径”,上传时不再校验员工或亲属归属,解析成功后按 `person_id` 直接覆盖入库,并让列表查询直接基于征信表聚合。
|
||||
|
||||
**Architecture:** 保留现有 `CcdiCreditInfoController -> ICcdiCreditInfoService -> CcdiCreditInfoServiceImpl -> CcdiCreditInfoQueryMapper.xml` 链路,不新增表、不改接口路径。核心改造点是删除上传链路中的员工存在性校验,收敛查询 DTO/VO 到征信对象字段,并将列表 SQL 从 `ccdi_base_staff` 驱动改成“征信业务表驱动”的按证件号聚合查询。
|
||||
|
||||
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, MyBatis XML, JUnit 5, Mockito, Maven, MySQL
|
||||
|
||||
---
|
||||
|
||||
## 文件结构与职责
|
||||
|
||||
**修改文件**
|
||||
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiCreditInfoQueryDTO.java`
|
||||
删除员工口径查询字段,仅保留征信对象筛选条件。
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CreditInfoListVO.java`
|
||||
删除 `staffId`、`deptName` 等员工字段,只保留征信对象摘要字段。
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiCreditInfoServiceImpl.java`
|
||||
删除 `CcdiBaseStaffMapper` 依赖与 `ensureStaffExists` 校验,保留最新日期与覆盖写入逻辑。
|
||||
- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiCreditInfoQueryMapper.xml`
|
||||
列表与摘要查询改为直接从征信业务表按 `person_id` 聚合,不再 `JOIN ccdi_base_staff`。
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiCreditInfoServiceImplTest.java`
|
||||
锁定“非员工征信对象也可上传成功”和“旧日期仍失败”行为。
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java`
|
||||
锁定列表 SQL 已去掉 `ccdi_base_staff`、`staffId`、`maintained` 依赖。
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiCreditInfoControllerTest.java`
|
||||
保持控制层分页委派契约,确认 DTO 精简后接口仍可调用。
|
||||
- `docs/reports/implementation/2026-03-24-credit-info-direct-storage-backend-record.md`
|
||||
后端实施记录。
|
||||
|
||||
**参考文件**
|
||||
|
||||
- `docs/design/2026-03-24-credit-info-direct-storage-design.md`
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiCreditInfoController.java`
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapper.java`
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CreditInfoDetailVO.java`
|
||||
|
||||
## Task 1: 锁定“直接入库”后端契约
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiCreditInfoServiceImplTest.java`
|
||||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java`
|
||||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiCreditInfoControllerTest.java`
|
||||
|
||||
- [ ] **Step 1: 先把服务测试改成征信对象口径**
|
||||
|
||||
在 `CcdiCreditInfoServiceImplTest` 新增或改写用例,明确非员工证件号也能成功上传:
|
||||
|
||||
```java
|
||||
@Test
|
||||
void uploadHtmlFiles_shouldStoreCreditObjectWithoutStaffBinding() {
|
||||
MockMultipartFile file = new MockMultipartFile(
|
||||
"files", "family.html", "text/html", "<html>ok</html>".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
when(creditParseClient.parse(anyString(), anyString(), any(File.class)))
|
||||
.thenReturn(successResponse("330101199202020022", "李四", "2026-03-24"));
|
||||
when(assembler.buildDebts(anyString(), anyString(), any(LocalDate.class), any(CreditParsePayload.class)))
|
||||
.thenReturn(List.of(buildDebt("330101199202020022")));
|
||||
when(assembler.buildNegative(anyString(), anyString(), any(LocalDate.class), any(CreditParsePayload.class)))
|
||||
.thenReturn(buildNegative("330101199202020022"));
|
||||
|
||||
CreditInfoUploadResultVO result = service.upload(List.of(file));
|
||||
|
||||
assertEquals(1, result.getSuccessCount());
|
||||
assertEquals(0, result.getFailureCount());
|
||||
verify(debtsInfoMapper).deleteByPersonId("330101199202020022");
|
||||
verify(negativeInfoMapper).deleteByPersonId("330101199202020022");
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 删除测试里对员工表 Mock 的依赖**
|
||||
|
||||
清理以下旧逻辑:
|
||||
|
||||
```java
|
||||
@Mock
|
||||
private CcdiBaseStaffMapper baseStaffMapper;
|
||||
|
||||
when(baseStaffMapper.selectOne(any())).thenReturn(baseStaff(...));
|
||||
```
|
||||
|
||||
并同步移除不再使用的 `CcdiBaseStaff`、`CcdiBaseStaffMapper`、`any()` 导入。
|
||||
|
||||
- [ ] **Step 3: 改写 SQL 契约测试**
|
||||
|
||||
把 `CcdiCreditInfoQueryMapperXmlTest` 改成下面这组断言:
|
||||
|
||||
```java
|
||||
assertFalse(source.contains("FROM ccdi_base_staff"),
|
||||
"征信维护列表不应再从员工表驱动查询");
|
||||
assertFalse(source.contains("query.staffId"),
|
||||
"征信维护列表不应再接收柜员号筛选");
|
||||
assertFalse(source.contains("query.maintained"),
|
||||
"征信维护列表不应再接收是否已维护筛选");
|
||||
assertTrue(source.contains("person_id"),
|
||||
"征信维护列表必须按征信对象证件号聚合");
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 运行失败测试确认改造点被覆盖**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoServiceImplTest,CcdiCreditInfoQueryMapperXmlTest,CcdiCreditInfoControllerTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- FAIL,原因应集中在服务实现仍校验员工存在、查询 XML 仍依赖员工表、DTO/VO 仍残留旧字段。
|
||||
|
||||
- [ ] **Step 5: 提交测试契约**
|
||||
|
||||
```bash
|
||||
git add ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiCreditInfoServiceImplTest.java \
|
||||
ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java \
|
||||
ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiCreditInfoControllerTest.java
|
||||
git commit -m "新增征信直接入库后端测试契约"
|
||||
```
|
||||
|
||||
## Task 2: 收敛 DTO / VO 到征信对象字段
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiCreditInfoQueryDTO.java`
|
||||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CreditInfoListVO.java`
|
||||
|
||||
- [ ] **Step 1: 精简查询 DTO**
|
||||
|
||||
将 `CcdiCreditInfoQueryDTO` 改为只保留:
|
||||
|
||||
```java
|
||||
@Data
|
||||
public class CcdiCreditInfoQueryDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String name;
|
||||
private String idCard;
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 精简列表 VO**
|
||||
|
||||
将 `CreditInfoListVO` 改为只保留:
|
||||
|
||||
```java
|
||||
private String name;
|
||||
private String idCard;
|
||||
private Date queryDate;
|
||||
private Long debtCount;
|
||||
private BigDecimal debtTotalAmount;
|
||||
private Integer civilCnt;
|
||||
private Integer enforceCnt;
|
||||
private Integer admCnt;
|
||||
```
|
||||
|
||||
删除:
|
||||
|
||||
```java
|
||||
private Long staffId;
|
||||
private String deptName;
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 运行单测确认编译通过**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoControllerTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,控制层在 DTO 精简后仍能正常分页委派。
|
||||
|
||||
- [ ] **Step 4: 提交 DTO / VO 调整**
|
||||
|
||||
```bash
|
||||
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiCreditInfoQueryDTO.java \
|
||||
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CreditInfoListVO.java
|
||||
git commit -m "精简征信维护后端查询字段"
|
||||
```
|
||||
|
||||
## Task 3: 改造上传服务为“直接入库”
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiCreditInfoServiceImpl.java`
|
||||
- Review: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/CreditInfoPayloadAssembler.java`
|
||||
|
||||
- [ ] **Step 1: 移除员工主数据依赖**
|
||||
|
||||
删除成员与导入:
|
||||
|
||||
```java
|
||||
@Resource
|
||||
private CcdiBaseStaffMapper baseStaffMapper;
|
||||
```
|
||||
|
||||
以及:
|
||||
|
||||
```java
|
||||
ensureStaffExists(personId);
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 删除 `ensureStaffExists` 方法**
|
||||
|
||||
从实现中彻底移除:
|
||||
|
||||
```java
|
||||
private void ensureStaffExists(String personId) { ... }
|
||||
```
|
||||
|
||||
保留对以下字段的校验:
|
||||
|
||||
```java
|
||||
String personId = stringValue(header.get("query_cert_no"));
|
||||
String personName = stringValue(header.get("query_cust_name"));
|
||||
LocalDate queryDate = parseQueryDate(stringValue(header.get("report_time")));
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 保持最新日期覆盖逻辑**
|
||||
|
||||
保留并验证以下路径仍然成立:
|
||||
|
||||
```java
|
||||
ensureLatestQueryDate(personId, queryDate);
|
||||
replaceEmployeeCredit(personId, debts, negative, userName);
|
||||
```
|
||||
|
||||
这里不用改方法名,优先走最短路径;只要行为变成“按征信对象本人证件号覆盖写入”即可。
|
||||
|
||||
- [ ] **Step 4: 运行服务测试**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoServiceImplTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,非员工征信对象可以上传成功
|
||||
- PASS,旧日期上传仍然失败
|
||||
|
||||
- [ ] **Step 5: 提交服务实现调整**
|
||||
|
||||
```bash
|
||||
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiCreditInfoServiceImpl.java \
|
||||
ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiCreditInfoServiceImplTest.java
|
||||
git commit -m "调整征信维护后端直接入库逻辑"
|
||||
```
|
||||
|
||||
## Task 4: 重写列表 SQL 为征信表聚合查询
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiCreditInfoQueryMapper.xml`
|
||||
- Modify: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java`
|
||||
|
||||
- [ ] **Step 1: 设计征信对象主集合**
|
||||
|
||||
在 XML 中构造统一主集合,覆盖“只有负债”“只有负面信息”“两者都有”三种场景:
|
||||
|
||||
```sql
|
||||
SELECT person_id
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
UNION
|
||||
SELECT person_id
|
||||
FROM ccdi_credit_negative_info
|
||||
GROUP BY person_id
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 改写分页查询 SQL**
|
||||
|
||||
参考结构:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
keys.person_id AS id_card,
|
||||
COALESCE(debt_agg.person_name, neg.person_name) AS name,
|
||||
COALESCE(debt_agg.query_date, neg.query_date) AS query_date,
|
||||
IFNULL(debt_agg.debt_count, 0) AS debt_count,
|
||||
IFNULL(debt_agg.debt_total_amount, 0) AS debt_total_amount,
|
||||
IFNULL(neg.civil_cnt, 0) AS civil_cnt,
|
||||
IFNULL(neg.enforce_cnt, 0) AS enforce_cnt,
|
||||
IFNULL(neg.adm_cnt, 0) AS adm_cnt
|
||||
FROM (
|
||||
SELECT person_id FROM ccdi_debts_info GROUP BY person_id
|
||||
UNION
|
||||
SELECT person_id FROM ccdi_credit_negative_info GROUP BY person_id
|
||||
) keys
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
person_id,
|
||||
MAX(person_name) AS person_name,
|
||||
MAX(query_date) AS query_date,
|
||||
COUNT(*) AS debt_count,
|
||||
SUM(debt_total_amount) AS debt_total_amount
|
||||
FROM ccdi_debts_info
|
||||
GROUP BY person_id
|
||||
) debt_agg ON debt_agg.person_id = keys.person_id
|
||||
LEFT JOIN ccdi_credit_negative_info neg ON neg.person_id = keys.person_id
|
||||
<where>
|
||||
<if test="query != null and query.name != null and query.name != ''">
|
||||
AND COALESCE(debt_agg.person_name, neg.person_name) LIKE CONCAT('%', #{query.name}, '%')
|
||||
</if>
|
||||
<if test="query != null and query.idCard != null and query.idCard != ''">
|
||||
AND keys.person_id LIKE CONCAT('%', #{query.idCard}, '%')
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY COALESCE(debt_agg.query_date, neg.query_date) DESC, keys.person_id DESC
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 改写详情摘要查询**
|
||||
|
||||
`selectCreditInfoSummaryByPersonId` 同样改为直接从征信表聚合,不再依赖员工表。至少保证:
|
||||
|
||||
```sql
|
||||
WHERE keys.person_id = #{personId}
|
||||
LIMIT 1
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 运行 XML 契约测试**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoQueryMapperXmlTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,XML 不再出现 `ccdi_base_staff`、`query.staffId`、`query.maintained`
|
||||
|
||||
- [ ] **Step 5: 提交查询 SQL 改造**
|
||||
|
||||
```bash
|
||||
git add ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiCreditInfoQueryMapper.xml \
|
||||
ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java
|
||||
git commit -m "调整征信维护后端聚合查询口径"
|
||||
```
|
||||
|
||||
## Task 5: 全量回归与实施记录
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/reports/implementation/2026-03-24-credit-info-direct-storage-backend-record.md`
|
||||
|
||||
- [ ] **Step 1: 运行后端回归测试**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoServiceImplTest,CcdiCreditInfoQueryMapperXmlTest,CcdiCreditInfoControllerTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,直接入库、聚合查询、控制层分页委派相关测试全部通过。
|
||||
|
||||
- [ ] **Step 2: 编写后端实施记录**
|
||||
|
||||
在 `docs/reports/implementation/2026-03-24-credit-info-direct-storage-backend-record.md` 中记录:
|
||||
|
||||
- 实施目标
|
||||
- 实际修改文件
|
||||
- 直接入库口径
|
||||
- SQL 聚合调整
|
||||
- 验证命令与结果
|
||||
- 若测试期间启动本地服务,结束后已关闭进程
|
||||
|
||||
- [ ] **Step 3: 检查工作区仅包含本次改动**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --staged --name-only
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- 仅出现本任务相关的后端源码、测试和实施记录文件。
|
||||
|
||||
- [ ] **Step 4: 提交后端收尾**
|
||||
|
||||
```bash
|
||||
git add docs/reports/implementation/2026-03-24-credit-info-direct-storage-backend-record.md
|
||||
git commit -m "补充征信维护后端直接入库实施记录"
|
||||
```
|
||||
@@ -0,0 +1,297 @@
|
||||
# Credit Info Direct Storage Frontend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 将征信维护前端页面从“员工维度展示”调整为“征信对象维度展示”,移除“柜员号”“是否已维护”两项旧口径字段,并保持上传、列表、详情、删除交互可用。
|
||||
|
||||
**Architecture:** 保留现有 `ruoyi-ui/src/views/ccdiCreditInfo/index.vue` 独立页面和 `@/api/ccdiCreditInfo` API 封装,不新增路由和页面。核心改造点是精简查询参数和列表列定义,使页面只围绕姓名、身份证号和征信摘要展示运转,同时同步修正前端静态契约测试与删除确认文案。
|
||||
|
||||
**Tech Stack:** Vue 2, Element UI, Axios request 封装, Node.js 源码契约测试, npm
|
||||
|
||||
---
|
||||
|
||||
## 文件结构与职责
|
||||
|
||||
**修改文件**
|
||||
|
||||
- `ruoyi-ui/src/views/ccdiCreditInfo/index.vue`
|
||||
移除“柜员号”“是否已维护”,收敛查询区、列表列和删除提示文案。
|
||||
- `ruoyi-ui/tests/unit/credit-info-page-layout.test.js`
|
||||
锁定新页面结构:只有姓名、身份证号查询,不再出现柜员号列。
|
||||
- `ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js`
|
||||
从“默认 maintained=1”契约改为“页面已彻底移除 maintained 口径”契约。
|
||||
- `ruoyi-ui/tests/unit/credit-info-detail-ui.test.js`
|
||||
删除提示文案从“员工当前已维护征信”改为“征信对象当前已维护征信”。
|
||||
- `docs/reports/implementation/2026-03-24-credit-info-direct-storage-frontend-record.md`
|
||||
前端实施记录。
|
||||
|
||||
**参考文件**
|
||||
|
||||
- `docs/design/2026-03-24-credit-info-direct-storage-design.md`
|
||||
- `ruoyi-ui/src/api/ccdiCreditInfo.js`
|
||||
- `docs/reports/implementation/2026-03-23-credit-info-maintenance-frontend-implementation.md`
|
||||
|
||||
## Task 1: 先把前端静态契约切到新口径
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/tests/unit/credit-info-page-layout.test.js`
|
||||
- Modify: `ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js`
|
||||
- Modify: `ruoyi-ui/tests/unit/credit-info-detail-ui.test.js`
|
||||
|
||||
- [ ] **Step 1: 改写页面结构契约**
|
||||
|
||||
在 `credit-info-page-layout.test.js` 中保留这些必备 token:
|
||||
|
||||
```javascript
|
||||
[
|
||||
"征信维护",
|
||||
"姓名",
|
||||
"身份证号",
|
||||
"批量上传征信HTML",
|
||||
"最近征信查询日期",
|
||||
"负债笔数",
|
||||
"负债总额",
|
||||
"民事案件笔数",
|
||||
"强制执行笔数",
|
||||
"行政处罚笔数",
|
||||
"详情",
|
||||
"删除"
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `征信维护页面缺少关键结构: ${token}`);
|
||||
});
|
||||
```
|
||||
|
||||
并增加排除断言:
|
||||
|
||||
```javascript
|
||||
assert(!source.includes('label="柜员号"'), "征信维护页面不应再展示柜员号查询项");
|
||||
assert(!source.includes('prop="staffId"'), "征信维护列表不应再展示柜员号列");
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 改写 maintained 契约**
|
||||
|
||||
把 `credit-info-maintained-filter.test.js` 改成下面这组断言:
|
||||
|
||||
```javascript
|
||||
assert(!source.includes("maintained:"), "征信维护页面不应再维护 maintained 查询参数");
|
||||
assert(!source.includes('label="是否已维护"'), "征信维护页面不应再展示是否已维护筛选项");
|
||||
assert(!source.includes('value="1"'), "征信维护页面不应再内置已维护默认筛选");
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 改写详情/删除契约**
|
||||
|
||||
把 `credit-info-detail-ui.test.js` 的删除确认文案断言改为:
|
||||
|
||||
```javascript
|
||||
"确认删除该征信对象当前已维护的征信信息吗?"
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 运行静态契约确认失败**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
node ruoyi-ui/tests/unit/credit-info-page-layout.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- FAIL,原因应集中在页面仍包含 `staffId`、`maintained` 和旧删除文案。
|
||||
|
||||
- [ ] **Step 5: 提交前端测试契约**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/tests/unit/credit-info-page-layout.test.js \
|
||||
ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js \
|
||||
ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
git commit -m "新增征信维护前端直接入库测试契约"
|
||||
```
|
||||
|
||||
## Task 2: 精简征信维护页面查询区与列表区
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/ccdiCreditInfo/index.vue`
|
||||
|
||||
- [ ] **Step 1: 删除查询区旧字段**
|
||||
|
||||
从查询表单移除以下片段:
|
||||
|
||||
```vue
|
||||
<el-form-item label="柜员号">
|
||||
<el-input v-model="queryParams.staffId" ... />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否已维护">
|
||||
<el-select v-model="queryParams.maintained" ...>
|
||||
<el-option label="已维护" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
```
|
||||
|
||||
查询区只保留:
|
||||
|
||||
```vue
|
||||
<el-form-item label="姓名">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入姓名" />
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号">
|
||||
<el-input v-model="queryParams.idCard" placeholder="请输入身份证号" />
|
||||
</el-form-item>
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 精简 `queryParams` 与重置逻辑**
|
||||
|
||||
把 `data()` 与 `resetQuery()` 收敛为:
|
||||
|
||||
```javascript
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
idCard: undefined,
|
||||
}
|
||||
```
|
||||
|
||||
确保以下字段彻底消失:
|
||||
|
||||
```javascript
|
||||
staffId
|
||||
maintained
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 删除列表中的柜员号列**
|
||||
|
||||
移除:
|
||||
|
||||
```vue
|
||||
<el-table-column label="柜员号" prop="staffId" align="center" />
|
||||
```
|
||||
|
||||
保留列表列顺序为:
|
||||
|
||||
```vue
|
||||
姓名 -> 身份证号 -> 最近征信查询日期 -> 负债笔数 -> 负债总额 -> 民事案件笔数 -> 强制执行笔数 -> 行政处罚笔数 -> 操作
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 调整删除确认文案**
|
||||
|
||||
将删除提示文案改成:
|
||||
|
||||
```javascript
|
||||
"确认删除该征信对象当前已维护的征信信息吗?"
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 运行静态契约确认通过**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
node ruoyi-ui/tests/unit/credit-info-page-layout.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,页面已完全移除员工口径字段。
|
||||
|
||||
- [ ] **Step 6: 提交页面改造**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/src/views/ccdiCreditInfo/index.vue \
|
||||
ruoyi-ui/tests/unit/credit-info-page-layout.test.js \
|
||||
ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js \
|
||||
ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
git commit -m "调整征信维护前端页面展示口径"
|
||||
```
|
||||
|
||||
## Task 3: 校验 API 调用与页面数据流未回退
|
||||
|
||||
**Files:**
|
||||
- Review: `ruoyi-ui/src/api/ccdiCreditInfo.js`
|
||||
- Review: `ruoyi-ui/tests/unit/credit-info-api-contract.test.js`
|
||||
- Review: `ruoyi-ui/tests/unit/credit-info-upload-ui.test.js`
|
||||
|
||||
- [ ] **Step 1: 确认 API 文件无需改路径**
|
||||
|
||||
检查 `ccdiCreditInfo.js` 保持以下函数与路径不变:
|
||||
|
||||
```javascript
|
||||
uploadCreditHtml(files)
|
||||
listCreditInfo(query)
|
||||
getCreditInfoDetail(personId)
|
||||
deleteCreditInfo(personId)
|
||||
```
|
||||
|
||||
以及:
|
||||
|
||||
```javascript
|
||||
'/ccdi/creditInfo/upload'
|
||||
'/ccdi/creditInfo/list'
|
||||
'/ccdi/creditInfo/'
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 运行 API 与上传 UI 契约**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
node ruoyi-ui/tests/unit/credit-info-api-contract.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-upload-ui.test.js
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,说明本次仅调整查询口径,不影响接口路径和上传交互。
|
||||
|
||||
- [ ] **Step 3: 运行前端构建**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- PASS,构建通过
|
||||
- 允许出现项目既有体积告警,但不应出现新增编译错误
|
||||
|
||||
## Task 4: 补齐前端实施记录
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/reports/implementation/2026-03-24-credit-info-direct-storage-frontend-record.md`
|
||||
|
||||
- [ ] **Step 1: 编写前端实施记录**
|
||||
|
||||
在实施记录中至少包含:
|
||||
|
||||
- 实施目标:页面切到征信对象维度
|
||||
- 实际修改文件
|
||||
- 查询区与列表区移除字段说明
|
||||
- 删除提示文案调整
|
||||
- 验证命令与结果
|
||||
- 若测试期间启动 dev server,结束后已关闭进程
|
||||
|
||||
- [ ] **Step 2: 检查暂存区仅包含本次前端改动**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git diff --staged --name-only
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- 仅出现前端页面、测试和实施记录相关文件。
|
||||
|
||||
- [ ] **Step 3: 提交前端记录**
|
||||
|
||||
```bash
|
||||
git add docs/reports/implementation/2026-03-24-credit-info-direct-storage-frontend-record.md
|
||||
git commit -m "补充征信维护前端直接入库实施记录"
|
||||
```
|
||||
@@ -0,0 +1,73 @@
|
||||
# 征信维护后端直接入库实施记录
|
||||
|
||||
## 1. 实施范围
|
||||
|
||||
- 实施目标:将征信维护后端切换为征信对象维度,上传时不再校验员工归属,解析成功后按 `person_id` 直接覆盖入库,列表查询改为征信表聚合
|
||||
- 实施目录:`ccdi-info-collection`
|
||||
- 实施日期:2026-03-24
|
||||
|
||||
## 2. 实际修改文件
|
||||
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiCreditInfoQueryDTO.java`
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CreditInfoListVO.java`
|
||||
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiCreditInfoServiceImpl.java`
|
||||
- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiCreditInfoQueryMapper.xml`
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiCreditInfoServiceImplTest.java`
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiCreditInfoQueryMapperXmlTest.java`
|
||||
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiCreditInfoControllerTest.java`
|
||||
|
||||
## 3. 功能落地说明
|
||||
|
||||
### 3.1 直接入库口径
|
||||
|
||||
- 上传解析后直接读取 `query_cert_no`、`query_cust_name`、`report_time`
|
||||
- 删除员工主数据依赖,不再校验征信对象是否存在于 `ccdi_base_staff`
|
||||
- 保留“同一证件号仅允许最新征信覆盖写入”的日期校验
|
||||
- 继续沿用 `replaceEmployeeCredit` 方法完成按 `person_id` 的先删后插覆盖写入
|
||||
|
||||
### 3.2 DTO / VO 收敛
|
||||
|
||||
- `CcdiCreditInfoQueryDTO` 仅保留 `name`、`idCard`
|
||||
- `CreditInfoListVO` 删除 `staffId`、`deptName`,仅保留征信对象摘要字段
|
||||
|
||||
### 3.3 SQL 聚合调整
|
||||
|
||||
- 列表查询改为以征信业务表为主集合,覆盖“只有负债”“只有负面信息”“两者都有”三类数据
|
||||
- 列表与摘要查询均通过 `person_id` 聚合,不再关联 `ccdi_base_staff`、`sys_dept`
|
||||
- 查询条件仅保留姓名、身份证号两项筛选
|
||||
|
||||
## 4. 验证记录
|
||||
|
||||
### 4.1 失败验证
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoServiceImplTest,CcdiCreditInfoQueryMapperXmlTest,CcdiCreditInfoControllerTest test
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
- 首轮失败点与计划一致,集中暴露为员工校验未删除、XML 仍依赖员工表
|
||||
|
||||
### 4.2 分段验证
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoControllerTest test
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoServiceImplTest test
|
||||
mvn -pl ccdi-info-collection -Dtest=CcdiCreditInfoQueryMapperXmlTest test
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
- 三组测试均通过
|
||||
- 控制层分页委派契约保持不变
|
||||
- 非员工征信对象可成功上传,旧日期上传仍被拦截
|
||||
- XML 契约确认已去掉 `ccdi_base_staff`、`query.staffId`、`query.maintained`
|
||||
|
||||
## 5. 进程与环境说明
|
||||
|
||||
- 本次仅执行 Maven 单元测试,未启动本地后端服务
|
||||
- 无残留测试进程需要清理
|
||||
@@ -0,0 +1,26 @@
|
||||
# 2026-03-24 征信维护直接入库设计记录
|
||||
|
||||
## 本次产出
|
||||
|
||||
- 新增设计文档 `docs/design/2026-03-24-credit-info-direct-storage-design.md`
|
||||
- 明确征信维护页由“员工征信维护”调整为“征信对象维护”
|
||||
|
||||
## 关键确认结论
|
||||
|
||||
- 导入时不关联柜员
|
||||
- 导入时不关联亲属
|
||||
- 解析成功后直接入库
|
||||
- 柜员亲属征信文件需要独立展示
|
||||
- 查询区移除“是否已维护”
|
||||
- 页面移除“柜员号”
|
||||
|
||||
## 设计结论
|
||||
|
||||
- 上传链路删除员工存在性校验
|
||||
- 列表查询改为直接从征信表按 `person_id` 聚合
|
||||
- 页面按征信对象维度展示摘要
|
||||
- 继续只保留同一证件号的最新征信数据
|
||||
|
||||
## 后续动作
|
||||
|
||||
- 待用户审阅设计文档后,继续输出前端与后端实施计划
|
||||
@@ -0,0 +1,84 @@
|
||||
# 征信维护前端直接入库实施记录
|
||||
|
||||
## 1. 实施范围
|
||||
|
||||
- 实施目标:将征信维护页面切换为征信对象维度展示,移除“柜员号”“是否已维护”旧口径字段,并保持上传、列表、详情、删除交互可用
|
||||
- 实施目录:`ruoyi-ui`
|
||||
- 实施日期:2026-03-24
|
||||
|
||||
## 2. 实际修改文件
|
||||
|
||||
- `ruoyi-ui/src/views/ccdiCreditInfo/index.vue`
|
||||
- `ruoyi-ui/tests/unit/credit-info-page-layout.test.js`
|
||||
- `ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js`
|
||||
- `ruoyi-ui/tests/unit/credit-info-detail-ui.test.js`
|
||||
|
||||
## 3. 功能落地说明
|
||||
|
||||
### 3.1 查询区与列表区收敛
|
||||
|
||||
- 查询区仅保留“姓名”“身份证号”
|
||||
- `queryParams` 与重置逻辑删除 `staffId`、`maintained`
|
||||
- 列表区移除“柜员号”列,展示顺序调整为征信对象摘要字段
|
||||
|
||||
### 3.2 删除提示文案调整
|
||||
|
||||
- 删除确认文案从“该员工当前已维护的征信信息”改为“该征信对象当前已维护的征信信息”
|
||||
|
||||
### 3.3 数据流校验
|
||||
|
||||
- `@/api/ccdiCreditInfo` 中上传、列表、详情、删除接口路径保持不变
|
||||
- 上传弹窗与详情弹窗交互保持可用,未引入额外页面或路由改动
|
||||
|
||||
## 4. 验证记录
|
||||
|
||||
### 4.1 失败验证
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
node ruoyi-ui/tests/unit/credit-info-page-layout.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
- 首轮失败点与计划一致,页面仍包含 `staffId`、`maintained` 和旧删除文案
|
||||
|
||||
### 4.2 页面与契约验证
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
node ruoyi-ui/tests/unit/credit-info-page-layout.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-maintained-filter.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-detail-ui.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-api-contract.test.js
|
||||
node ruoyi-ui/tests/unit/credit-info-upload-ui.test.js
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
- 五个前端静态/契约测试全部通过
|
||||
- 页面已彻底移除员工口径筛选项与列表列
|
||||
- API 路径和上传交互契约未回退
|
||||
|
||||
### 4.3 前端构建
|
||||
|
||||
执行命令:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
执行结果:
|
||||
|
||||
- 构建通过,`dist/` 产物正常生成
|
||||
- 仅出现项目既有的包体积告警,未出现新增编译错误
|
||||
|
||||
## 5. 进程与环境说明
|
||||
|
||||
- 本次未启动本地前端 dev server
|
||||
- 无残留测试进程需要清理
|
||||
@@ -0,0 +1,25 @@
|
||||
# 2026-03-24 征信维护直接入库实施计划产出记录
|
||||
|
||||
## 本次产出
|
||||
|
||||
- 后端实施计划:`docs/plans/backend/2026-03-24-credit-info-direct-storage-backend-implementation.md`
|
||||
- 前端实施计划:`docs/plans/frontend/2026-03-24-credit-info-direct-storage-frontend-implementation.md`
|
||||
|
||||
## 计划范围
|
||||
|
||||
- 后端:删除员工存在性校验、按征信对象直接入库、列表查询改为征信表聚合、同步更新 DTO/VO 与测试
|
||||
- 前端:移除“柜员号”“是否已维护”、页面改为征信对象维度展示、同步更新静态契约测试与删除提示文案
|
||||
|
||||
## 关键实现约束
|
||||
|
||||
- 导入时不关联柜员或亲属
|
||||
- 解析成功后直接按 `person_id` 入库
|
||||
- 不新增征信主表,不拆新页面
|
||||
- 同一证件号继续只保留最新征信数据
|
||||
- 测试结束后若启动过前后端进程,需要主动关闭
|
||||
|
||||
## 执行说明
|
||||
|
||||
- 仓库约定不启用 subagent,后续执行计划时直接在当前会话使用 `executing-plans`
|
||||
- 提交前必须检查暂存区,仅允许包含本次任务相关文件
|
||||
- 若需要执行 SQL,涉及中文内容时优先使用 `bin/mysql_utf8_exec.sh`
|
||||
@@ -12,15 +12,6 @@
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="柜员号">
|
||||
<el-input
|
||||
v-model="queryParams.staffId"
|
||||
placeholder="请输入柜员号"
|
||||
clearable
|
||||
style="width: 240px"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号">
|
||||
<el-input
|
||||
v-model="queryParams.idCard"
|
||||
@@ -30,11 +21,6 @@
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否已维护">
|
||||
<el-select v-model="queryParams.maintained" placeholder="仅展示已维护数据" style="width: 240px">
|
||||
<el-option label="已维护" value="1" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||||
@@ -50,7 +36,6 @@
|
||||
|
||||
<el-table :data="creditInfoList" v-loading="loading">
|
||||
<el-table-column label="姓名" prop="name" align="center" />
|
||||
<el-table-column label="柜员号" prop="staffId" align="center" />
|
||||
<el-table-column label="身份证号" prop="idCard" align="center" />
|
||||
<el-table-column label="最近征信查询日期" align="center" width="160">
|
||||
<template slot-scope="scope">
|
||||
@@ -208,9 +193,7 @@ export default {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
staffId: undefined,
|
||||
idCard: undefined,
|
||||
maintained: "1",
|
||||
},
|
||||
};
|
||||
},
|
||||
@@ -240,9 +223,7 @@ export default {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
name: undefined,
|
||||
staffId: undefined,
|
||||
idCard: undefined,
|
||||
maintained: "1",
|
||||
};
|
||||
this.resetForm("queryForm");
|
||||
this.handleQuery();
|
||||
@@ -321,7 +302,7 @@ export default {
|
||||
handleDelete(row) {
|
||||
const personId = row.idCard;
|
||||
this.$modal
|
||||
.confirm("确认删除该员工当前已维护的征信信息吗?")
|
||||
.confirm("确认删除该征信对象当前已维护的征信信息吗?")
|
||||
.then(() => {
|
||||
return deleteCreditInfo(personId);
|
||||
})
|
||||
|
||||
@@ -19,7 +19,7 @@ const source = fs.readFileSync(componentPath, "utf8");
|
||||
"handleDetail",
|
||||
"handleDelete",
|
||||
"deleteCreditInfo",
|
||||
"确认删除该员工当前已维护的征信信息吗?",
|
||||
"确认删除该征信对象当前已维护的征信信息吗?",
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `详情或删除交互缺少关键结构: ${token}`);
|
||||
});
|
||||
|
||||
@@ -8,14 +8,13 @@ const componentPath = path.resolve(
|
||||
);
|
||||
const source = fs.readFileSync(componentPath, "utf8");
|
||||
|
||||
assert(
|
||||
source.includes('maintained: "1"'),
|
||||
"征信维护页面应默认只查询已维护数据"
|
||||
);
|
||||
assert(!source.includes("maintained:"), "征信维护页面不应再维护 maintained 查询参数");
|
||||
|
||||
assert(
|
||||
!source.includes('label="未维护"'),
|
||||
"征信维护页面不应再提供未维护筛选项"
|
||||
!source.includes('label="是否已维护"'),
|
||||
"征信维护页面不应再展示是否已维护筛选项"
|
||||
);
|
||||
|
||||
assert(!source.includes('value="1"'), "征信维护页面不应再内置已维护默认筛选");
|
||||
|
||||
console.log("credit-info-maintained-filter test passed");
|
||||
|
||||
@@ -13,6 +13,8 @@ const source = fs.readFileSync(componentPath, "utf8");
|
||||
|
||||
[
|
||||
"征信维护",
|
||||
"姓名",
|
||||
"身份证号",
|
||||
"批量上传征信HTML",
|
||||
"最近征信查询日期",
|
||||
"负债笔数",
|
||||
@@ -22,9 +24,11 @@ const source = fs.readFileSync(componentPath, "utf8");
|
||||
"行政处罚笔数",
|
||||
"详情",
|
||||
"删除",
|
||||
"@/api/ccdiCreditInfo",
|
||||
].forEach((token) => {
|
||||
assert(source.includes(token), `征信维护页面缺少关键结构: ${token}`);
|
||||
});
|
||||
|
||||
assert(!source.includes('label="柜员号"'), "征信维护页面不应再展示柜员号查询项");
|
||||
assert(!source.includes('prop="staffId"'), "征信维护列表不应再展示柜员号列");
|
||||
|
||||
console.log("credit-info-page-layout test passed");
|
||||
|
||||
Reference in New Issue
Block a user