合并账户库为单表

This commit is contained in:
wkc
2026-04-17 10:18:13 +08:00
parent cc1a4538af
commit 4c6ca52e7e
24 changed files with 1285 additions and 377 deletions

View File

@@ -9,6 +9,7 @@ import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
@@ -56,6 +57,42 @@ public class CcdiAccountInfo implements Serializable {
/** 币种 */
private String currency;
/** 是否实控账户0-否 1-是 */
@TableField("is_self_account")
private Integer isActualControl;
/** 月均交易笔数 */
@TableField("monthly_avg_trans_count")
private Integer avgMonthTxnCount;
/** 月均交易金额 */
@TableField("monthly_avg_trans_amount")
private BigDecimal avgMonthTxnAmount;
/** 交易频率等级 */
@TableField("trans_freq_type")
private String txnFrequencyLevel;
/** 借方单笔最高额 */
@TableField("dr_max_single_amount")
private BigDecimal debitSingleMaxAmount;
/** 贷方单笔最高额 */
@TableField("cr_max_single_amount")
private BigDecimal creditSingleMaxAmount;
/** 借方日累计最高额 */
@TableField("dr_max_daily_amount")
private BigDecimal debitDailyMaxAmount;
/** 贷方日累计最高额 */
@TableField("cr_max_daily_amount")
private BigDecimal creditDailyMaxAmount;
/** 风险等级 */
@TableField("trans_risk_level")
private String txnRiskLevel;
/** 状态1-正常 2-已销户 */
private Integer status;

View File

@@ -1,86 +0,0 @@
package com.ruoyi.info.collection.domain;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 账户分析结果对象 ccdi_account_result
*
* @author ruoyi
* @date 2026-04-13
*/
@Data
@TableName("ccdi_account_result")
public class CcdiAccountResult implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/** 主键ID */
@TableId(value = "result_id", type = IdType.AUTO)
private Long resultId;
/** 账户号码 */
private String accountNo;
/** 是否实控账户0-否 1-是 */
@TableField("is_self_account")
private Integer isActualControl;
/** 月均交易笔数 */
@TableField("monthly_avg_trans_count")
private Integer avgMonthTxnCount;
/** 月均交易金额 */
@TableField("monthly_avg_trans_amount")
private BigDecimal avgMonthTxnAmount;
/** 交易频率等级 */
@TableField("trans_freq_type")
private String txnFrequencyLevel;
/** 借方单笔最高额 */
@TableField("dr_max_single_amount")
private BigDecimal debitSingleMaxAmount;
/** 贷方单笔最高额 */
@TableField("cr_max_single_amount")
private BigDecimal creditSingleMaxAmount;
/** 借方日累计最高额 */
@TableField("dr_max_daily_amount")
private BigDecimal debitDailyMaxAmount;
/** 贷方日累计最高额 */
@TableField("cr_max_daily_amount")
private BigDecimal creditDailyMaxAmount;
/** 风险等级 */
@TableField("trans_risk_level")
private String txnRiskLevel;
/** 创建者 */
@TableField(fill = FieldFill.INSERT)
private String createBy;
/** 创建时间 */
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/** 更新者 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
/** 更新时间 */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
}

View File

@@ -1,13 +0,0 @@
package com.ruoyi.info.collection.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ruoyi.info.collection.domain.CcdiAccountResult;
/**
* 账户分析结果数据层
*
* @author ruoyi
* @date 2026-04-13
*/
public interface CcdiAccountResultMapper extends BaseMapper<CcdiAccountResult> {
}

View File

@@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.info.collection.domain.CcdiAccountInfo;
import com.ruoyi.info.collection.domain.CcdiAccountResult;
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
import com.ruoyi.info.collection.domain.CcdiStaffFmyRelation;
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoAddDTO;
@@ -16,7 +15,6 @@ import com.ruoyi.info.collection.domain.vo.CcdiAccountInfoVO;
import com.ruoyi.info.collection.domain.vo.CcdiAccountRelationOptionVO;
import com.ruoyi.info.collection.domain.vo.ImportResult;
import com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper;
import com.ruoyi.info.collection.mapper.CcdiAccountResultMapper;
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
import com.ruoyi.info.collection.service.ICcdiAccountInfoService;
@@ -56,9 +54,6 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
@Resource
private CcdiAccountInfoMapper accountInfoMapper;
@Resource
private CcdiAccountResultMapper accountResultMapper;
@Resource
private CcdiBaseStaffMapper baseStaffMapper;
@@ -87,9 +82,8 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
BeanUtils.copyProperties(addDTO, accountInfo);
int result = accountInfoMapper.insert(accountInfo);
syncAccountResult(accountInfo.getBankScope(), null, accountInfo.getAccountNo(), addDTO);
return result;
prepareAnalysisFields(accountInfo);
return accountInfoMapper.insert(accountInfo);
}
@Override
@@ -110,26 +104,13 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
CcdiAccountInfo accountInfo = new CcdiAccountInfo();
BeanUtils.copyProperties(editDTO, accountInfo);
int result = accountInfoMapper.updateById(accountInfo);
syncAccountResult(accountInfo.getBankScope(), existing, accountInfo.getAccountNo(), editDTO);
return result;
prepareAnalysisFields(accountInfo);
return accountInfoMapper.updateById(accountInfo);
}
@Override
@Transactional
public int deleteAccountInfoByIds(Long[] ids) {
List<CcdiAccountInfo> accountList = accountInfoMapper.selectBatchIds(Arrays.asList(ids));
if (!accountList.isEmpty()) {
List<String> accountNos = accountList.stream()
.map(CcdiAccountInfo::getAccountNo)
.filter(StringUtils::isNotEmpty)
.toList();
if (!accountNos.isEmpty()) {
LambdaQueryWrapper<CcdiAccountResult> resultWrapper = new LambdaQueryWrapper<>();
resultWrapper.in(CcdiAccountResult::getAccountNo, accountNos);
accountResultMapper.delete(resultWrapper);
}
}
return accountInfoMapper.deleteBatchIds(Arrays.asList(ids));
}
@@ -250,51 +231,38 @@ public class CcdiAccountInfoServiceImpl implements ICcdiAccountInfoService {
}
}
private void syncAccountResult(String newBankScope, CcdiAccountInfo existing, String accountNo, Object dto) {
String oldBankScope = existing == null ? null : existing.getBankScope();
String oldAccountNo = existing == null ? null : existing.getAccountNo();
if (existing != null && "EXTERNAL".equals(oldBankScope)
&& (!"EXTERNAL".equals(newBankScope) || !StringUtils.equals(oldAccountNo, accountNo))) {
LambdaQueryWrapper<CcdiAccountResult> deleteWrapper = new LambdaQueryWrapper<>();
deleteWrapper.eq(CcdiAccountResult::getAccountNo, oldAccountNo);
accountResultMapper.delete(deleteWrapper);
}
if (!"EXTERNAL".equals(newBankScope)) {
private void prepareAnalysisFields(CcdiAccountInfo accountInfo) {
if (!"EXTERNAL".equals(accountInfo.getBankScope())) {
clearAnalysisFields(accountInfo);
return;
}
if (accountInfo.getIsActualControl() == null) {
accountInfo.setIsActualControl(1);
}
if (accountInfo.getAvgMonthTxnCount() == null) {
accountInfo.setAvgMonthTxnCount(0);
}
if (accountInfo.getAvgMonthTxnAmount() == null) {
accountInfo.setAvgMonthTxnAmount(BigDecimal.ZERO);
}
if (StringUtils.isEmpty(accountInfo.getTxnFrequencyLevel())) {
accountInfo.setTxnFrequencyLevel("MEDIUM");
}
if (StringUtils.isEmpty(accountInfo.getTxnRiskLevel())) {
accountInfo.setTxnRiskLevel("LOW");
}
}
LambdaQueryWrapper<CcdiAccountResult> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CcdiAccountResult::getAccountNo, accountNo);
CcdiAccountResult existingResult = accountResultMapper.selectOne(wrapper);
CcdiAccountResult accountResult = new CcdiAccountResult();
BeanUtils.copyProperties(dto, accountResult);
accountResult.setAccountNo(accountNo);
if (accountResult.getIsActualControl() == null) {
accountResult.setIsActualControl(1);
}
if (accountResult.getAvgMonthTxnCount() == null) {
accountResult.setAvgMonthTxnCount(0);
}
if (accountResult.getAvgMonthTxnAmount() == null) {
accountResult.setAvgMonthTxnAmount(BigDecimal.ZERO);
}
if (StringUtils.isEmpty(accountResult.getTxnFrequencyLevel())) {
accountResult.setTxnFrequencyLevel("MEDIUM");
}
if (StringUtils.isEmpty(accountResult.getTxnRiskLevel())) {
accountResult.setTxnRiskLevel("LOW");
}
if (existingResult == null) {
accountResultMapper.insert(accountResult);
return;
}
accountResult.setResultId(existingResult.getResultId());
accountResultMapper.updateById(accountResult);
private void clearAnalysisFields(CcdiAccountInfo accountInfo) {
accountInfo.setIsActualControl(null);
accountInfo.setAvgMonthTxnCount(null);
accountInfo.setAvgMonthTxnAmount(null);
accountInfo.setTxnFrequencyLevel(null);
accountInfo.setDebitSingleMaxAmount(null);
accountInfo.setCreditSingleMaxAmount(null);
accountInfo.setDebitDailyMaxAmount(null);
accountInfo.setCreditDailyMaxAmount(null);
accountInfo.setTxnRiskLevel(null);
}
private void validateAmount(BigDecimal amount, String fieldLabel) {

View File

@@ -67,15 +67,15 @@
ai.status AS status,
ai.effective_date AS effectiveDate,
ai.invalid_date AS invalidDate,
ar.is_self_account AS isActualControl,
ar.monthly_avg_trans_count AS avgMonthTxnCount,
ar.monthly_avg_trans_amount AS avgMonthTxnAmount,
ar.trans_freq_type AS txnFrequencyLevel,
ar.dr_max_single_amount AS debitSingleMaxAmount,
ar.cr_max_single_amount AS creditSingleMaxAmount,
ar.dr_max_daily_amount AS debitDailyMaxAmount,
ar.cr_max_daily_amount AS creditDailyMaxAmount,
ar.trans_risk_level AS txnRiskLevel,
ai.is_self_account AS isActualControl,
ai.monthly_avg_trans_count AS avgMonthTxnCount,
ai.monthly_avg_trans_amount AS avgMonthTxnAmount,
ai.trans_freq_type AS txnFrequencyLevel,
ai.dr_max_single_amount AS debitSingleMaxAmount,
ai.cr_max_single_amount AS creditSingleMaxAmount,
ai.dr_max_daily_amount AS debitDailyMaxAmount,
ai.cr_max_daily_amount AS creditDailyMaxAmount,
ai.trans_risk_level AS txnRiskLevel,
ai.create_by AS createBy,
ai.create_time AS createTime,
ai.update_by AS updateBy,
@@ -107,10 +107,10 @@
AND ai.account_type = #{query.accountType}
</if>
<if test="query.isActualControl != null">
AND ar.is_self_account = #{query.isActualControl}
AND ai.is_self_account = #{query.isActualControl}
</if>
<if test="query.riskLevel != null and query.riskLevel != ''">
AND ar.trans_risk_level = #{query.riskLevel}
AND ai.trans_risk_level = #{query.riskLevel}
</if>
<if test="query.status != null">
AND ai.status = #{query.status}
@@ -121,7 +121,6 @@
SELECT
<include refid="AccountInfoSelectColumns"/>
FROM ccdi_account_info ai
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
@@ -133,7 +132,6 @@
SELECT
<include refid="AccountInfoSelectColumns"/>
FROM ccdi_account_info ai
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card
@@ -145,7 +143,6 @@
SELECT
<include refid="AccountInfoSelectColumns"/>
FROM ccdi_account_info ai
LEFT JOIN ccdi_account_result ar ON ai.account_no = ar.account_no
LEFT JOIN ccdi_base_staff bs ON ai.owner_type = 'EMPLOYEE' AND ai.owner_id = bs.id_card
LEFT JOIN ccdi_staff_fmy_relation fr ON ai.owner_type = 'RELATION' AND ai.owner_id = fr.relation_cert_no
LEFT JOIN ccdi_base_staff bsRel ON fr.person_id = bsRel.id_card

View File

@@ -0,0 +1,109 @@
package com.ruoyi.info.collection.mapper;
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoQueryDTO;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.scripting.xmltags.XMLLanguageDriver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CcdiAccountInfoMapperTest {
private static final String RESOURCE = "mapper/info/collection/CcdiAccountInfoMapper.xml";
@Test
void selectAccountInfoPage_shouldReadAnalysisColumnsFromAccountInfoTableOnly() throws Exception {
MappedStatement mappedStatement = loadMappedStatement(
"com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper.selectAccountInfoPage");
String sql = renderSql(mappedStatement, Map.of("query", new CcdiAccountInfoQueryDTO())).toLowerCase();
assertTrue(sql.contains("from ccdi_account_info ai"), sql);
assertFalse(sql.contains("ccdi_account_result"), sql);
assertTrue(sql.contains("ai.is_self_account as isactualcontrol"), sql);
assertTrue(sql.contains("ai.monthly_avg_trans_count as avgmonthtxncount"), sql);
assertTrue(sql.contains("ai.trans_risk_level as txnrisklevel"), sql);
}
private MappedStatement loadMappedStatement(String statementId) throws Exception {
Configuration configuration = new Configuration();
configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), new NoOpDataSource()));
registerTypeAliases(configuration.getTypeAliasRegistry());
configuration.getLanguageRegistry().register(XMLLanguageDriver.class);
configuration.addMapper(CcdiAccountInfoMapper.class);
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
XMLMapperBuilder xmlMapperBuilder =
new XMLMapperBuilder(inputStream, configuration, RESOURCE, configuration.getSqlFragments());
xmlMapperBuilder.parse();
}
return configuration.getMappedStatement(statementId);
}
private String renderSql(MappedStatement mappedStatement, Map<String, Object> params) {
BoundSql boundSql = mappedStatement.getBoundSql(new HashMap<>(params));
return boundSql.getSql().replaceAll("\\s+", " ").trim();
}
private void registerTypeAliases(TypeAliasRegistry typeAliasRegistry) {
typeAliasRegistry.registerAlias("map", Map.class);
}
private static class NoOpDataSource implements DataSource {
@Override
public java.sql.Connection getConnection() {
throw new UnsupportedOperationException("Not required for SQL rendering tests");
}
@Override
public java.sql.Connection getConnection(String username, String password) {
throw new UnsupportedOperationException("Not required for SQL rendering tests");
}
@Override
public java.io.PrintWriter getLogWriter() {
return null;
}
@Override
public void setLogWriter(java.io.PrintWriter out) {
}
@Override
public void setLoginTimeout(int seconds) {
}
@Override
public int getLoginTimeout() {
return 0;
}
@Override
public java.util.logging.Logger getParentLogger() {
return java.util.logging.Logger.getGlobal();
}
@Override
public <T> T unwrap(Class<T> iface) {
throw new UnsupportedOperationException("Not supported");
}
@Override
public boolean isWrapperFor(Class<?> iface) {
return false;
}
}
}

View File

@@ -0,0 +1,124 @@
package com.ruoyi.info.collection.service;
import com.ruoyi.info.collection.domain.CcdiAccountInfo;
import com.ruoyi.info.collection.domain.CcdiBaseStaff;
import com.ruoyi.info.collection.domain.dto.CcdiAccountInfoAddDTO;
import com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper;
import com.ruoyi.info.collection.mapper.CcdiBaseStaffMapper;
import com.ruoyi.info.collection.mapper.CcdiStaffFmyRelationMapper;
import com.ruoyi.info.collection.service.impl.CcdiAccountInfoServiceImpl;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.BeanWrapperImpl;
import java.math.BigDecimal;
import java.util.Date;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class CcdiAccountInfoServiceImplTest {
@InjectMocks
private CcdiAccountInfoServiceImpl service;
@Mock
private CcdiAccountInfoMapper accountInfoMapper;
@Mock
private CcdiBaseStaffMapper baseStaffMapper;
@Mock
private CcdiStaffFmyRelationMapper staffFmyRelationMapper;
@Test
void insertExternalAccount_shouldPersistAnalysisFieldsOnAccountInfo() {
CcdiAccountInfoAddDTO dto = buildBaseAddDto();
dto.setOwnerType("EXTERNAL");
dto.setOwnerId("330101199001010011");
dto.setBankScope("EXTERNAL");
dto.setIsActualControl(0);
dto.setAvgMonthTxnCount(6);
dto.setAvgMonthTxnAmount(new BigDecimal("1234.56"));
dto.setTxnFrequencyLevel("HIGH");
dto.setDebitSingleMaxAmount(new BigDecimal("100.00"));
dto.setCreditSingleMaxAmount(new BigDecimal("200.00"));
dto.setDebitDailyMaxAmount(new BigDecimal("300.00"));
dto.setCreditDailyMaxAmount(new BigDecimal("400.00"));
dto.setTxnRiskLevel("MEDIUM");
when(accountInfoMapper.selectCount(any())).thenReturn(0L);
when(accountInfoMapper.insert(any(CcdiAccountInfo.class))).thenReturn(1);
service.insertAccountInfo(dto);
ArgumentCaptor<CcdiAccountInfo> captor = ArgumentCaptor.forClass(CcdiAccountInfo.class);
verify(accountInfoMapper).insert(captor.capture());
BeanWrapperImpl wrapper = new BeanWrapperImpl(captor.getValue());
assertEquals(0, wrapper.getPropertyValue("isActualControl"));
assertEquals(6, wrapper.getPropertyValue("avgMonthTxnCount"));
assertEquals(new BigDecimal("1234.56"), wrapper.getPropertyValue("avgMonthTxnAmount"));
assertEquals("HIGH", wrapper.getPropertyValue("txnFrequencyLevel"));
assertEquals("MEDIUM", wrapper.getPropertyValue("txnRiskLevel"));
}
@Test
void insertInternalAccount_shouldClearAnalysisFieldsOnAccountInfo() {
CcdiAccountInfoAddDTO dto = buildBaseAddDto();
dto.setOwnerType("EMPLOYEE");
dto.setOwnerId("330101199001010022");
dto.setBankScope("INTERNAL");
dto.setIsActualControl(1);
dto.setAvgMonthTxnCount(8);
dto.setAvgMonthTxnAmount(new BigDecimal("9988.66"));
dto.setTxnFrequencyLevel("HIGH");
dto.setDebitSingleMaxAmount(new BigDecimal("111.11"));
dto.setCreditSingleMaxAmount(new BigDecimal("222.22"));
dto.setDebitDailyMaxAmount(new BigDecimal("333.33"));
dto.setCreditDailyMaxAmount(new BigDecimal("444.44"));
dto.setTxnRiskLevel("HIGH");
CcdiBaseStaff staff = new CcdiBaseStaff();
staff.setIdCard(dto.getOwnerId());
when(baseStaffMapper.selectOne(any())).thenReturn(staff);
when(accountInfoMapper.selectCount(any())).thenReturn(0L);
when(accountInfoMapper.insert(any(CcdiAccountInfo.class))).thenReturn(1);
service.insertAccountInfo(dto);
ArgumentCaptor<CcdiAccountInfo> captor = ArgumentCaptor.forClass(CcdiAccountInfo.class);
verify(accountInfoMapper).insert(captor.capture());
BeanWrapperImpl wrapper = new BeanWrapperImpl(captor.getValue());
assertNull(wrapper.getPropertyValue("isActualControl"));
assertNull(wrapper.getPropertyValue("avgMonthTxnCount"));
assertNull(wrapper.getPropertyValue("avgMonthTxnAmount"));
assertNull(wrapper.getPropertyValue("txnFrequencyLevel"));
assertNull(wrapper.getPropertyValue("debitSingleMaxAmount"));
assertNull(wrapper.getPropertyValue("creditSingleMaxAmount"));
assertNull(wrapper.getPropertyValue("debitDailyMaxAmount"));
assertNull(wrapper.getPropertyValue("creditDailyMaxAmount"));
assertNull(wrapper.getPropertyValue("txnRiskLevel"));
}
private CcdiAccountInfoAddDTO buildBaseAddDto() {
CcdiAccountInfoAddDTO dto = new CcdiAccountInfoAddDTO();
dto.setAccountNo("6222024000000001");
dto.setAccountType("BANK");
dto.setAccountName("测试账户");
dto.setOpenBank("中国银行");
dto.setBankCode("BOC");
dto.setCurrency("CNY");
dto.setStatus(1);
dto.setEffectiveDate(new Date());
return dto;
}
}