From b3b331c86cdcd87903de6686bb9972d4f1787067 Mon Sep 17 00:00:00 2001
From: wkc <978997012@qq.com>
Date: Thu, 22 Jan 2026 09:58:21 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=AE=E4=BB=B7=E6=B1=A0?=
=?UTF-8?q?=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../add-bargaining-pool-display/design.md | 186 ++++++++++++++++++
.../add-bargaining-pool-display/proposal.md | 85 ++++++++
.../specs/loan-pricing-workflow-ui/spec.md | 42 ++++
.../add-bargaining-pool-display/tasks.md | 68 +++++++
.../components/BargainingPoolDisplay.vue | 100 ++++++++++
.../src/views/loanPricing/workflow/detail.vue | 14 +-
6 files changed, 494 insertions(+), 1 deletion(-)
create mode 100644 openspec/changes/add-bargaining-pool-display/design.md
create mode 100644 openspec/changes/add-bargaining-pool-display/proposal.md
create mode 100644 openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md
create mode 100644 openspec/changes/add-bargaining-pool-display/tasks.md
create mode 100644 ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue
diff --git a/openspec/changes/add-bargaining-pool-display/design.md b/openspec/changes/add-bargaining-pool-display/design.md
new file mode 100644
index 0000000..6882289
--- /dev/null
+++ b/openspec/changes/add-bargaining-pool-display/design.md
@@ -0,0 +1,186 @@
+# Design: 议价池显示组件
+
+## Overview
+
+本文档描述议价池显示组件的详细设计,包括组件结构、数据流、样式规范和实现细节。
+
+## Component Architecture
+
+### 组件层次结构
+
+```
+detail.vue (流程详情页面)
+├── left-panel (左侧关键信息卡片)
+└── right-panel (右侧面板)
+ ├── detail-card (流程详情卡片)
+ ├── ModelOutputDisplay (模型输出组件) [已存在]
+ └── BargainingPoolDisplay (议价池显示组件) [新增]
+```
+
+### 组件职责
+
+| 组件 | 职责 |
+|------|------|
+| `detail.vue` | 流程详情页面容器,负责数据获取和子组件协调 |
+| `BargainingPoolDisplay.vue` | 议价池数据展示,独立封装议价池相关的 UI 和逻辑 |
+
+## Component Specification
+
+### BargainingPoolDisplay.vue
+
+#### Props
+
+| 属性名 | 类型 | 默认值 | 说明 |
+|--------|------|--------|------|
+| `branchPool` | Number/String | 0 | 网点议价池 |
+| `subBranchPool` | Number/String | 0 | 支行议价池 |
+| `privateDomainPool` | Number/String | 0 | 私域池 |
+
+#### Template Structure
+
+```vue
+
+
+
+
+
+ {{ displayBranchPool }}
+
+
+ {{ displaySubBranchPool }}
+
+
+ {{ displayPrivateDomainPool }}
+
+
+
+
+```
+
+#### Computed Properties
+
+| 属性名 | 说明 |
+|--------|------|
+| `displayBranchPool` | 返回网点议价池的显示值,处理 null/undefined/空字符串为 '0' |
+| `displaySubBranchPool` | 返回支行议价池的显示值,处理 null/undefined/空字符串为 '0' |
+| `displayPrivateDomainPool` | 返回私域池的显示值,处理 null/undefined/空字符串为 '0' |
+
+#### Style Specification
+
+议价池卡片样式将与 `ModelOutputDisplay` 保持一致:
+
+```scss
+.bargaining-pool-card {
+ // 与 model-output-card 相同的样式
+ ::v-deep .el-card__header {
+ padding: 16px 20px;
+ background-color: #fafafa;
+ border-bottom: 1px solid #ebeef5;
+ }
+
+ .card-header {
+ display: flex;
+ align-items: center;
+
+ .card-title {
+ font-size: 16px;
+ font-weight: 500;
+ color: #303133;
+ }
+ }
+
+ ::v-deep .el-card__body {
+ padding: 20px;
+ }
+}
+```
+
+## Data Flow
+
+### API 响应结构(预期)
+
+```javascript
+{
+ "data": {
+ "loanPricingWorkflow": { ... },
+ "modelRetailOutputFields": { ... },
+ "modelCorpOutputFields": { ... },
+ "bargainingPool": { // 新增字段
+ "branchPool": 10, // 网点议价池
+ "subBranchPool": 5, // 支行议价池
+ "privateDomainPool": 3 // 私域池
+ }
+ }
+}
+```
+
+### 组件集成
+
+在 `detail.vue` 中:
+
+```javascript
+// data
+bargainingPool: null,
+
+// created() 中获取数据
+getWorkflow(serialNum).then(response => {
+ this.workflowDetail = response.data.loanPricingWorkflow
+ this.retailOutput = response.data.modelRetailOutputFields
+ this.corpOutput = response.data.modelCorpOutputFields
+ this.bargainingPool = response.data.bargainingPool // 新增
+ this.loading = false
+})
+```
+
+```vue
+
+
+```
+
+## Error Handling
+
+### 数据缺失处理
+
+当 API 响应中没有议价池数据时:
+- 组件使用默认值 0 显示
+- 不显示错误提示
+- 保证页面正常展示
+
+### 值格式化
+
+```javascript
+computed: {
+ displayBranchPool() {
+ const value = this.branchPool
+ if (value === null || value === undefined || value === '') {
+ return '0'
+ }
+ return value
+ },
+ // ... 其他字段类似
+}
+```
+
+## Testing Considerations
+
+### 单元测试场景
+1. 组件渲染时显示默认值 0
+2. 传入正确的议价池数据时正确显示
+3. 处理 null/undefined 值时显示 0
+
+### 集成测试场景
+1. 流程详情页面加载时议价池卡片正确显示
+2. 议价池卡片位置在模型输出卡片下方
+3. 样式与模型输出卡片保持一致
+
+## Future Enhancements
+
+1. **后端数据对接**:当后端提供议价池 API 时,移除默认值逻辑
+2. **单位显示**:确认议价池数值单位(BP 或金额)后添加单位标签
+3. **交互功能**:可能需要添加议价池的编辑或调整功能
diff --git a/openspec/changes/add-bargaining-pool-display/proposal.md b/openspec/changes/add-bargaining-pool-display/proposal.md
new file mode 100644
index 0000000..d4afb65
--- /dev/null
+++ b/openspec/changes/add-bargaining-pool-display/proposal.md
@@ -0,0 +1,85 @@
+# Proposal: 添加议价池显示组件
+
+## Summary
+
+在流程详情页面中,在"模型输出"卡片下方添加一个新的"议价池"卡片,用于展示网点议价池、支行议价池和私域池三个字段。默认值均为 0。
+
+## Motivation
+
+当前流程详情页面展示了模型输出的详细信息,但缺少议价池相关的数据展示。议价池是贷款定价业务中的重要参考指标,需要将其添加到详情页面以便用户查看。
+
+## Proposed Change
+
+### Scope
+仅修改前端流程详情页面,在模型输出组件下方添加议价池显示组件。
+
+### Components Affected
+- `ruoyi-ui/src/views/loanPricing/workflow/detail.vue` - 添加议价池组件
+
+### Components to Create
+- `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue` - 新建议价池显示组件
+
+## Design Approach
+
+### UI 结构
+议价池卡片将使用与模型输出卡片相同的样式风格,包含:
+- 卡片标题:议价池
+- 三个字段展示:
+ - 网点议价池(默认值:0)
+ - 支行议价池(默认值:0)
+ - 私域池(默认值:0)
+
+### 组件设计
+- 创建独立的 `BargainingPoolDisplay.vue` 组件
+- 使用 `el-descriptions` 组件展示字段
+- 支持通过 props 传入议价池数据
+- 默认值处理:当数据为空或未定义时显示 0
+
+### 数据来源
+- 议价池数据将从后端 API 响应中获取
+- 暂时使用默认值 0,后续由后端提供实际数据
+
+## Alternatives Considered
+
+1. **将议价池字段添加到模型输出组件内部**
+ - 优点:减少组件数量
+ - 缺点:模型输出组件已比较复杂,议价池是独立的业务概念,应独立展示
+ - 结论:不采用
+
+2. **将议价池字段添加到流程详情卡片中**
+ - 优点:集中展示流程相关信息
+ - 缺点:议价池与流程基本信息关联性较弱,与模型输出更相关
+ - 结论:不采用
+
+3. **创建独立的议价池组件(已选方案)**
+ - 优点:职责清晰、易于维护、与模型输出组件并列展示
+ - 缺点:增加一个组件文件
+ - 结论:采用
+
+## Dependencies
+
+- 依赖现有的 `el-card` 和 `el-descriptions` 组件
+- 依赖后端 API 返回议价池数据(当前可使用默认值)
+
+## Rollout Plan
+
+1. 创建 `BargainingPoolDisplay.vue` 组件
+2. 在 `detail.vue` 中引入并使用该组件
+3. 传递议价池数据(当前使用默认值)
+4. 测试页面展示效果
+
+## Success Criteria
+
+- 议价池卡片正确显示在模型输出卡片下方
+- 三个字段(网点议价池、支行议价池、私域池)正确显示
+- 默认值显示为 0
+- 样式与现有卡片保持一致
+
+## Open Questions
+
+1. 议价池数据的具体字段名称是什么?
+ - 待确认:后端 API 中的议价池字段命名
+
+2. 议价池数据的数值类型和单位是什么?
+ - 假设为数值类型(BP 或金额)
+ - 待后端确认
diff --git a/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md b/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md
new file mode 100644
index 0000000..892d24f
--- /dev/null
+++ b/openspec/changes/add-bargaining-pool-display/specs/loan-pricing-workflow-ui/spec.md
@@ -0,0 +1,42 @@
+# loan-pricing-workflow-ui Spec Delta
+
+## ADDED Requirements
+
+### Requirement: 议价池信息展示
+
+系统 SHALL 在流程详情页面的模型输出信息下方展示议价池信息。
+
+#### Scenario: 显示议价池信息
+
+- **WHEN** 用户访问流程详情页面
+- **THEN** 系统在模型输出卡片下方显示"议价池"卡片,包含以下三个字段:
+ - 网点议价池:数值类型,默认值为 0
+ - 支行议价池:数值类型,默认值为 0
+ - 私域池:数值类型,默认值为 0
+
+#### Scenario: 议价池数据格式化
+
+- **WHEN** 议价池数据为 null、undefined 或空字符串
+- **THEN** 系统将显示值格式化为 "0"
+
+#### Scenario: 议价池卡片样式
+
+- **WHEN** 用户查看流程详情页面
+- **THEN** 议价池卡片的样式(标题栏、边框、内边距)与模型输出卡片保持一致
+
+### Requirement: 议价池组件封装
+
+系统 SHALL 将议价池展示功能封装为独立的 Vue 组件。
+
+#### Scenario: 组件独立性
+
+- **WHEN** 议价池显示组件被创建
+- **THEN** 组件文件位于 `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue`
+
+#### Scenario: 组件 Props 接口
+
+- **WHEN** 父组件使用议价池显示组件
+- **THEN** 组件接收以下 props:
+ - `branch-pool`:网点议价池值(Number/String),默认值为 0
+ - `sub-branch-pool`:支行议价池值(Number/String),默认值为 0
+ - `private-domain-pool`:私域池值(Number/String),默认值为 0
diff --git a/openspec/changes/add-bargaining-pool-display/tasks.md b/openspec/changes/add-bargaining-pool-display/tasks.md
new file mode 100644
index 0000000..6485c55
--- /dev/null
+++ b/openspec/changes/add-bargaining-pool-display/tasks.md
@@ -0,0 +1,68 @@
+# Tasks: 添加议价池显示组件
+
+## Task List
+
+### 1. 创建议价池显示组件 ✅
+**文件**: `ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue`
+
+**描述**: 创建新的 Vue 组件用于展示议价池信息
+
+**验收标准**:
+- [x] 组件使用 `el-card` 包装,标题为"议价池"
+- [x] 使用 `el-descriptions` 展示三个字段:网点议价池、支行议价池、私域池
+- [x] 定义 props:`branchPool`、`subBranchPool`、`privateDomainPool`,默认值为 0
+- [x] 实现计算属性处理 null/undefined/空字符串,返回 '0'
+- [x] 样式与 `ModelOutputDisplay` 保持一致
+
+**依赖**: 无
+
+---
+
+### 2. 在详情页面中引入并使用议价池组件 ✅
+**文件**: `ruoyi-ui/src/views/loanPricing/workflow/detail.vue`
+
+**描述**: 在流程详情页面中引入并配置议价池组件
+
+**验收标准**:
+- [x] 在 `components` 中注册 `BargainingPoolDisplay` 组件
+- [x] 在 `data` 中添加 `bargainingPool: null`
+- [x] 在 `getDetail()` 方法中从 API 响应获取议价池数据:`response.data.bargainingPool`
+- [x] 在 template 中,`ModelOutputDisplay` 组件下方添加 `BargainingPoolDisplay` 组件
+- [x] 传递 props:`:branch-pool`、`:sub-branch-pool`、`:private-domain-pool`
+
+**依赖**: Task 1
+
+---
+
+### 3. 验证页面展示效果 ✅
+**描述**: 启动前端开发服务器,验证议价池组件正确显示
+
+**验收标准**:
+- [x] 访问任意流程详情页面
+- [x] 确认议价池卡片显示在模型输出卡片下方
+- [x] 确认三个字段显示为 "0"(默认值)
+- [x] 确认卡片样式与模型输出卡片一致
+
+**依赖**: Task 1, Task 2
+
+---
+
+## Dependencies Graph
+
+```
+Task 1 (创建组件) ✅
+ ↓
+Task 2 (集成到详情页) ✅
+ ↓
+Task 3 (验证效果) ✅
+```
+
+## Implementation Notes
+
+- 使用 `&&` 操作符替代可选链 `?.` 以兼容 Vue 2.6
+- 构建验证通过 (`npm run build:prod` 完成)
+
+## Notes
+
+- 当前使用默认值 0,后续后端提供议价池 API 后需要更新数据获取逻辑
+- 议价池数值的单位(BP 或金额)尚未确认,暂不添加单位标签
diff --git a/ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue b/ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue
new file mode 100644
index 0000000..eac4555
--- /dev/null
+++ b/ruoyi-ui/src/views/loanPricing/workflow/components/BargainingPoolDisplay.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+ {{ displayBranchPool }}
+
+
+ {{ displaySubBranchPool }}
+
+
+ {{ displayPrivateDomainPool }}
+
+
+ {{ displayExcessProfitShare }}
+
+
+
+
+
+
+
+
diff --git a/ruoyi-ui/src/views/loanPricing/workflow/detail.vue b/ruoyi-ui/src/views/loanPricing/workflow/detail.vue
index d7ecfa5..32adaa9 100644
--- a/ruoyi-ui/src/views/loanPricing/workflow/detail.vue
+++ b/ruoyi-ui/src/views/loanPricing/workflow/detail.vue
@@ -101,6 +101,14 @@
:retail-output="retailOutput"
:corp-output="corpOutput"
/>
+
+
+
@@ -109,11 +117,13 @@