604 lines
19 KiB
Markdown
604 lines
19 KiB
Markdown
# 银行流水实体类与数据转换设计文档
|
||
|
||
**日期:** 2026-03-04
|
||
**模块:** ccdi-project
|
||
**作者:** Claude
|
||
|
||
---
|
||
|
||
## 一、概述
|
||
|
||
### 1.1 目标
|
||
|
||
创建银行流水实体类 `CcdiBankStatement`,用于持久化从流水分析平台获取的流水数据,并提供数据转换方法。
|
||
|
||
### 1.2 背景
|
||
|
||
- 流水分析平台提供 `GetBankStatementResponse.BankStatementItem` 接口响应对象
|
||
- 需要将响应数据转换为本地数据库实体进行持久化
|
||
- 流水数据需要关联到具体项目(`ccdi_project` 表)
|
||
|
||
### 1.3 技术选型
|
||
|
||
| 技术点 | 选择 | 理由 |
|
||
|--------|------|------|
|
||
| ORM框架 | MyBatis Plus 3.5.10 | 项目已集成,简化CRUD操作 |
|
||
| 对象映射 | Spring BeanUtils | 无需额外依赖,简单易用 |
|
||
| 数据库 | MySQL 8.2.0 | 项目标准数据库 |
|
||
| 实体类注解 | Lombok @Data | 简化代码,提高可读性 |
|
||
|
||
---
|
||
|
||
## 二、架构设计
|
||
|
||
### 2.1 模块位置
|
||
|
||
**主模块:** `ccdi-project` (项目管理模块)
|
||
|
||
**依赖关系:**
|
||
```
|
||
ccdi-project (流水实体类所在模块)
|
||
└── 依赖 ccdi-lsfx (访问流水分析响应类)
|
||
└── 依赖 ruoyi-common (通用工具)
|
||
```
|
||
|
||
### 2.2 包结构
|
||
|
||
```
|
||
ccdi-project/
|
||
├── src/main/java/com/ruoyi/ccdi/project/
|
||
│ ├── domain/
|
||
│ │ └── entity/
|
||
│ │ └── CcdiBankStatement.java (核心实体类)
|
||
│ ├── mapper/
|
||
│ │ └── CcdiBankStatementMapper.java (数据访问层)
|
||
│ └── service/
|
||
│ ├── IBankStatementService.java
|
||
│ └── impl/BankStatementServiceImpl.java
|
||
└── src/main/resources/
|
||
└── mapper/ccdi/project/
|
||
└── CcdiBankStatementMapper.xml
|
||
```
|
||
|
||
### 2.3 核心组件
|
||
|
||
**1. 实体类:** `CcdiBankStatement`
|
||
- 39个字段(38个原有字段 + 1个新增字段)
|
||
- 包含静态转换方法 `fromResponse()`
|
||
- 使用 MyBatis Plus 注解进行映射
|
||
|
||
**2. Mapper接口:** `CcdiBankStatementMapper`
|
||
- 继承 `BaseMapper<CcdiBankStatement>`
|
||
- 提供批量插入方法
|
||
|
||
**3. Service层:** 调用转换方法,设置业务字段
|
||
|
||
---
|
||
|
||
## 三、数据模型设计
|
||
|
||
### 3.1 数据库表结构修改
|
||
|
||
**表名:** `ccdi_bank_statement`
|
||
|
||
**新增字段:**
|
||
```sql
|
||
ALTER TABLE `ccdi_bank_statement`
|
||
ADD COLUMN `project_id` bigint(20) DEFAULT NULL COMMENT '关联项目ID' AFTER `bank_statement_id`,
|
||
ADD INDEX `idx_project_id` (`project_id`);
|
||
```
|
||
|
||
**说明:**
|
||
- `project_id` 关联 `ccdi_project` 表的主键
|
||
- `group_id` 字段保留,用于兼容流水分析平台的原始项目ID
|
||
|
||
### 3.2 字段映射关系
|
||
|
||
**总字段数:** 39个
|
||
|
||
**字段分类:**
|
||
|
||
| 分类 | 字段数 | 说明 |
|
||
|------|--------|------|
|
||
| 主键和关联 | 4 | bank_statement_id, project_id, le_id, group_id |
|
||
| 账号信息 | 5 | account_id, le_account_name, le_account_no, accounting_date_id, accounting_date |
|
||
| 交易信息 | 5 | trx_date, currency, amount_dr, amount_cr, amount_balance |
|
||
| 交易类型 | 5 | cash_type, trx_flag, trx_type, exception_type, internal_flag |
|
||
| 对手方信息 | 5 | customer_le_id, customer_account_name, customer_account_no, customer_bank, customer_reference |
|
||
| 摘要备注 | 4 | user_memo, bank_comments, bank_trx_number, bank |
|
||
| 批次上传 | 2 | batch_id, batch_sequence |
|
||
| 附加字段 | 7 | meta_json, no_balance, begin_balance, end_balance, override_bs_id, payment_method, cret_no |
|
||
| 审计字段 | 2 | create_date, created_by |
|
||
|
||
**特殊字段处理:**
|
||
|
||
| 数据库字段 | 响应字段 | 处理方式 |
|
||
|-----------|---------|---------|
|
||
| le_account_no | accountMaskNo | 手动映射 |
|
||
| customer_account_no | customerAccountMaskNo | 手动映射 |
|
||
| batch_sequence | uploadSequnceNumber | 手动映射 |
|
||
| meta_json | - | 强制设为 null |
|
||
| project_id | - | Service层设置 |
|
||
|
||
### 3.3 实体类字段类型
|
||
|
||
```java
|
||
// 数值类型
|
||
private Long bankStatementId; // 主键
|
||
private Long projectId; // 项目ID(新增)
|
||
private Long accountId; // 账号ID
|
||
private Integer leId; // 企业ID
|
||
private Integer groupId; // 项目ID(原有)
|
||
private Integer accountingDateId; // 账号日期ID
|
||
private Integer customerLeId; // 对手方企业ID
|
||
private Integer trxType; // 分类ID
|
||
private Integer internalFlag; // 内部交易标志
|
||
private Integer batchId; // 批次ID
|
||
private Integer batchSequence; // 批次序号
|
||
private Integer noBalance; // 是否包含余额
|
||
private Integer beginBalance; // 初始余额
|
||
private Integer endBalance; // 结束余额
|
||
private Long overrideBsId; // 覆盖标识
|
||
private Long createdBy; // 创建者
|
||
|
||
// 金额类型
|
||
private BigDecimal amountDr; // 付款金额
|
||
private BigDecimal amountCr; // 收款金额
|
||
private BigDecimal amountBalance; // 余额
|
||
|
||
// 字符串类型
|
||
private String leAccountName; // 企业账号名称
|
||
private String leAccountNo; // 企业银行账号
|
||
private String accountingDate; // 账号日期
|
||
private String trxDate; // 交易日期
|
||
private String currency; // 币种
|
||
private String cashType; // 交易类型
|
||
private String trxFlag; // 交易标志位
|
||
private String exceptionType; // 异常类型
|
||
private String customerAccountName;// 对手方企业名称
|
||
private String customerAccountNo; // 对手方账号
|
||
private String customerBank; // 对手方银行
|
||
private String customerReference; // 对手方备注
|
||
private String userMemo; // 用户交易摘要
|
||
private String bankComments; // 银行交易摘要
|
||
private String bankTrxNumber; // 银行交易号
|
||
private String bank; // 所属银行缩写
|
||
private String metaJson; // meta json
|
||
private String paymentMethod; // 交易方式
|
||
private String cretNo; // 身份证号
|
||
|
||
// 日期类型
|
||
private Date createDate; // 创建时间
|
||
```
|
||
|
||
---
|
||
|
||
## 四、转换方法设计
|
||
|
||
### 4.1 方法签名
|
||
|
||
```java
|
||
/**
|
||
* 从流水分析接口响应转换为实体
|
||
*
|
||
* @param item 流水分析接口返回的流水项
|
||
* @return 流水实体,如果 item 为 null 则返回 null
|
||
*/
|
||
public static CcdiBankStatement fromResponse(BankStatementItem item)
|
||
```
|
||
|
||
### 4.2 转换逻辑
|
||
|
||
```java
|
||
public static CcdiBankStatement fromResponse(BankStatementItem item) {
|
||
// 1. 空值检查
|
||
if (item == null) {
|
||
return null;
|
||
}
|
||
|
||
// 2. 创建实体对象
|
||
CcdiBankStatement entity = new CcdiBankStatement();
|
||
|
||
// 3. 使用 BeanUtils 复制同名字段
|
||
BeanUtils.copyProperties(item, entity);
|
||
|
||
// 4. 手动映射字段名不一致的情况
|
||
entity.setLeAccountNo(item.getAccountMaskNo());
|
||
entity.setCustomerAccountNo(item.getCustomerAccountMaskNo());
|
||
entity.setBatchSequence(item.getUploadSequnceNumber());
|
||
|
||
// 5. 特殊字段处理
|
||
entity.setMetaJson(null); // 根据文档要求强制设为 null
|
||
|
||
// 6. 注意:project_id 需要在 Service 层设置
|
||
|
||
return entity;
|
||
}
|
||
```
|
||
|
||
### 4.3 BeanUtils 行为说明
|
||
|
||
| 场景 | BeanUtils 行为 |
|
||
|------|---------------|
|
||
| 字段名相同且类型兼容 | 自动复制 |
|
||
| 字段名相同但类型不兼容 | 抛出异常 |
|
||
| 源对象中不存在目标字段 | 忽略,不抛异常 |
|
||
| 目标对象中不存在源字段 | 忽略,不抛异常 |
|
||
| 源字段为 null | 复制 null 值到目标字段 |
|
||
|
||
**注意事项:**
|
||
- BeanUtils 会忽略响应对象中额外的字段(如 `transAmount`, `attachments` 等)
|
||
- 需要手动处理字段名不一致的3个字段
|
||
- `meta_json` 字段强制设为 null
|
||
|
||
---
|
||
|
||
## 五、使用示例
|
||
|
||
### 5.1 Service层调用
|
||
|
||
```java
|
||
@Service
|
||
public class BankStatementServiceImpl implements IBankStatementService {
|
||
|
||
@Resource
|
||
private CcdiBankStatementMapper bankStatementMapper;
|
||
|
||
@Resource
|
||
private LsfxAnalysisClient lsfxClient;
|
||
|
||
/**
|
||
* 获取并保存流水数据
|
||
*
|
||
* @param projectId 项目ID
|
||
* @param request 查询请求
|
||
* @return 保存的记录数
|
||
*/
|
||
public int fetchAndSaveBankStatements(Long projectId, GetBankStatementRequest request) {
|
||
// 1. 调用流水分析接口
|
||
GetBankStatementResponse response = lsfxClient.getBankStatement(request);
|
||
|
||
// 2. 校验响应
|
||
if (response == null || !Boolean.TRUE.equals(response.getSuccessResponse())) {
|
||
throw new ServiceException("获取流水数据失败");
|
||
}
|
||
|
||
List<BankStatementItem> items = response.getData().getBankStatementList();
|
||
if (items == null || items.isEmpty()) {
|
||
return 0;
|
||
}
|
||
|
||
// 3. 转换并设置项目ID
|
||
List<CcdiBankStatement> entities = items.stream()
|
||
.map(item -> {
|
||
CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);
|
||
if (entity != null) {
|
||
entity.setProjectId(projectId); // 设置关联项目ID
|
||
}
|
||
return entity;
|
||
})
|
||
.filter(Objects::nonNull)
|
||
.collect(Collectors.toList());
|
||
|
||
// 4. 批量插入数据库
|
||
return bankStatementMapper.insertBatch(entities);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 单条数据转换
|
||
|
||
```java
|
||
// 从接口响应转换单条流水
|
||
BankStatementItem item = response.getData().getBankStatementList().get(0);
|
||
CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);
|
||
|
||
// 设置业务字段
|
||
entity.setProjectId(1001L);
|
||
|
||
// 保存到数据库
|
||
bankStatementMapper.insert(entity);
|
||
```
|
||
|
||
### 5.3 批量数据转换
|
||
|
||
```java
|
||
List<CcdiBankStatement> entities = response.getData().getBankStatementList()
|
||
.stream()
|
||
.map(CcdiBankStatement::fromResponse)
|
||
.peek(entity -> entity.setProjectId(projectId))
|
||
.collect(Collectors.toList());
|
||
|
||
bankStatementMapper.insertBatch(entities);
|
||
```
|
||
|
||
---
|
||
|
||
## 六、错误处理
|
||
|
||
### 6.1 空指针异常防护
|
||
|
||
**问题:** 接口响应可能为 null 或数据列表为空
|
||
|
||
**解决方案:**
|
||
```java
|
||
// 在 fromResponse 方法中
|
||
if (item == null) {
|
||
log.warn("流水项为空,无法转换");
|
||
return null;
|
||
}
|
||
|
||
// 在 Service 层
|
||
if (response == null || !Boolean.TRUE.equals(response.getSuccessResponse())) {
|
||
throw new ServiceException("获取流水数据失败");
|
||
}
|
||
|
||
List<BankStatementItem> items = response.getData().getBankStatementList();
|
||
if (items == null || items.isEmpty()) {
|
||
return 0; // 正常返回,不是异常情况
|
||
}
|
||
```
|
||
|
||
### 6.2 类型转换异常
|
||
|
||
**问题:** BeanUtils 在字段类型不匹配时会抛出异常
|
||
|
||
**解决方案:**
|
||
1. 确保 `BankStatementItem` 和 `CcdiBankStatement` 字段类型一致
|
||
2. BigDecimal、Integer、Long 类型已验证兼容
|
||
3. 添加异常捕获日志:
|
||
|
||
```java
|
||
public static CcdiBankStatement fromResponse(BankStatementItem item) {
|
||
if (item == null) {
|
||
return null;
|
||
}
|
||
|
||
try {
|
||
CcdiBankStatement entity = new CcdiBankStatement();
|
||
BeanUtils.copyProperties(item, entity);
|
||
entity.setLeAccountNo(item.getAccountMaskNo());
|
||
entity.setCustomerAccountNo(item.getCustomerAccountMaskNo());
|
||
entity.setBatchSequence(item.getUploadSequnceNumber());
|
||
entity.setMetaJson(null);
|
||
return entity;
|
||
} catch (Exception e) {
|
||
log.error("流水数据转换失败, bankStatementId={}", item.getBankStatementId(), e);
|
||
throw new RuntimeException("流水数据转换失败", e);
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.3 数据验证
|
||
|
||
**必填字段验证:**
|
||
```java
|
||
// 在 Service 层验证业务字段
|
||
if (entity.getProjectId() == null) {
|
||
throw new IllegalArgumentException("项目ID不能为空");
|
||
}
|
||
```
|
||
|
||
**数据库约束:**
|
||
- `bank_statement_id` 自增主键,无需验证
|
||
- 其他字段根据业务需求设置数据库约束(NOT NULL、DEFAULT等)
|
||
|
||
---
|
||
|
||
## 七、性能考虑
|
||
|
||
### 7.1 BeanUtils 性能
|
||
|
||
**特点:**
|
||
- 使用 Java 反射机制
|
||
- 单次转换性能影响可忽略(< 1ms)
|
||
- 批量转换时累计开销需要考虑
|
||
|
||
**性能数据(参考):**
|
||
| 操作 | 耗时 |
|
||
|------|------|
|
||
| 单次 BeanUtils.copyProperties() | < 1ms |
|
||
| 100次转换 | ~50ms |
|
||
| 1000次转换 | ~200ms |
|
||
|
||
**优化建议:**
|
||
- 对于单次或小批量转换(<100条),直接使用 BeanUtils
|
||
- 对于大批量转换(>1000条),可考虑:
|
||
1. 使用 MapStruct(编译期生成代码,无反射)
|
||
2. 异步批量处理
|
||
3. 分批插入数据库
|
||
|
||
### 7.2 数据库批量插入
|
||
|
||
**推荐方式:**
|
||
```java
|
||
// MyBatis Plus 批量插入
|
||
@Service
|
||
public class BankStatementServiceImpl {
|
||
|
||
@Resource
|
||
private CcdiBankStatementMapper bankStatementMapper;
|
||
|
||
public int insertBatch(List<CcdiBankStatement> entities) {
|
||
if (entities == null || entities.isEmpty()) {
|
||
return 0;
|
||
}
|
||
|
||
// 分批插入,每批 1000 条
|
||
int batchSize = 1000;
|
||
int totalInserted = 0;
|
||
|
||
for (int i = 0; i < entities.size(); i += batchSize) {
|
||
int end = Math.min(i + batchSize, entities.size());
|
||
List<CcdiBankStatement> batch = entities.subList(i, end);
|
||
bankStatementMapper.insertBatch(batch);
|
||
totalInserted += batch.size();
|
||
}
|
||
|
||
return totalInserted;
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.3 内存考虑
|
||
|
||
**对象占用空间估算:**
|
||
- 单个 `CcdiBankStatement` 对象约 1KB(包含所有字段)
|
||
- 1000条流水数据约占用 1MB 内存
|
||
- 10000条流水数据约占用 10MB 内存
|
||
|
||
**建议:**
|
||
- 对于超大数据量(>10000条),使用流式处理:
|
||
```java
|
||
response.getData().getBankStatementList()
|
||
.stream()
|
||
.map(CcdiBankStatement::fromResponse)
|
||
.forEach(entity -> {
|
||
// 立即处理,不保留在内存中
|
||
bankStatementMapper.insert(entity);
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 八、测试策略
|
||
|
||
### 8.1 单元测试
|
||
|
||
**测试类:** `CcdiBankStatementTest`
|
||
|
||
**测试用例:**
|
||
|
||
| 测试场景 | 测试方法 | 验证点 |
|
||
|---------|---------|--------|
|
||
| 正常转换 | `testFromResponse_Success` | 所有字段正确映射 |
|
||
| 空值处理 | `testFromResponse_Null` | 返回 null |
|
||
| 字段名映射 | `testFromResponse_FieldMapping` | 3个特殊字段正确映射 |
|
||
| meta_json | `testFromResponse_MetaJson` | 强制为 null |
|
||
|
||
**测试代码示例:**
|
||
```java
|
||
@Test
|
||
public void testFromResponse_Success() {
|
||
// 准备测试数据
|
||
BankStatementItem item = new BankStatementItem();
|
||
item.setBankStatementId(123456L);
|
||
item.setLeId(100);
|
||
item.setAccountMaskNo("6222****1234");
|
||
item.setDrAmount(new BigDecimal("1000.00"));
|
||
|
||
// 执行转换
|
||
CcdiBankStatement entity = CcdiBankStatement.fromResponse(item);
|
||
|
||
// 验证结果
|
||
assertNotNull(entity);
|
||
assertEquals(123456L, entity.getBankStatementId());
|
||
assertEquals(100, entity.getLeId());
|
||
assertEquals("6222****1234", entity.getLeAccountNo());
|
||
assertEquals(new BigDecimal("1000.00"), entity.getAmountDr());
|
||
assertNull(entity.getMetaJson());
|
||
}
|
||
```
|
||
|
||
### 8.2 集成测试
|
||
|
||
**测试场景:**
|
||
1. 完整流程:调用接口 → 转换数据 → 保存数据库
|
||
2. 数据库查询:验证字段值正确性
|
||
3. 关联查询:验证 `project_id` 关联有效
|
||
|
||
### 8.3 性能测试
|
||
|
||
**测试指标:**
|
||
- 单次转换耗时
|
||
- 1000次批量转换耗时
|
||
- 数据库批量插入耗时
|
||
|
||
---
|
||
|
||
## 九、部署检查清单
|
||
|
||
### 9.1 数据库修改
|
||
|
||
- [ ] 执行 ALTER TABLE 添加 `project_id` 字段
|
||
- [ ] 创建索引 `idx_project_id`
|
||
- [ ] 验证字段类型和长度
|
||
|
||
### 9.2 代码检查
|
||
|
||
- [ ] `ccdi-project` 模块已依赖 `ccdi-lsfx`
|
||
- [ ] 实体类字段类型与数据库一致
|
||
- [ ] 转换方法处理所有特殊字段
|
||
- [ ] Service 层正确设置 `project_id`
|
||
|
||
### 9.3 测试验证
|
||
|
||
- [ ] 单元测试通过
|
||
- [ ] 集成测试通过
|
||
- [ ] 性能测试达标
|
||
|
||
### 9.4 文档更新
|
||
|
||
- [ ] 更新 CLAUDE.md 文档
|
||
- [ ] 更新数据库设计文档
|
||
- [ ] 添加 API 文档说明
|
||
|
||
---
|
||
|
||
## 十、附录
|
||
|
||
### 10.1 完整字段映射表
|
||
|
||
| 序号 | 数据库字段 | Java字段 | Java类型 | 响应字段 | 说明 |
|
||
|------|-----------|---------|---------|---------|------|
|
||
| 1 | bank_statement_id | bankStatementId | Long | bankStatementId | 主键自增 |
|
||
| 2 | project_id | projectId | Long | - | **新增字段** |
|
||
| 3 | LE_ID | leId | Integer | leId | 企业ID |
|
||
| 4 | ACCOUNT_ID | accountId | Long | accountId | 账号ID |
|
||
| 5 | LE_ACCOUNT_NAME | leAccountName | String | leName | 企业账号名称 |
|
||
| 6 | LE_ACCOUNT_NO | leAccountNo | String | accountMaskNo | **手动映射** |
|
||
| 7 | ACCOUNTING_DATE_ID | accountingDateId | Integer | accountingDateId | 账号日期ID |
|
||
| 8 | ACCOUNTING_DATE | accountingDate | String | accountingDate | 账号日期 |
|
||
| 9 | TRX_DATE | trxDate | String | trxDate | 交易日期 |
|
||
| 10 | CURRENCY | currency | String | currency | 币种 |
|
||
| 11 | AMOUNT_DR | amountDr | BigDecimal | drAmount | 付款金额 |
|
||
| 12 | AMOUNT_CR | amountCr | BigDecimal | crAmount | 收款金额 |
|
||
| 13 | AMOUNT_BALANCE | amountBalance | BigDecimal | balanceAmount | 余额 |
|
||
| 14 | CASH_TYPE | cashType | String | cashType | 交易类型 |
|
||
| 15 | CUSTOMER_LE_ID | customerLeId | Integer | customerId | 对手方企业ID |
|
||
| 16 | CUSTOMER_ACCOUNT_NAME | customerAccountName | String | customerName | 对手方企业名称 |
|
||
| 17 | CUSTOMER_ACCOUNT_NO | customerAccountNo | String | customerAccountMaskNo | **手动映射** |
|
||
| 18 | customer_bank | customerBank | String | customerBank | 对手方银行 |
|
||
| 19 | customer_reference | customerReference | String | customerReference | 对手方备注 |
|
||
| 20 | USER_MEMO | userMemo | String | userMemo | 用户交易摘要 |
|
||
| 21 | BANK_COMMENTS | bankComments | String | bankComments | 银行交易摘要 |
|
||
| 22 | BANK_TRX_NUMBER | bankTrxNumber | String | bankTrxNumber | 银行交易号 |
|
||
| 23 | BANK | bank | String | bank | 所属银行缩写 |
|
||
| 24 | TRX_FLAG | trxFlag | String | transFlag | 交易标志位 |
|
||
| 25 | TRX_TYPE | trxType | Integer | transTypeId | 分类ID |
|
||
| 26 | EXCEPTION_TYPE | exceptionType | String | exceptionType | 异常类型 |
|
||
| 27 | internal_flag | internalFlag | Integer | internalFlag | 是否为内部交易 |
|
||
| 28 | batch_id | batchId | Integer | batchId | 上传logId |
|
||
| 29 | batch_sequence | batchSequence | Integer | uploadSequnceNumber | **手动映射** |
|
||
| 30 | CREATE_DATE | createDate | Date | createDate | 创建时间 |
|
||
| 31 | created_by | createdBy | Long | createdBy | 创建者 |
|
||
| 32 | meta_json | metaJson | String | - | **强制null** |
|
||
| 33 | no_balance | noBalance | Integer | isNoBalance | 是否包含余额 |
|
||
| 34 | begin_balance | beginBalance | Integer | isBeginBalance | 初始余额 |
|
||
| 35 | end_balance | endBalance | Integer | isEndBalance | 结束余额 |
|
||
| 36 | override_bs_id | overrideBsId | Long | overrideBsId | 覆盖标识 |
|
||
| 37 | payment_method | paymentMethod | String | paymentMethod | 交易方式 |
|
||
| 38 | cret_no | cretNo | String | cretNo | 身份证号 |
|
||
| 39 | group_id | groupId | Integer | groupId | 项目id |
|
||
|
||
### 10.2 参考文档
|
||
|
||
- [ccdi_bank_statement.md](../../assets/对接流水分析/ccdi_bank_statement.md)
|
||
- [MyBatis Plus 官方文档](https://baomidou.com/)
|
||
- [Spring BeanUtils 文档](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/BeanUtils.html)
|
||
|
||
---
|
||
|
||
**文档版本:** 1.0
|
||
**最后更新:** 2026-03-04
|