From a0fd1d0e4e036f5e86924a09e32976d0dc613d2c Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Thu, 22 Jan 2026 09:20:28 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E8=BE=93=E5=87=BA=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .claude/settings.local.json | 4 +- doc/api/loan-pricing-workflow-api.md | 185 +++++++++-- .../add-model-output-display/design.md | 160 +++++++++ .../add-model-output-display/proposal.md | 74 +++++ .../specs/loan-pricing-workflow-ui/spec.md | 63 ++++ .../changes/add-model-output-display/tasks.md | 53 +++ .../config/handler/MyMetaHandler.java | 6 +- .../components/ModelOutputDisplay.vue | 306 ++++++++++++++++++ .../src/views/loanPricing/workflow/detail.vue | 265 +++++++++++---- 9 files changed, 1014 insertions(+), 102 deletions(-) create mode 100644 openspec/changes/add-model-output-display/design.md create mode 100644 openspec/changes/add-model-output-display/proposal.md create mode 100644 openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md create mode 100644 openspec/changes/add-model-output-display/tasks.md create mode 100644 ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 973268b..c56f740 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -15,7 +15,9 @@ "Bash(openspec archive add-loan-pricing-create:*)", "Bash(git add:*)", "Bash(cd:*)", - "mcp__zai-mcp-server__extract_text_from_screenshot" + "mcp__zai-mcp-server__extract_text_from_screenshot", + "Bash(npx openspec validate:*)", + "Bash(npx openspec show:*)" ], "additionalDirectories": [ "d:\\利率定价\\loan-pricing-892\\loan-pricing-892-v2.0" diff --git a/doc/api/loan-pricing-workflow-api.md b/doc/api/loan-pricing-workflow-api.md index c280122..3e61901 100644 --- a/doc/api/loan-pricing-workflow-api.md +++ b/doc/api/loan-pricing-workflow-api.md @@ -74,6 +74,8 @@ "code": 200, "msg": "操作成功", "data": { + "id": 1, + "modelOutputId": 100, "serialNum": "20250119143025123", "orgCode": "931000", "runType": "1", @@ -108,6 +110,8 @@ | createBy | String | 否 | 创建者(筛选条件) | | custName | String | 否 | 客户名称(模糊查询) | | orgCode | String | 否 | 机构号(筛选条件) | +| custType | String | 否 | 客户类型(筛选条件) | +| guarType | String | 否 | 担保方式(筛选条件) | **请求示例:** @@ -123,6 +127,8 @@ GET /loanPricing/workflow/list?pageNum=1&pageSize=10&custName=科技 "msg": "查询成功", "rows": [ { + "id": 1, + "modelOutputId": 100, "serialNum": "20250119143025123", "orgCode": "931000", "custIsn": "CUST001", @@ -146,7 +152,7 @@ GET /loanPricing/workflow/list?pageNum=1&pageSize=10&custName=科技 ### 3. 查看利率定价流程详情 -根据业务方流水号查询流程的完整信息。 +根据业务方流水号查询流程的完整信息,包括模型输出字段。 **接口地址:** `GET /loanPricing/workflow/{serialNum}` @@ -171,39 +177,152 @@ GET /loanPricing/workflow/20250119143025123 "code": 200, "msg": "查询成功", "data": { - "serialNum": "20250119143025123", - "orgCode": "931000", - "runType": "1", - "custIsn": "CUST001", - "custType": "企业", - "guarType": "抵押", - "midPerQuickPay": "false", - "midPerEleDdc": "false", - "midEntEleDdc": "false", - "midEntWaterDdc": "false", - "applyAmt": "1000000", - "isCleanEnt": "false", - "hasSettleAcct": "false", - "isManufacturing": "true", - "isAgriGuar": "false", - "isTaxA": "false", - "isAgriLeading": "false", - "loanPurpose": "business", - "bizProof": "true", - "collType": "一类", - "collThirdParty": "false", - "loanRate": "4.35", - "custName": "某某科技有限公司", - "idType": "统一社会信用代码", - "isInclusiveFinance": "true", - "createTime": "2025-01-19 14:30:25", - "createBy": "admin", - "updateTime": "2025-01-19 15:20:10", - "updateBy": "admin" + "loanPricingWorkflow": { + "id": 1, + "modelOutputId": 100, + "serialNum": "20250119143025123", + "orgCode": "931000", + "runType": "1", + "custIsn": "CUST001", + "custType": "企业", + "guarType": "抵押", + "midPerQuickPay": "false", + "midPerEleDdc": "false", + "midEntEleDdc": "false", + "midEntWaterDdc": "false", + "applyAmt": "1000000", + "isCleanEnt": "false", + "hasSettleAcct": "false", + "isManufacturing": "true", + "isAgriGuar": "false", + "isTaxA": "false", + "isAgriLeading": "false", + "loanPurpose": "business", + "bizProof": "true", + "collType": "一类", + "collThirdParty": "false", + "loanRate": "4.35", + "custName": "某某科技有限公司", + "idType": "统一社会信用代码", + "isInclusiveFinance": "true", + "createTime": "2025-01-19 14:30:25", + "createBy": "admin", + "updateTime": "2025-01-19 15:20:10", + "updateBy": "admin" + }, + "modelRetailOutputFields": { + "id": 1, + "custIsn": "CUST001", + "custType": "个人", + "custName": "张三", + "idType": "身份证", + "idNum": "330102199001011234", + "baseLoanRate": "3.45", + "isFirstLoan": "true", + "faithDay": "365", + "custAge": "35", + "bpFirstLoan": "-10", + "bpAgeLoan": "-5", + "bpAge": "0", + "totalBpLoyalty": "-15", + "balanceAvg": "50000", + "loanAvg": "300000", + "derivationRate": "0.6", + "totalBpContribution": "-20", + "midPerCard": "true", + "midPerPass": "false", + "midPerHarvest": "true", + "midPerEffect": "true", + "midPerQuickPay": "false", + "midPerEleDdc": "false", + "midPerWaterDdc": "false", + "midPerHuashuDdc": "false", + "MidPerGasDdc": "false", + "midPerCitizencard": "true", + "midPerFinMan": "false", + "midPerEtc": "true", + "bpMid": "-15", + "totoalBpRelevance": "-50", + "applyAmt": "500000", + "bpLoanAmount": "0", + "loanPurpose": "consumer", + "bizProof": "false", + "bpLoanUse": "0", + "loanLoop": "false", + "bpLoanLoop": "0", + "collType": "一类", + "collThirdParty": "false", + "bpCollateral": "-30", + "greyCust": "false", + "prinOverdue": "false", + "interestOverdue": "false", + "cardOverdue": "false", + "bpGreyOverdue": "0", + "totoalBpRisk": "0", + "totalBp": "-80", + "calculateRate": "2.65" + }, + "modelCorpOutputFields": { + "id": 2, + "custIsn": "CUST001", + "custType": "企业", + "custName": "某某科技有限公司", + "idType": "统一社会信用代码", + "idNum": "91330100MA2ABCDE01", + "baseLoanRate": "3.45", + "isFirstLoan": "false", + "faithDay": "730", + "bpFirstLoan": "0", + "bpAgeLoan": "-5", + "totalBpLoyalty": "-5", + "balanceAvg": "500000", + "loanAvg": "3000000", + "derivationRate": "0.16", + "totalBpContribution": "-30", + "midEntConnect": "true", + "midEntEffect": "true", + "midEntInter": "false", + "midEntAccept": "true", + "midEntDiscount": "false", + "midEntEleDdc": "true", + "midEntWaterDdc": "false", + "midEntTax": "true", + "bpMid": "-20", + "payroll": "50", + "invLoanAmount": "2000000", + "bpPayroll": "-10", + "isCleanEnt": "true", + "hasSettleAcct": "true", + "isAgriGuar": "false", + "isGreenLoan": "false", + "isTechEnt": "true", + "bpEntType": "-25", + "totoalBpRelevance": "-55", + "loanTerm": "36", + "bpLoanTerm": "0", + "applyAmt": "1000000", + "bpLoanAmount": "0", + "collType": "一类", + "collThirdParty": "false", + "bpCollateral": "-30", + "greyCust": "false", + "prinOverdue": "false", + "interestOverdue": "false", + "cardOverdue": "false", + "bpGreyOverdue": "0", + "totoalBpRisk": "0", + "totalBp": "-85", + "calculateRate": "2.60" + } } } ``` +**说明:** +- `loanPricingWorkflow`: 利率定价流程基本信息 +- `modelRetailOutputFields`: 个人客户模型输出字段(当 custType 为个人时返回) +- `modelCorpOutputFields`: 企业客户模型输出字段(当 custType 为企业时返回) + --- ## 错误码说明 @@ -260,6 +379,12 @@ GET /loanPricing/workflow/20250119143025123 | 一类 | 一类抵押 | | 二类 | 二类抵押 | +### 运行模式 (runType) + +| 值 | 说明 | +|----|------| +| 1 | 同步运行 | + --- ## 在线文档 diff --git a/openspec/changes/add-model-output-display/design.md b/openspec/changes/add-model-output-display/design.md new file mode 100644 index 0000000..08fc8a4 --- /dev/null +++ b/openspec/changes/add-model-output-display/design.md @@ -0,0 +1,160 @@ +# 设计文档: 模型输出展示 + +## 概述 + +本文档描述在流程详情页面中添加模型输出展示功能的技术设计。 + +## 页面结构 + +### 当前布局 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 页面标题: 流程详情 [返回按钮] │ +├──────────────────────┬──────────────────────────────────┤ +│ 关键信息摘要 (30%) │ 详情标签页 (70%) │ +│ ┌────────────────┐ │ ┌────────────────────────────┐ │ +│ │ 流水号 │ │ │ [基本信息][业务信息]... │ │ +│ │ 客户名称 │ │ │ │ │ +│ │ 客户类型 │ │ │ 字段内容... │ │ +│ │ 申请金额 │ │ │ │ │ +│ │ 贷款利率 │ │ │ │ │ +│ │ 担保方式 │ │ │ │ │ +│ └────────────────┘ │ └────────────────────────────┘ │ +└──────────────────────┴──────────────────────────────────┘ +``` + +### 新增布局 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 页面标题: 流程详情 [返回按钮] │ +├──────────────────────┬──────────────────────────────────┤ +│ 关键信息摘要 (30%) │ 详情标签页 (70%) │ +│ ┌────────────────┐ │ ┌────────────────────────────┐ │ +│ │ 流水号 │ │ │ [基本信息][业务信息]... │ │ +│ │ 客户名称 │ │ │ │ │ +│ │ 客户类型 │ │ │ 字段内容... │ │ +│ │ 申请金额 │ │ │ │ │ +│ │ 贷款利率 │ │ │ │ │ +│ │ 担保方式 │ │ │ │ │ +│ └────────────────┘ │ └────────────────────────────┘ │ +├──────────────────────┴──────────────────────────────────┤ +│ 模型输出 (当有数据时显示) │ +│ ┌────────────────────────────────────────────────────┐│ +│ │ [基本信息][忠诚度分析][贡献度分析]... ││ +│ │ ││ +│ │ 字段内容... ││ +│ └────────────────────────────────────────────────────┘│ +└─────────────────────────────────────────────────────────┘ +``` + +## 组件设计 + +### ModelOutputDisplay 组件 + +建议创建独立的模型输出展示组件,便于维护和复用。 + +```vue + +``` + +## 数据流 + +### API 响应结构 + +```json +{ + "code": 200, + "msg": "查询成功", + "data": { + "loanPricingWorkflow": { ... }, + "modelRetailOutputFields": { ... }, // 个人客户时存在 + "modelCorpOutputFields": { ... } // 企业客户时存在 + } +} +``` + +### 组件 Props + +| Prop | 类型 | 说明 | +|------|------|------| +| custType | String | 客户类型(个人/企业) | +| retailOutput | Object | 个人客户模型输出数据 | +| corpOutput | Object | 企业客户模型输出数据 | + +## 样式规范 + +### 卡片样式 + +与现有 `.summary-card` 和 `.detail-card` 保持一致: + +- 头部背景色: `#fafafa` +- 边框颜色: `#ebeef5` +- 内边距: 头部 `16px 20px`, 内容 `20px` +- 标题字号: `16px`, 字重 `500` +- 标题颜色: `#303133` + +### Tab 样式 + +使用 Element UI 默认 Tab 样式,间距保持一致。 + +## 字段映射表 + +### 个人客户模型输出字段 + +| Tab | 字段名 | 显示标签 | 格式化 | +|-----|--------|----------|--------| +| 基本信息 | custIsn | 客户内码 | - | +| 基本信息 | custName | 客户名称 | - | +| 基本信息 | idType | 证件类型 | - | +| 基本信息 | idNum | 证件号码 | - | +| 基本信息 | baseLoanRate | 基准利率 | - | +| 测算结果 | totalBp | 浮动BP | - | +| 测算结果 | calculateRate | 测算利率 | 高亮显示 | + +### 企业客户模型输出字段 + +| Tab | 字段名 | 显示标签 | 格式化 | +|-----|--------|----------|--------| +| 基本信息 | custIsn | 客户内码 | - | +| 基本信息 | custName | 客户名称 | - | +| 基本信息 | idType | 证件类型 | - | +| 基本信息 | idNum | 证件号码 | - | +| 基本信息 | baseLoanRate | 基准利率 | - | +| 测算结果 | totalBp | 浮动BP | - | +| 测算结果 | calculateRate | 测算利率 | 高亮显示 | + +## 响应式设计 + +- 桌面端 (≥768px): 模型输出卡片宽度 100%,Tab 内容两列布局 +- 移动端 (<768px): 模型输出卡片宽度 100%,Tab 内容单列布局 diff --git a/openspec/changes/add-model-output-display/proposal.md b/openspec/changes/add-model-output-display/proposal.md new file mode 100644 index 0000000..be9cbef --- /dev/null +++ b/openspec/changes/add-model-output-display/proposal.md @@ -0,0 +1,74 @@ +# 提案: 在流程详情页添加模型输出展示 + +## 背景 + +利率定价流程详情接口已更新,新增了模型输出字段 (`modelRetailOutputFields` 和 `modelCorpOutputFields`)。目前前端详情页面仅展示流程基本信息,未展示模型输出数据。 + +## 问题 + +用户在查看流程详情时,无法看到模型计算的输出结果(包括各项 BP 值、测算利率等关键信息),影响业务决策和问题排查。 + +## 提案概述 + +在流程详情页面 (`/loanPricing/workflow/detail/:serialNum`) 下方新增独立的模型输出展示区域,根据客户类型(个人/企业)显示对应的模型输出字段。 + +### 展示逻辑 + +- 当 `loanPricingWorkflow.custType === "个人"` 时,展示 `modelRetailOutputFields` 字段 +- 当 `loanPricingWorkflow.custType === "企业"` 时,展示 `modelCorpOutputFields` 字段 +- 当模型输出数据为空时,隐藏该展示区域 + +### 布局结构 + +保持与现有页面风格一致,采用卡片 + Tab 标签页的形式展示模型输出字段。 + +#### 个人客户模型输出 Tab 分类 + +| Tab 名称 | 字段内容 | +|---------|---------| +| 基本信息 | 客户内码、客户名称、证件类型、证件号码、基准利率 | +| 忠诚度分析 | 我行首贷客户、用信天数、客户年龄、BP_首贷、BP_贷龄、BP_年龄、TOTAL_BP_忠诚度 | +| 贡献度分析 | 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 | +| 关联度分析 | 中间业务_个人_信用卡、中间业务_个人_一码通、中间业务_个人_丰收互联、中间业务_个人_有效客户、中间业务_个人_快捷支付、中间业务_个人_电费代扣、中间业务_个人_水费代扣、中间业务_个人_华数费代扣、中间业务_个人_煤气费代扣、中间业务_个人_市民卡、中间业务_个人_理财业务、中间业务_个人_etc、BP_中间业务、TOTAL_BP_关联度 | +| 贷款特征 | 申请金额、BP_贷款额度、贷款用途、是否有经营佐证、BP_贷款用途、循环功能、BP_循环功能、抵质押类型、抵质押物三方所有、BP_抵押物 | +| 风险度分析 | 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 | +| 测算结果 | 浮动BP、测算利率 | + +#### 企业客户模型输出 Tab 分类 + +| Tab 名称 | 字段内容 | +|---------|---------| +| 基本信息 | 客户内码、客户名称、证件类型、证件号码、基准利率 | +| 忠诚度分析 | 我行首贷客户、用信天数、BP_首贷、BP_贷龄、TOTAL_BP_忠诚度 | +| 贡献度分析 | 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 | +| 关联度分析 | 中间业务_企业_企业互联、中间业务_企业_有效价值客户、中间业务_企业_国际业务、中间业务_企业_承兑、中间业务_企业_贴现、中间业务_企业_电费代扣、中间业务_企业_水费代扣、中间业务_企业_税务代扣、BP_中间业务、代发工资户数、存量贷款余额、BP_代发工资、TOTAL_BP_关联度 | +| 企业类别 | 净身企业、开立基本结算账户、省农担担保贷款、绿色贷款、科技型企业、BP_企业客户类别 | +| 贷款特征 | 贷款期限、BP_贷款期限、申请金额、BP_贷款额度、抵质押类型、抵质押物三方所有、BP_抵押物 | +| 风险度分析 | 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 | +| 测算结果 | 浮动BP、测算利率 | + +## 影响范围 + +- 前端: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` +- API: 使用现有的 `GET /loanPricing/workflow/{serialNum}` 接口 + +## 设计考虑 + +1. **独立性**: 模型输出区域与流程基本信息分离,避免页面过于臃肿 +2. **一致性**: 采用与现有详情页面相同的卡片 + Tab 布局风格 +3. **响应式**: 保持移动端友好布局 +4. **可扩展**: 预留未来可能新增的模型输出字段 + +## 替代方案 + +### 方案 A: 在现有详情对话框中添加 Tab (未采纳) +- **优点**: 集中展示,减少页面跳转 +- **缺点**: 详情页改为独立页面后此方案不适用 + +### 方案 B: 新增独立页面展示模型输出 (未采纳) +- **优点**: 完全分离,职责清晰 +- **缺点**: 增加用户操作步骤,需要额外的路由和菜单配置 + +### 方案 C: 在详情页下方新增卡片区域 (采纳) +- **优点**: 一次性获取所有信息,用户体验好,实现简单 +- **缺点**: 单次页面内容较多(通过 Tab 解决) diff --git a/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md new file mode 100644 index 0000000..4f32336 --- /dev/null +++ b/openspec/changes/add-model-output-display/specs/loan-pricing-workflow-ui/spec.md @@ -0,0 +1,63 @@ +# loan-pricing-workflow-ui Spec Delta + +## ADDED Requirements + +### Requirement: 流程详情-模型输出展示 + +系统 SHALL 在流程详情页面中展示模型输出字段,根据客户类型显示对应的个人或企业模型输出数据。 + +#### Scenario: 查看个人客户模型输出 +- **WHEN** 用户在流程详情页面查看个人客户的流程记录,且后端返回了 `modelRetailOutputFields` 数据 +- **THEN** 系统在页面下方显示"模型输出"卡片区域,包含 7 个 Tab 标签页: + - **基本信息**: 客户内码、客户名称、证件类型、证件号码、基准利率 + - **忠诚度分析**: 我行首贷客户、用信天数、客户年龄、BP_首贷、BP_贷龄、BP_年龄、TOTAL_BP_忠诚度 + - **贡献度分析**: 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 + - **关联度分析**: 中间业务_个人_信用卡、中间业务_个人_一码通、中间业务_个人_丰收互联、中间业务_个人_有效客户、中间业务_个人_快捷支付、中间业务_个人_电费代扣、中间业务_个人_水费代扣、中间业务_个人_华数费代扣、中间业务_个人_煤气费代扣、中间业务_个人_市民卡、中间业务_个人_理财业务、中间业务_个人_etc、BP_中间业务、TOTAL_BP_关联度 + - **贷款特征**: 申请金额、BP_贷款额度、贷款用途、是否有经营佐证、BP_贷款用途、循环功能、BP_循环功能、抵质押类型、抵质押物三方所有、BP_抵押物 + - **风险度分析**: 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 + - **测算结果**: 浮动BP、测算利率 + +#### Scenario: 查看企业客户模型输出 +- **WHEN** 用户在流程详情页面查看企业客户的流程记录,且后端返回了 `modelCorpOutputFields` 数据 +- **THEN** 系统在页面下方显示"模型输出"卡片区域,包含 8 个 Tab 标签页: + - **基本信息**: 客户内码、客户名称、证件类型、证件号码、基准利率 + - **忠诚度分析**: 我行首贷客户、用信天数、BP_首贷、BP_贷龄、TOTAL_BP_忠诚度 + - **贡献度分析**: 存款年日均、贷款年日均、派生率、TOTAL_BP_贡献度 + - **关联度分析**: 中间业务_企业_企业互联、中间业务_企业_有效价值客户、中间业务_企业_国际业务、中间业务_企业_承兑、中间业务_企业_贴现、中间业务_企业_电费代扣、中间业务_企业_水费代扣、中间业务_企业_税务代扣、BP_中间业务、代发工资户数、存量贷款余额、BP_代发工资、TOTAL_BP_关联度 + - **企业类别**: 净身企业、开立基本结算账户、省农担担保贷款、绿色贷款、科技型企业、BP_企业客户类别 + - **贷款特征**: 贷款期限、BP_贷款期限、申请金额、BP_贷款额度、抵质押类型、抵质押物三方所有、BP_抵押物 + - **风险度分析**: 灰名单客户、本金逾期、利息逾期、信用卡逾期、BP_灰名单与逾期、TOTAL_BP_风险度 + - **测算结果**: 浮动BP、测算利率 + +#### Scenario: 无模型输出数据时隐藏展示区域 +- **WHEN** 用户在流程详情页面查看流程记录,但 `modelRetailOutputFields` 和 `modelCorpOutputFields` 均为空 +- **THEN** 系统不显示"模型输出"卡片区域 + +#### Scenario: 模型输出字段布尔值格式化 +- **WHEN** 模型输出字段中布尔类型值(如 "true"/"false") +- **THEN** 系统将其格式化为中文"是"/"否"显示 + +#### Scenario: 模型输出字段空值处理 +- **WHEN** 模型输出字段值为 null 或空字符串 +- **THEN** 系统显示占位符"-"或空,不显示 "null" 或 "undefined" + +#### Scenario: 模型输出区域布局一致性 +- **WHEN** 用户查看流程详情页面 +- **THEN** "模型输出"卡片区域的样式、Tab 样式、字体、间距与上方"流程详情"区域保持一致 + +#### Scenario: 模型输出区域响应式布局 +- **WHEN** 用户在移动设备或小屏幕上查看流程详情页面 +- **THEN** "模型输出"卡片区域正常显示,Tab 标签页可正常切换,字段描述列表采用单列布局 + +## MODIFIED Requirements + +### Requirement: 流程详情查看 + +系统 SHALL 提供流程详情查看功能,以独立页面形式展示完整的流程信息,包括模型输出数据。 + +#### Scenario: 查看流程详情 +- **WHEN** 用户在流程列表页面且具有 `loanPricing:workflow:query` 权限,点击列表中某条记录的"查看"按钮 +- **THEN** 系统跳转至流程详情页面 `/loanPricing/workflow/detail/:serialNum`,展示: + - **左侧摘要卡片**: 业务方流水号、客户名称、客户类型、申请金额、贷款利率、担保方式 + - **右侧详情标签页**: 基本信息页签、业务信息页签、中间业务标识页签、企业标识页签、其他信息页签 + - **下方模型输出卡片**: 当存在模型输出数据时显示,根据客户类型展示对应的个人或企业模型输出字段 diff --git a/openspec/changes/add-model-output-display/tasks.md b/openspec/changes/add-model-output-display/tasks.md new file mode 100644 index 0000000..f11a21e --- /dev/null +++ b/openspec/changes/add-model-output-display/tasks.md @@ -0,0 +1,53 @@ +# 任务列表: 模型输出展示功能 + +## 实施顺序 + +### 1. 前端页面结构调整 +- [x] 在 detail.vue 中新增模型输出展示区域(el-card) +- [x] 添加条件渲染逻辑:仅当模型输出数据存在时显示 +- [x] 添加客户类型判断逻辑:个人/企业显示不同字段 +- [x] 抽离模型输出组件 ModelOutputDisplay.vue + +### 2. 页面布局调整 +- [x] 将模型输出组件放在关键信息右侧(三栏布局) +- [x] 调整响应式布局支持不同屏幕尺寸 + +### 3. 个人客户模型输出组件 +- [x] 创建个人模型输出 Tab 结构(7 个 Tab) +- [x] 实现"基本信息"Tab 字段展示(5 个字段) +- [x] 实现"忠诚度分析"Tab 字段展示(7 个字段) +- [x] 实现"贡献度分析"Tab 字段展示(4 个字段) +- [x] 实现"关联度分析"Tab 字段展示(14 个字段) +- [x] 实现"贷款特征"Tab 字段展示(10 个字段) +- [x] 实现"风险度分析"Tab 字段展示(7 个字段) +- [x] 实现"测算结果"Tab 字段展示(2 个字段) + +### 4. 企业客户模型输出组件 +- [x] 创建企业模型输出 Tab 结构(8 个 Tab) +- [x] 实现"基本信息"Tab 字段展示(5 个字段) +- [x] 实现"忠诚度分析"Tab 字段展示(6 个字段) +- [x] 实现"贡献度分析"Tab 字段展示(4 个字段) +- [x] 实现"关联度分析"Tab 字段展示(13 个字段) +- [x] 实现"企业类别"Tab 字段展示(6 个字段) +- [x] 实现"贷款特征"Tab 字段展示(7 个字段) +- [x] 实现"风险度分析"Tab 字段展示(7 个字段) +- [x] 实现"测算结果"Tab 字段展示(2 个字段) + +### 5. 数据适配 +- [x] 修改 API 响应数据解析逻辑,支持 `LoanPricingWorkflowVO` 结构 +- [x] 添加模型输出字段的数据绑定 +- [x] 添加布尔值字段的格式化(true/false → 是/否) +- [x] 添加空值处理逻辑 + +### 6. 样式调整 +- [x] 保持与现有详情页面一致的卡片样式 +- [x] 保持 Tab 样式一致性 +- [x] 确保响应式布局在移动端正常显示 +- [x] 调整卡片间距 + +### 7. 测试验证 +- [ ] 测试个人客户数据展示 +- [ ] 测试企业客户数据展示 +- [ ] 测试无模型输出数据时的页面表现 +- [ ] 测试响应式布局 +- [ ] 测试各 Tab 切换交互 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/handler/MyMetaHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/handler/MyMetaHandler.java index 8aa0d50..657ea34 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/handler/MyMetaHandler.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/handler/MyMetaHandler.java @@ -18,16 +18,16 @@ public class MyMetaHandler implements MetaObjectHandler { @Override public void insertFill(MetaObject metaObject) { - this.setFieldValByName("createBy", SecurityUtils.getUsername(), metaObject); + this.setFieldValByName("createBy", SecurityUtils.getLoginUser().getUser().getNickName() + '-'+ SecurityUtils.getUsername(), metaObject); this.setFieldValByName("createTime", new Date(), metaObject); - this.setFieldValByName("updateBy", SecurityUtils.getUsername(), metaObject); + this.setFieldValByName("updateBy", SecurityUtils.getLoginUser().getUser().getNickName() + '-'+ SecurityUtils.getUsername(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } @Override public void updateFill(MetaObject metaObject) { - this.setFieldValByName("updateBy", SecurityUtils.getUsername(), metaObject); + this.setFieldValByName("updateBy", SecurityUtils.getLoginUser().getUser().getNickName() + '-'+ SecurityUtils.getUsername(), metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); } } diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue new file mode 100644 index 0000000..97c06f5 --- /dev/null +++ b/ruoyi-ui/src/views/loanPricing/workflow/components/ModelOutputDisplay.vue @@ -0,0 +1,306 @@ + + + + + diff --git a/ruoyi-ui/src/views/loanPricing/workflow/detail.vue b/ruoyi-ui/src/views/loanPricing/workflow/detail.vue index e7a45cf..d7ecfa5 100644 --- a/ruoyi-ui/src/views/loanPricing/workflow/detail.vue +++ b/ruoyi-ui/src/views/loanPricing/workflow/detail.vue @@ -6,97 +6,121 @@ 返回 - - - - + +
+ +
关键信息
- {{ detail.serialNum }} - {{ detail.custName }} - {{ detail.custType }} - {{ detail.applyAmt }} 元 - {{ detail.loanRate }} % - {{ detail.guarType }} + {{ workflowDetail.serialNum }} + {{ workflowDetail.custName }} + {{ workflowDetail.custType }} + {{ workflowDetail.applyAmt }} 元 + + {{ getBaseLoanRate() }} % + + + {{ getTotalBp() }} + + + {{ getCalculateRate() }} % +
- +
- - + +
+ +
+ 流程详情 +
- {{ detail.orgCode }} - {{ detail.runType }} - {{ detail.custIsn }} - {{ detail.idType }} + {{ workflowDetail.orgCode }} + {{ workflowDetail.runType }} + {{ workflowDetail.custIsn }} + {{ workflowDetail.idType }} - {{ detail.loanPurpose === 'consumer' ? '消费贷款' : detail.loanPurpose === 'business' ? '经营贷款' : detail.loanPurpose }} - {{ detail.bizProof === 'true' ? '是' : '否' }} - {{ detail.collType }} - {{ detail.collThirdParty === 'true' ? '是' : '否' }} + {{ formatLoanPurpose(workflowDetail.loanPurpose) }} + {{ formatBoolean(workflowDetail.bizProof) }} + {{ workflowDetail.collType }} + {{ formatBoolean(workflowDetail.collThirdParty) }} - {{ detail.midPerQuickPay === 'true' ? '是' : '否' }} - {{ detail.midPerEleDdc === 'true' ? '是' : '否' }} - {{ detail.midEntEleDdc === 'true' ? '是' : '否' }} - {{ detail.midEntWaterDdc === 'true' ? '是' : '否' }} + {{ formatBoolean(workflowDetail.midPerQuickPay) }} + {{ formatBoolean(workflowDetail.midPerEleDdc) }} + {{ formatBoolean(workflowDetail.midEntEleDdc) }} + {{ formatBoolean(workflowDetail.midEntWaterDdc) }} - {{ detail.isCleanEnt === 'true' ? '是' : '否' }} - {{ detail.hasSettleAcct === 'true' ? '是' : '否' }} - {{ detail.isManufacturing === 'true' ? '是' : '否' }} - {{ detail.isAgriGuar === 'true' ? '是' : '否' }} - {{ detail.isTaxA === 'true' ? '是' : '否' }} - {{ detail.isAgriLeading === 'true' ? '是' : '否' }} - {{ detail.isInclusiveFinance === 'true' ? '是' : '否' }} + {{ formatBoolean(workflowDetail.isCleanEnt) }} + {{ formatBoolean(workflowDetail.hasSettleAcct) }} + {{ formatBoolean(workflowDetail.isManufacturing) }} + {{ formatBoolean(workflowDetail.isAgriGuar) }} + {{ formatBoolean(workflowDetail.isTaxA) }} + {{ formatBoolean(workflowDetail.isAgriLeading) }} + {{ formatBoolean(workflowDetail.isInclusiveFinance) }} - {{ detail.createTime }} - {{ detail.createBy }} - {{ detail.updateTime }} - {{ detail.updateBy }} + {{ workflowDetail.createTime }} + {{ workflowDetail.createBy }} + {{ workflowDetail.updateTime }} + {{ workflowDetail.updateBy }}
- - + + + +
+