# 设计文档

## 概述

银行选择逻辑优化设计旨在简化贷款申请流程，消除用户在申请和提交阶段的重复银行选择操作。通过重构前端组件和后端数据模型，实现一次选择、多次使用的用户体验。

## 架构

### 当前架构问题
- 贷款申请创建时选择银行，但不保存提交说明
- 详情页面需要重新选择银行和填写说明
- 银行选择状态不明确，用户体验混乱

### 优化后架构
- 贷款申请创建时同时保存银行选择和提交说明
- 详情页面直接使用已保存的银行信息
- 提供修改银行选择的独立功能
- 实现一键提交机制

## 组件和接口

### 前端组件修改

#### LoanManagement.vue 组件优化

**数据模型扩展:**
```javascript
// 贷款申请表单增加提交说明字段
const loanApplicationForm = ref({
  loanAmount: null,
  loanTermMonths: 12,
  loanPurpose: '服务周期人工成本融资',
  submitComments: '', // 新增：提交说明
  selectedBankId: null, // 新增：选择的银行ID
  bankInstitutionName: '', // 新增：银行名称
  interestRate: null, // 新增：利率
  monthlyPayment: null // 新增：月还款额
});

// 详情页面表单简化
const detailSubmitForm = ref({
  quickSubmit: false // 简化为快速提交标志
});
```

**界面布局调整:**
1. 申请贷款对话框增加提交说明输入框
2. 银行选择表格移至提交说明之前
3. 详情页面简化银行选择界面
4. 增加一键提交按钮

#### 新增组件功能

**银行选择状态显示:**
```javascript
// 银行选择状态计算
const getBankSelectionStatus = (loan) => {
  if (!loan.bankInstitutionId) return 'NOT_SELECTED';
  if (loan.loanStatus === 'PENDING') return 'SELECTED_PENDING';
  if (loan.loanStatus === 'SUBMITTED') return 'SUBMITTED';
  return 'UNKNOWN';
};

// 状态文本映射
const bankSelectionStatusText = {
  'NOT_SELECTED': '未选择银行',
  'SELECTED_PENDING': '已选择银行，待提交',
  'SUBMITTED': '已提交至银行'
};
```

### 后端接口修改

#### ServicePeriodLoan 数据模型扩展

**新增字段:**
```java
public class ServicePeriodLoan {
    // 现有字段...
    
    /** 提交说明 */
    private String submitComments;
    
    /** 银行选择时间 */
    private Date bankSelectedTime;
    
    /** 银行选择变更历史 */
    private String bankSelectionHistory;
    
    /** 是否可一键提交 */
    private Boolean quickSubmitEnabled;
}
```

#### API 接口优化

**贷款申请接口增强:**
```java
@PostMapping("/apply")
public AjaxResult applyLoanWithBankSelection(@RequestBody LoanApplicationRequest request) {
    // 验证银行选择信息
    if (request.getBankInstitutionId() == null) {
        return AjaxResult.error("请选择银行");
    }
    
    // 创建贷款申请并保存银行信息
    ServicePeriodLoan loan = new ServicePeriodLoan();
    loan.setBankInstitutionId(request.getBankInstitutionId());
    loan.setSubmitComments(request.getSubmitComments());
    loan.setBankSelectedTime(new Date());
    loan.setQuickSubmitEnabled(true);
    
    return servicePeriodLoanService.createLoanWithBankSelection(loan);
}
```

**一键提交接口:**
```java
@PostMapping("/quick-submit/{loanId}")
public AjaxResult quickSubmitToBank(@PathVariable Long loanId) {
    ServicePeriodLoan loan = servicePeriodLoanService.selectById(loanId);
    
    // 验证是否可以一键提交
    if (!loan.getQuickSubmitEnabled() || loan.getBankInstitutionId() == null) {
        return AjaxResult.error("贷款申请信息不完整，无法提交");
    }
    
    // 直接提交到银行
    loan.setLoanStatus("SUBMITTED");
    loan.setApprovalStatus("SUBMITTED");
    loan.setSubmitTime(new Date());
    
    return servicePeriodLoanService.updateLoan(loan);
}
```

## 数据模型

### 数据库表结构修改

**service_period_loan 表新增字段:**
```sql
ALTER TABLE service_period_loan 
ADD COLUMN submit_comments TEXT COMMENT '提交说明',
ADD COLUMN bank_selected_time DATETIME COMMENT '银行选择时间',
ADD COLUMN bank_selection_history TEXT COMMENT '银行选择变更历史',
ADD COLUMN quick_submit_enabled TINYINT(1) DEFAULT 1 COMMENT '是否可一键提交';
```

### 数据流转优化

**申请阶段数据流:**
1. 用户选择银行 → 保存银行ID和基本信息
2. 用户填写说明 → 保存提交说明
3. 用户确认申请 → 创建完整的贷款申请记录

**提交阶段数据流:**
1. 系统读取已保存的银行信息
2. 用户确认提交 → 直接使用已保存信息
3. 系统更新贷款状态为已提交

## 正确性属性

*属性是一个特征或行为，应该在系统的所有有效执行中保持为真。属性作为人类可读规范和机器可验证正确性保证之间的桥梁。*

### 属性 1: 银行选择一致性
*对于任何*贷款申请，如果在创建时选择了银行，那么在提交时应该使用相同的银行信息，除非用户明确修改
**验证: 需求 1.2, 1.5**

### 属性 2: 提交说明保持性
*对于任何*贷款申请，如果在创建时填写了提交说明，那么在提交时应该使用相同的说明内容，除非用户明确修改
**验证: 需求 1.2, 1.5**

### 属性 3: 状态显示准确性
*对于任何*贷款申请，系统显示的银行选择状态应该与实际的银行选择情况完全一致
**验证: 需求 3.1, 3.2, 3.3, 3.4, 3.5**

### 属性 4: 一键提交条件
*对于任何*贷款申请，当且仅当包含完整信息（金额、期限、用途、银行、说明）时，系统应该允许一键提交
**验证: 需求 4.1, 4.2**

### 属性 5: 修改操作幂等性
*对于任何*银行选择修改操作，如果修改前后的银行信息相同，那么系统状态应该保持不变
**验证: 需求 2.4, 2.5**

### 属性 6: 变更历史完整性
*对于任何*银行选择变更，系统应该记录变更前的状态、变更后的状态和变更时间
**验证: 需求 5.1, 5.2, 5.3**

## 错误处理

### 银行选择错误处理
- **银行信息缺失**: 显示友好提示，引导用户选择银行
- **银行服务不可用**: 提供备选银行选项或稍后重试
- **利率计算错误**: 使用默认利率并标记需要人工确认

### 数据一致性错误处理
- **银行信息不匹配**: 自动同步最新银行信息
- **状态不一致**: 根据实际数据重新计算状态
- **历史记录丢失**: 记录错误日志但不影响主流程

### 用户操作错误处理
- **重复提交**: 检测并阻止重复提交操作
- **无效修改**: 验证修改权限和数据有效性
- **网络中断**: 提供本地缓存和重试机制