From 4a7cfde4af419498fb24bbc75a85a8d1e9fd4acf Mon Sep 17 00:00:00 2001
From: wjj <2069666735@qq.com>
Date: Thu, 16 Jul 2026 14:47:04 +0800
Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E6=95=B4=E4=B8=93=E9=A1=B9=E6=8E=92?=
=?UTF-8?q?=E6=9F=A5=E8=B5=84=E4=BA=A7=E6=94=B6=E5=85=A5=E5=8C=B9=E9=85=8D?=
=?UTF-8?q?=E5=8F=A3=E5=BE=84?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
...ProjectFamilyAssetLiabilityListItemVO.java | 15 ++
.../vo/CcdiProjectFamilyIncomeDetailVO.java | 6 +
.../CcdiProjectSpecialCheckServiceImpl.java | 1 +
.../project/CcdiProjectSpecialCheckMapper.xml | 153 ++++++++++++------
...t-income-caliber-backend-implementation.md | 39 +++++
...-income-caliber-frontend-implementation.md | 42 +++++
...7-16-special-check-asset-income-caliber.md | 32 ++++
.../detail/FamilyAssetLiabilityDetail.vue | 88 ++++++++--
.../detail/FamilyAssetLiabilitySection.vue | 11 +-
9 files changed, 315 insertions(+), 72 deletions(-)
create mode 100644 docs/plans/backend/2026-07-16-special-check-asset-income-caliber-backend-implementation.md
create mode 100644 docs/plans/frontend/2026-07-16-special-check-asset-income-caliber-frontend-implementation.md
create mode 100644 docs/reports/implementation/2026-07-16-special-check-asset-income-caliber.md
diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java
index 23b90ed2..9786c464 100644
--- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java
+++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyAssetLiabilityListItemVO.java
@@ -24,6 +24,15 @@ public class CcdiProjectFamilyAssetLiabilityListItemVO {
/** 家庭总年收入 */
private BigDecimal totalIncome;
+ /** 本人年收入 */
+ private BigDecimal selfIncome;
+
+ /** 配偶年收入 */
+ private BigDecimal spouseIncome;
+
+ /** 本人入职年限 */
+ private Integer employmentYears;
+
/** 家庭总资产 */
private BigDecimal totalAsset;
@@ -33,6 +42,12 @@ public class CcdiProjectFamilyAssetLiabilityListItemVO {
/** 收入负债对比金额 */
private BigDecimal comparisonAmount;
+ /** 可解释收入 */
+ private BigDecimal explainableIncome;
+
+ /** 资产收入倍数 */
+ private BigDecimal assetIncomeRatio;
+
/** 风险等级编码 */
private String riskLevelCode;
diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java
index ee2ddb43..5d0b23d0 100644
--- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java
+++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectFamilyIncomeDetailVO.java
@@ -15,6 +15,12 @@ public class CcdiProjectFamilyIncomeDetailVO {
/** 配偶年收入 */
private BigDecimal spouseIncome;
+ /** 本人入职年限 */
+ private Integer employmentYears;
+
/** 家庭总年收入 */
private BigDecimal totalIncome;
+
+ /** 可解释收入 */
+ private BigDecimal explainableIncome;
}
diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java
index 5cb4f093..74aa690a 100644
--- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java
+++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectSpecialCheckServiceImpl.java
@@ -227,6 +227,7 @@ public class CcdiProjectSpecialCheckServiceImpl implements ICcdiProjectSpecialCh
incomeDetail.setSelfIncome(BigDecimal.ZERO);
incomeDetail.setSpouseIncome(BigDecimal.ZERO);
incomeDetail.setTotalIncome(BigDecimal.ZERO);
+ incomeDetail.setExplainableIncome(BigDecimal.ZERO);
detail.setIncomeDetail(incomeDetail);
}
diff --git a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml
index d913cc05..9e585bf4 100644
--- a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml
+++ b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiProjectSpecialCheckMapper.xml
@@ -9,9 +9,14 @@
+
+
+
+
+
@@ -95,7 +100,9 @@
javaType="com.ruoyi.ccdi.project.domain.vo.CcdiProjectFamilyIncomeDetailVO">
+
+
@@ -126,9 +133,14 @@
+
+
+
+
+
@@ -194,44 +206,58 @@
aggregated.staff_name,
aggregated.dept_name,
aggregated.total_income,
+ aggregated.self_income,
+ aggregated.spouse_income,
+ aggregated.employment_years,
aggregated.total_asset,
aggregated.total_debt,
aggregated.comparison_amount,
+ aggregated.explainable_income,
+ aggregated.asset_income_ratio,
case
- when aggregated.missing_asset_info = 1 or aggregated.missing_debt_info = 1 then 'MISSING_INFO'
- when comparison_amount <= total_asset * 1.5 then 'NORMAL'
- when comparison_amount > total_asset * 1.5 and comparison_amount <= total_asset * 3 then 'RISK'
- when comparison_amount > total_asset * 3 then 'HIGH'
+ when aggregated.missing_info = 1 then 'MISSING_INFO'
+ when aggregated.asset_income_ratio <= 1.5 then 'NORMAL'
+ when aggregated.asset_income_ratio > 1.5 and aggregated.asset_income_ratio <= 3 then 'RISK'
+ when aggregated.asset_income_ratio > 3 then 'HIGH'
else 'HIGH'
end as risk_level_code,
case
- when aggregated.missing_asset_info = 1 or aggregated.missing_debt_info = 1 then '缺少信息'
- when comparison_amount <= total_asset * 1.5 then '正常'
- when comparison_amount > total_asset * 1.5 and comparison_amount <= total_asset * 3 then '存在风险'
- when comparison_amount > total_asset * 3 then '高风险'
- else '高风险'
+ when aggregated.missing_info = 1 then '缺少信息'
+ when aggregated.asset_income_ratio <= 1.5 then '正常'
+ when aggregated.asset_income_ratio > 1.5 and aggregated.asset_income_ratio <= 3 then '关注'
+ when aggregated.asset_income_ratio > 3 then '高关注'
+ else '高关注'
end as risk_level_name
from (
select
source.*,
case
- when source.self_asset_record_count = 0
- or source.spouse_staff_asset_record_count = 0 then 1
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0 then 1
else 0
- end as missing_asset_info,
+ end as missing_info,
+ source.self_income * source.employment_years
+ + source.spouse_income
+ + source.total_debt as explainable_income,
+ source.self_income * source.employment_years
+ + source.spouse_income
+ + source.total_debt as comparison_amount,
case
- when source.self_debt_record_count = 0
- or source.spouse_staff_debt_record_count = 0 then 1
- else 0
- end as missing_debt_info,
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0
+ or (source.self_income * source.employment_years + source.spouse_income + source.total_debt) <= 0 then null
+ else source.total_asset / (source.self_income * source.employment_years + source.spouse_income + source.total_debt)
+ end as asset_income_ratio,
case
- when source.self_asset_record_count = 0
- or source.spouse_staff_asset_record_count = 0
- or source.self_debt_record_count = 0
- or source.spouse_staff_debt_record_count = 0 then 4
- when source.comparison_amount <= source.total_asset * 1.5 then 1
- when source.comparison_amount <= source.total_asset * 3 then 2
- when source.comparison_amount > source.total_asset * 3 then 3
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0
+ or (source.self_income * source.employment_years + source.spouse_income + source.total_debt) <= 0 then 0
+ when source.total_asset / (source.self_income * source.employment_years + source.spouse_income + source.total_debt) <= 1.5 then 1
+ when source.total_asset / (source.self_income * source.employment_years + source.spouse_income + source.total_debt) <= 3 then 2
+ when source.total_asset / (source.self_income * source.employment_years + source.spouse_income + source.total_debt) > 3 then 3
else 3
end as risk_level_sort
from (
@@ -240,6 +266,12 @@
scope.staff_code,
scope.staff_name,
scope.dept_name,
+ coalesce(base_staff.annual_income, 0) as self_income,
+ coalesce(spouse.spouse_income, 0) as spouse_income,
+ case
+ when base_staff.hire_date is null then null
+ else greatest(1, ceiling(datediff(curdate(), base_staff.hire_date) / 365))
+ end as employment_years,
coalesce(base_staff.annual_income, 0) + coalesce(spouse.spouse_income, 0) as total_income,
coalesce((
select count(1)
@@ -294,15 +326,7 @@
from ccdi_debts_info debt
where debt.person_id = scope.staff_id_card
or (spouse.spouse_id_card is not null and debt.person_id = spouse.spouse_id_card)
- ), 0) as total_debt,
- coalesce(base_staff.annual_income, 0)
- + coalesce(spouse.spouse_income, 0)
- + coalesce((
- select sum(coalesce(debt.principal_balance, 0))
- from ccdi_debts_info debt
- where debt.person_id = scope.staff_id_card
- or (spouse.spouse_id_card is not null and debt.person_id = spouse.spouse_id_card)
- ), 0) as comparison_amount
+ ), 0) as total_debt
from (
) scope
@@ -328,7 +352,9 @@
aggregated.dept_name,
aggregated.self_income as income_self_income,
aggregated.spouse_income as income_spouse_income,
+ aggregated.employment_years as income_employment_years,
aggregated.total_income as income_total_income,
+ aggregated.explainable_income as income_explainable_income,
aggregated.missing_self_asset_info as asset_missing_self_asset_info,
aggregated.self_total_asset as asset_self_total_asset,
aggregated.spouse_total_asset as asset_spouse_total_asset,
@@ -342,36 +368,61 @@
aggregated.staff_name as summary_staff_name,
aggregated.dept_name as summary_dept_name,
aggregated.total_income as summary_total_income,
+ aggregated.self_income as summary_self_income,
+ aggregated.spouse_income as summary_spouse_income,
+ aggregated.employment_years as summary_employment_years,
aggregated.total_asset as summary_total_asset,
aggregated.total_debt as summary_total_debt,
aggregated.comparison_amount as summary_comparison_amount,
+ aggregated.explainable_income as summary_explainable_income,
+ aggregated.asset_income_ratio as summary_asset_income_ratio,
case
- when aggregated.missing_self_asset_info = 1 or aggregated.missing_self_debt_info = 1 then 'MISSING_INFO'
- when comparison_amount <= total_asset * 1.5 then 'NORMAL'
- when comparison_amount > total_asset * 1.5 and comparison_amount <= total_asset * 3 then 'RISK'
- when comparison_amount > total_asset * 3 then 'HIGH'
+ when aggregated.missing_info = 1 then 'MISSING_INFO'
+ when aggregated.asset_income_ratio <= 1.5 then 'NORMAL'
+ when aggregated.asset_income_ratio > 1.5 and aggregated.asset_income_ratio <= 3 then 'RISK'
+ when aggregated.asset_income_ratio > 3 then 'HIGH'
else 'HIGH'
end as summary_risk_level_code,
case
- when aggregated.missing_self_asset_info = 1 or aggregated.missing_self_debt_info = 1 then '缺少信息'
- when comparison_amount <= total_asset * 1.5 then '正常'
- when comparison_amount > total_asset * 1.5 and comparison_amount <= total_asset * 3 then '存在风险'
- when comparison_amount > total_asset * 3 then '高风险'
- else '高风险'
+ when aggregated.missing_info = 1 then '缺少信息'
+ when aggregated.asset_income_ratio <= 1.5 then '正常'
+ when aggregated.asset_income_ratio > 1.5 and aggregated.asset_income_ratio <= 3 then '关注'
+ when aggregated.asset_income_ratio > 3 then '高关注'
+ else '高关注'
end as summary_risk_level_name
from (
select
source.*,
case
- when source.self_asset_record_count = 0
- or source.spouse_staff_asset_record_count = 0 then 1
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0 then 1
else 0
end as missing_self_asset_info,
case
when source.self_debt_record_count = 0
or source.spouse_staff_debt_record_count = 0 then 1
else 0
- end as missing_self_debt_info
+ end as missing_self_debt_info,
+ case
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0 then 1
+ else 0
+ end as missing_info,
+ source.self_income * source.employment_years
+ + source.spouse_income
+ + source.total_debt as explainable_income,
+ source.self_income * source.employment_years
+ + source.spouse_income
+ + source.total_debt as comparison_amount,
+ case
+ when source.self_income <= 0
+ or source.employment_years is null
+ or source.total_asset <= 0
+ or (source.self_income * source.employment_years + source.spouse_income + source.total_debt) <= 0 then null
+ else source.total_asset / (source.self_income * source.employment_years + source.spouse_income + source.total_debt)
+ end as asset_income_ratio
from (
select
#{projectId} as project_id,
@@ -383,6 +434,10 @@
spouse.spouse_is_staff,
coalesce(base_staff.annual_income, 0) as self_income,
coalesce(spouse.spouse_income, 0) as spouse_income,
+ case
+ when base_staff.hire_date is null then null
+ else greatest(1, ceiling(datediff(curdate(), base_staff.hire_date) / 365))
+ end as employment_years,
coalesce(base_staff.annual_income, 0) + coalesce(spouse.spouse_income, 0) as total_income,
coalesce((
select count(1)
@@ -471,15 +526,7 @@
from ccdi_debts_info debt
where debt.person_id = scope.staff_id_card
or (spouse.spouse_id_card is not null and debt.person_id = spouse.spouse_id_card)
- ), 0) as total_debt,
- coalesce(base_staff.annual_income, 0)
- + coalesce(spouse.spouse_income, 0)
- + coalesce((
- select sum(coalesce(debt.principal_balance, 0))
- from ccdi_debts_info debt
- where debt.person_id = scope.staff_id_card
- or (spouse.spouse_id_card is not null and debt.person_id = spouse.spouse_id_card)
- ), 0) as comparison_amount
+ ), 0) as total_debt
from (
) scope
diff --git a/docs/plans/backend/2026-07-16-special-check-asset-income-caliber-backend-implementation.md b/docs/plans/backend/2026-07-16-special-check-asset-income-caliber-backend-implementation.md
new file mode 100644
index 00000000..4a6d4043
--- /dev/null
+++ b/docs/plans/backend/2026-07-16-special-check-asset-income-caliber-backend-implementation.md
@@ -0,0 +1,39 @@
+# 专项排查资产收入匹配口径后端实施计划
+
+## 保存路径确认
+
+本文档保存于 `docs/plans/backend/`,用于记录专项排查后端口径调整计划。
+
+## 背景
+
+专项排查家庭资产负债原逻辑将无负债记录判为缺少信息,且使用收入、负债、资产之间的旧比较方式,无法满足“无负债仍需输出资产收入匹配判断”的业务口径。
+
+## 实施范围
+
+- 调整 `CcdiProjectSpecialCheckMapper.xml` 中家庭资产负债列表与详情查询。
+- 保留家庭总年收入、家庭总资产、家庭总负债等原字段。
+- 新增本人年收入、配偶年收入、本人入职年限、可解释收入、资产收入倍数等返回字段。
+- 风险等级统一为 `高关注`、`关注`、`正常`、`缺少信息`。
+
+## 计算口径
+
+- 本人年收入取 `ccdi_base_staff.annual_income`。
+- 本人入职年限由 `ccdi_base_staff.hire_date` 按当前日期折算,不足 1 年按 1 年。
+- 配偶年收入取配偶员工年收入或亲属关系年收入。
+- 家庭总资产取本人及配偶 `ccdi_asset_info.current_value` 合计。
+- 家庭总负债取本人及配偶 `ccdi_debts_info.principal_balance` 合计,无记录按 0。
+- 可解释收入 = 本人年收入 × 本人入职年限 + 配偶年收入 + 家庭总负债。
+- 资产收入倍数 = 家庭总资产 / 可解释收入。
+
+## 风险规则
+
+- 缺少信息:本人年收入为空或小于等于 0、入职时间为空、家庭总资产为空或小于等于 0。
+- 正常:资产收入倍数小于等于 1.5。
+- 关注:资产收入倍数大于 1.5 且小于等于 3。
+- 高关注:资产收入倍数大于 3。
+
+## 验证计划
+
+- 执行后端编译或针对 `ccdi-project` 模块的编译检查。
+- 检查 MyBatis XML 中新增字段映射与 SQL 别名一致。
+- 对典型数据进行公式复核:年收入 20 万、入职 10 年、资产 586 万、负债 0 时应为关注。
diff --git a/docs/plans/frontend/2026-07-16-special-check-asset-income-caliber-frontend-implementation.md b/docs/plans/frontend/2026-07-16-special-check-asset-income-caliber-frontend-implementation.md
new file mode 100644
index 00000000..1a57c3ac
--- /dev/null
+++ b/docs/plans/frontend/2026-07-16-special-check-asset-income-caliber-frontend-implementation.md
@@ -0,0 +1,42 @@
+# 专项排查资产收入匹配口径前端实施计划
+
+## 保存路径确认
+
+本文档保存于 `docs/plans/frontend/`,用于记录专项排查前端展示调整计划。
+
+## 背景
+
+专项排查家庭资产负债详情需要展示新的资产收入匹配结论,并将家庭总年收入改为万元展示,便于业务人员阅读。
+
+## 实施范围
+
+- 调整 `FamilyAssetLiabilitySection.vue` 列表中的家庭总年收入展示为万元。
+- 调整 `FamilyAssetLiabilityDetail.vue` 总收入、本人收入、配偶收入展示为万元。
+- 将详查结果结论改为分行展示。
+- 结论显示风险等级、家庭总资产、可解释收入公式和资产收入倍数。
+
+## 展示口径
+
+详查结果结论示例:
+
+```text
+关注
+
+家庭总资产:586.00 万元
+可解释收入:本人年收入 20.00 万元 × 入职年限 10 年 + 配偶年收入 0.00 万元 + 家庭总负债 0.00 万元 = 200.00 万元
+资产收入倍数:2.93
+```
+
+缺少信息时仅显示:
+
+```text
+缺少资产,暂无法判断。
+```
+
+缺少项会按实际情况展示为收入、资产或入职时间;多项同时缺失时展示“关键信息不完整,暂无法判断。”。
+
+## 验证计划
+
+- 执行前端构建或静态编译检查。
+- 页面验证专项排查列表家庭总年收入为万元。
+- 页面验证详查结果按多行展示,且长公式不溢出容器。
diff --git a/docs/reports/implementation/2026-07-16-special-check-asset-income-caliber.md b/docs/reports/implementation/2026-07-16-special-check-asset-income-caliber.md
new file mode 100644
index 00000000..da2c186d
--- /dev/null
+++ b/docs/reports/implementation/2026-07-16-special-check-asset-income-caliber.md
@@ -0,0 +1,32 @@
+# 专项排查资产收入匹配口径实施记录
+
+## 保存路径确认
+
+本文档保存于 `docs/reports/implementation/`,用于记录本次专项排查口径调整的实施内容、影响范围与验证情况。
+
+## 修改内容
+
+- 后端专项排查家庭资产负债查询新增本人年收入、配偶年收入、入职年限、可解释收入、资产收入倍数。
+- 后端风险结论改为 `高关注`、`关注`、`正常`、`缺少信息`。
+- 无负债记录不再阻断结论判断,负债金额按 0 纳入可解释收入。
+- 前端专项排查列表中家庭总年收入改为万元展示。
+- 前端详查结果改为分行展示家庭总资产、可解释收入公式与资产收入倍数。
+- 缺少信息结论按实际缺项展示收入、资产或入职时间,多项缺失时展示关键信息不完整。
+- 隐藏家庭资产负债表格内置展开箭头,保留“查看详情”按钮作为展开入口,避免展开箭头挤在序号列前导致显示异常。
+
+## 影响范围
+
+- `ccdi-project` 专项排查家庭资产负债接口。
+- `ruoyi-ui` 项目详情专项排查家庭资产负债列表与展开详情。
+- 不涉及员工信息维护、资产导入、征信负债导入和数据库结构变更。
+
+## 验证情况
+
+- 已执行 `mvn -pl ccdi-project -am compile -DskipTests`,编译通过。执行过程中 Maven 提示 `ccdi-info-collection` 中存在既有重复依赖声明警告,本次未调整该无关问题。
+- 已执行前端 Node 环境确认。`.nvmrc` 指向 `14.21.3`,但本机 PowerShell 环境下 `nvm use` 未能直接切换该版本;按仓库约定改用已验证可用的 `Node v22.22.3`、`npm 10.9.8`。
+- 已执行 `npm run build:prod`,生产构建通过。构建输出存在既有资源体积警告,本次未调整该无关问题。
+- 已重新完整打包并启动真实后端 `ruoyi-admin.jar`,确认 62318 端口由本仓库 Java 进程监听,日志出现 `Started RuoYiApplication`。
+- 已在真实页面验证项目 42:员工“模型二测试员工”有收入、有入职时间、有资产、无负债,列表家庭总年收入展示为 `12.35 万元`,风险情况为 `正常`;详查结果展示 `本人年收入 12.35 万元 × 入职年限 7 年 + 配偶年收入 0.00 万元 + 家庭总负债 0.00 万元 = 86.42 万元`。
+- 已在真实页面验证项目 44:同一项目内两名员工均可按新口径展示,列表家庭总年收入分别展示为 `24.35 万元`、`12.35 万元`,风险情况为 `正常`。
+- 已在真实页面验证项目 90629002:员工有收入和入职时间但无资产,列表风险情况为 `缺少信息`,详查结果显示 `缺少资产,暂无法判断。`
+- 已在真实页面验证家庭资产负债表格展开箭头隐藏生效,序号列前不再显示异常符号;继续通过“查看详情”展开明细。
diff --git a/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilityDetail.vue b/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilityDetail.vue
index e7a0ce6d..1ba129ad 100644
--- a/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilityDetail.vue
+++ b/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilityDetail.vue
@@ -4,16 +4,16 @@
本人收入
- {{ formatAmount(incomeDetail.selfIncome) }}
+ {{ formatWanAmount(incomeDetail.selfIncome) }}
配偶收入
- {{ formatAmount(incomeDetail.spouseIncome) }}
+ {{ formatWanAmount(incomeDetail.spouseIncome) }}
@@ -69,7 +69,7 @@
{{ assetDebtRatio }}
- 资产/收入比
+ 资产收入倍数
{{ assetIncomeRatio }}
@@ -86,7 +86,9 @@
结论
-
{{ riskResult.text }}
+
@@ -115,7 +117,9 @@ export default {
: {
selfIncome: 0,
spouseIncome: 0,
+ employmentYears: null,
totalIncome: 0,
+ explainableIncome: 0,
};
},
summary() {
@@ -160,6 +164,15 @@ export default {
totalDebt() {
return this.resolveAmount(this.summary.totalDebt, this.debtDetail.totalDebt);
},
+ employmentYears() {
+ const target = this.summary.employmentYears !== undefined && this.summary.employmentYears !== null
+ ? this.summary.employmentYears
+ : this.incomeDetail.employmentYears;
+ return target === undefined || target === null || target === "" ? null : Number(target);
+ },
+ explainableIncome() {
+ return this.resolveAmount(this.summary.explainableIncome, this.incomeDetail.explainableIncome);
+ },
assetItems() {
return Array.isArray(this.assetDetail.items) ? this.assetDetail.items : [];
},
@@ -184,12 +197,10 @@ export default {
isPercent: true,
});
},
- // 资产/收入比 = totalAsset / totalIncome
+ // 资产收入倍数 = totalAsset / explainableIncome
assetIncomeRatio() {
- return this.formatMetricValue(this.totalAsset / this.totalIncome, {
- denominator: this.totalIncome,
- suffix: "倍",
- });
+ const ratio = this.resolveRatio(this.summary.assetIncomeRatio, this.totalAsset, this.explainableIncome);
+ return this.formatRatio(ratio);
},
// 负债/收入比 = totalDebt / totalIncome
debtIncomeRatio() {
@@ -202,22 +213,22 @@ export default {
const riskResultMap = {
NORMAL: {
name: this.summary.riskLevelName || "正常",
- text: "结构基本合理",
+ lines: this.buildResultLines(),
type: "success",
},
RISK: {
- name: this.summary.riskLevelName || "存在风险",
- text: "负债与收入压力偏高",
+ name: this.summary.riskLevelName || "关注",
+ lines: this.buildResultLines(),
type: "warning",
},
HIGH: {
- name: this.summary.riskLevelName || "高风险",
- text: "资产负债结构明显异常",
+ name: this.summary.riskLevelName || "高关注",
+ lines: this.buildResultLines(),
type: "danger",
},
MISSING_INFO: {
name: this.summary.riskLevelName || "缺少信息",
- text: "当前信息不完整",
+ lines: [this.buildMissingInfoLine()],
type: "info",
},
};
@@ -246,6 +257,46 @@ export default {
maximumFractionDigits: 2,
})} 万元`;
},
+ buildResultLines() {
+ return [
+ `家庭总资产:${this.formatWanAmount(this.totalAsset)}`,
+ `可解释收入:本人年收入 ${this.formatWanAmount(this.incomeDetail.selfIncome)} × 入职年限 ${this.employmentYears || "-"} 年 + 配偶年收入 ${this.formatWanAmount(this.incomeDetail.spouseIncome)} + 家庭总负债 ${this.formatWanAmount(this.totalDebt)} = ${this.formatWanAmount(this.explainableIncome)}`,
+ `资产收入倍数:${this.formatRatio(this.resolveRatio(this.summary.assetIncomeRatio, this.totalAsset, this.explainableIncome))}`,
+ ];
+ },
+ buildMissingInfoLine() {
+ const missing = [];
+ if (this.resolveAmount(this.incomeDetail.selfIncome) <= 0) {
+ missing.push("收入");
+ }
+ if (this.resolveAmount(this.totalAsset) <= 0) {
+ missing.push("资产");
+ }
+ if (!this.employmentYears) {
+ missing.push("入职时间");
+ }
+ return missing.length === 1
+ ? `缺少${missing[0]},暂无法判断。`
+ : "关键信息不完整,暂无法判断。";
+ },
+ resolveRatio(preferred, numerator, denominator) {
+ if (preferred !== undefined && preferred !== null && preferred !== "") {
+ const ratio = Number(preferred);
+ return Number.isFinite(ratio) ? ratio : null;
+ }
+ const divisor = Number(denominator || 0);
+ if (!divisor) {
+ return null;
+ }
+ const ratio = Number(numerator || 0) / divisor;
+ return Number.isFinite(ratio) ? ratio : null;
+ },
+ formatRatio(value) {
+ if (value === null || value === undefined || !Number.isFinite(Number(value))) {
+ return "-";
+ }
+ return Number(value).toFixed(2);
+ },
buildAmountGroups(items, amountField, resolveLabel, totalAmount) {
const groupMap = items.reduce((result, item, index) => {
const label = resolveLabel(item);
@@ -467,6 +518,11 @@ export default {
color: #111827;
}
+.result-card-line {
+ line-height: 1.7;
+ word-break: break-word;
+}
+
.empty-hint {
font-size: 13px;
color: #94a3b8;
diff --git a/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilitySection.vue b/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilitySection.vue
index 6409ebe6..b84c78cc 100644
--- a/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilitySection.vue
+++ b/ruoyi-ui/src/views/ccdiProject/components/detail/FamilyAssetLiabilitySection.vue
@@ -19,7 +19,7 @@
-
+
@@ -47,7 +47,7 @@
- {{ formatAmount(scope.row.totalIncome) }}
+ {{ formatWanAmount(scope.row.totalIncome) }}
@@ -201,7 +201,7 @@ export default {
}
const detail = this.detailCache[row.staffIdCard] || {};
const summary = detail.summary || {};
- const evidenceSummary = `${row.staffName}家庭资产负债核查:家庭总年收入${this.formatAmount(row.totalIncome)},家庭总负债${this.formatAmount(row.totalDebt)},家庭总资产${this.formatWanAmount(row.totalAsset)},风险情况${row.riskLevelName || "-" }。`;
+ const evidenceSummary = `${row.staffName}家庭资产负债核查:家庭总年收入${this.formatWanAmount(row.totalIncome)},家庭总负债${this.formatAmount(row.totalDebt)},家庭总资产${this.formatWanAmount(row.totalAsset)},风险情况${row.riskLevelName || "-" }。`;
this.$emit("evidence-confirm", {
evidenceType: "ASSET",
relatedPersonName: row.staffName || "关联人员",
@@ -291,4 +291,9 @@ export default {
background: #f8fafc;
color: #64748b;
}
+
+::v-deep .family-expand-column .cell,
+::v-deep .family-expand-column .el-table__expand-icon {
+ display: none;
+}