完成银行流水打标规则大写编码与后端落地

This commit is contained in:
wkc
2026-03-18 13:44:15 +08:00
parent 9791dab67e
commit b07b725057
18 changed files with 1241 additions and 25 deletions

View File

@@ -28,6 +28,7 @@
- 测试结束后,自动关闭测试过程中启动的前后端进程
- 遇到 MCP 数据库操作时,使用项目配置文件中的数据库连接信息
- 执行包含中文内容的 MySQL SQL 脚本时,禁止直接手写 `mysql -e` 或普通重定向执行;必须优先使用 `bin/mysql_utf8_exec.sh <sql-file>`,确保会话字符集为 `utf8mb4`,避免写入乱码
- 银行流水打标相关规则与参数编码需要统一使用全大写;新增或修改 `rule_code``indicator_code``param_code` 时,禁止混用大小写风格
---

View File

@@ -89,4 +89,204 @@ public interface CcdiBankTagAnalysisMapper {
*/
List<BankTagStatementHitVO> selectLargeTransferStatements(@Param("projectId") Long projectId,
@Param("threshold") BigDecimal threshold);
/**
* 与客户之间非正常资金往来
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectAbnormalCustomerTransactionStatements(@Param("projectId") Long projectId);
/**
* 低收入亲属大额交易
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectLowIncomeRelativeLargeTransactionObjects(@Param("projectId") Long projectId);
/**
* 疑似赌博交易
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectMultiPartyGamblingTransferObjects(@Param("projectId") Long projectId);
/**
* 疑似敏感交易
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectGamblingSensitiveKeywordStatements(@Param("projectId") Long projectId);
/**
* 特殊金额交易
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectSpecialAmountTransactionStatements(@Param("projectId") Long projectId);
/**
* 月度固定收入疑似兼职
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectMonthlyFixedIncomeObjects(@Param("projectId") Long projectId);
/**
* 固定交易对手转入疑似兼职
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectFixedCounterpartyTransferObjects(@Param("projectId") Long projectId);
/**
* 摘要收入疑似兼职
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectSuspiciousIncomeKeywordStatements(@Param("projectId") Long projectId);
/**
* 购房交易与房产登记不匹配
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectHouseRegistrationMismatchStatements(@Param("projectId") Long projectId);
/**
* 物业缴费与房产登记不匹配
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectPropertyFeeRegistrationMismatchStatements(@Param("projectId") Long projectId);
/**
* 大额纳税与资产登记不匹配
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectTaxAssetRegistrationMismatchStatements(@Param("projectId") Long projectId);
/**
* 收入资产不符
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectIncomeAssetMismatchStatements(@Param("projectId") Long projectId);
/**
* 单笔购汇金额超限
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectForexBuyAmtStatements(@Param("projectId") Long projectId);
/**
* 单笔结汇金额超限
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectForexSellAmtStatements(@Param("projectId") Long projectId);
/**
* 单笔跨境汇款金额超限
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectCrossBorderAmtStatements(@Param("projectId") Long projectId);
/**
* 可疑付息
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectInterestPaymentByOthersObjects(@Param("projectId") Long projectId);
/**
* 单笔采购金额超过10万元
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectLargePurchaseTransactionStatements(@Param("projectId") Long projectId);
/**
* 供应商集中采购
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectSupplierConcentrationObjects(@Param("projectId") Long projectId);
/**
* 可疑银证大额转账
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectStockTfrLargeStatements(@Param("projectId") Long projectId);
/**
* 微信支付宝频繁提现
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectWithdrawCntObjects(@Param("projectId") Long projectId);
/**
* 微信支付宝提现超额
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectWithdrawAmtObjects(@Param("projectId") Long projectId);
/**
* 工资快速转出
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectSalaryQuickTransferObjects(@Param("projectId") Long projectId);
/**
* 工资无使用记录
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectSalaryUnusedObjects(@Param("projectId") Long projectId);
/**
* 大额炒股
*
* @param projectId 项目ID
* @return 流水命中结果
*/
List<BankTagStatementHitVO> selectLargeStockTradingStatements(@Param("projectId") Long projectId);
/**
* 疑似代理他人账户
*
* @param projectId 项目ID
* @return 对象命中结果
*/
List<BankTagObjectHitVO> selectProxyAccountOperationObjects(@Param("projectId") Long projectId);
}

View File

@@ -27,7 +27,7 @@ public class BankTagRuleConfigResolver {
private static final Map<String, Set<String>> RULE_PARAM_MAPPING = Map.of(
"SINGLE_LARGE_INCOME", Set.of("SINGLE_TRANSACTION_AMOUNT"),
"CUMULATIVE_INCOME", Set.of("CUMULATIVE_TRANSACTION_AMOUNT"),
"ANNUAL_TURNOVER", Set.of("annual_turnover"),
"ANNUAL_TURNOVER", Set.of("ANNUAL_TURNOVER"),
"LARGE_CASH_DEPOSIT", Set.of("LARGE_CASH_DEPOSIT"),
"FREQUENT_CASH_DEPOSIT", Set.of("LARGE_CASH_DEPOSIT", "FREQUENT_CASH_DEPOSIT"),
"LARGE_TRANSFER", Set.of("FREQUENT_TRANSFER")

View File

@@ -211,6 +211,20 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
case "LARGE_TRANSFER" -> analysisMapper.selectLargeTransferStatements(
projectId, toBigDecimal(config.getThresholdValue("FREQUENT_TRANSFER"))
);
case "ABNORMAL_CUSTOMER_TRANSACTION" -> analysisMapper.selectAbnormalCustomerTransactionStatements(projectId);
case "GAMBLING_SENSITIVE_KEYWORD" -> analysisMapper.selectGamblingSensitiveKeywordStatements(projectId);
case "SPECIAL_AMOUNT_TRANSACTION" -> analysisMapper.selectSpecialAmountTransactionStatements(projectId);
case "SUSPICIOUS_INCOME_KEYWORD" -> analysisMapper.selectSuspiciousIncomeKeywordStatements(projectId);
case "HOUSE_REGISTRATION_MISMATCH" -> analysisMapper.selectHouseRegistrationMismatchStatements(projectId);
case "PROPERTY_FEE_REGISTRATION_MISMATCH" -> analysisMapper.selectPropertyFeeRegistrationMismatchStatements(projectId);
case "TAX_ASSET_REGISTRATION_MISMATCH" -> analysisMapper.selectTaxAssetRegistrationMismatchStatements(projectId);
case "INCOME_ASSET_MISMATCH" -> analysisMapper.selectIncomeAssetMismatchStatements(projectId);
case "FOREX_BUY_AMT" -> analysisMapper.selectForexBuyAmtStatements(projectId);
case "FOREX_SELL_AMT" -> analysisMapper.selectForexSellAmtStatements(projectId);
case "CROSS_BORDER_AMT" -> analysisMapper.selectCrossBorderAmtStatements(projectId);
case "LARGE_PURCHASE_TRANSACTION" -> analysisMapper.selectLargePurchaseTransactionStatements(projectId);
case "STOCK_TFR_LARGE" -> analysisMapper.selectStockTfrLargeStatements(projectId);
case "LARGE_STOCK_TRADING" -> analysisMapper.selectLargeStockTradingStatements(projectId);
default -> List.of();
};
}
@@ -223,13 +237,24 @@ public class CcdiBankTagServiceImpl implements ICcdiBankTagService {
projectId, toBigDecimal(config.getThresholdValue("CUMULATIVE_TRANSACTION_AMOUNT"))
);
case "ANNUAL_TURNOVER" -> analysisMapper.selectAnnualTurnoverObjects(
projectId, toBigDecimal(config.getThresholdValue("annual_turnover"))
projectId, toBigDecimal(config.getThresholdValue("ANNUAL_TURNOVER"))
);
case "FREQUENT_CASH_DEPOSIT" -> analysisMapper.selectFrequentCashDepositObjects(
projectId,
toBigDecimal(config.getThresholdValue("LARGE_CASH_DEPOSIT")),
toInteger(config.getThresholdValue("FREQUENT_CASH_DEPOSIT"))
);
case "LOW_INCOME_RELATIVE_LARGE_TRANSACTION" -> analysisMapper.selectLowIncomeRelativeLargeTransactionObjects(projectId);
case "MULTI_PARTY_GAMBLING_TRANSFER" -> analysisMapper.selectMultiPartyGamblingTransferObjects(projectId);
case "MONTHLY_FIXED_INCOME" -> analysisMapper.selectMonthlyFixedIncomeObjects(projectId);
case "FIXED_COUNTERPARTY_TRANSFER" -> analysisMapper.selectFixedCounterpartyTransferObjects(projectId);
case "INTEREST_PAYMENT_BY_OTHERS" -> analysisMapper.selectInterestPaymentByOthersObjects(projectId);
case "SUPPLIER_CONCENTRATION" -> analysisMapper.selectSupplierConcentrationObjects(projectId);
case "WITHDRAW_CNT" -> analysisMapper.selectWithdrawCntObjects(projectId);
case "WITHDRAW_AMT" -> analysisMapper.selectWithdrawAmtObjects(projectId);
case "SALARY_QUICK_TRANSFER" -> analysisMapper.selectSalaryQuickTransferObjects(projectId);
case "SALARY_UNUSED" -> analysisMapper.selectSalaryUnusedObjects(projectId);
case "PROXY_ACCOUNT_OPERATION" -> analysisMapper.selectProxyAccountOperationObjects(projectId);
default -> List.of();
};
}

View File

@@ -363,4 +363,243 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
)
</select>
<select id="selectAbnormalCustomerTransactionStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectLowIncomeRelativeLargeTransactionObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectMultiPartyGamblingTransferObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectGamblingSensitiveKeywordStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectSpecialAmountTransactionStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectMonthlyFixedIncomeObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectFixedCounterpartyTransferObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectSuspiciousIncomeKeywordStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectHouseRegistrationMismatchStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectPropertyFeeRegistrationMismatchStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectTaxAssetRegistrationMismatchStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectIncomeAssetMismatchStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectForexBuyAmtStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectForexSellAmtStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectCrossBorderAmtStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectInterestPaymentByOthersObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectLargePurchaseTransactionStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectSupplierConcentrationObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectStockTfrLargeStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectWithdrawCntObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectWithdrawAmtObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectSalaryQuickTransferObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectSalaryUnusedObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectLargeStockTradingStatements" resultMap="BankTagStatementHitResultMap">
select
bs.bank_statement_id AS bankStatementId,
bs.group_id AS groupId,
bs.batch_id AS logId,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
<select id="selectProxyAccountOperationObjects" resultMap="BankTagObjectHitResultMap">
select
'STAFF_ID_CARD' AS objectType,
'' AS objectKey,
'占位SQL待补充真实规则' AS reasonDetail
from ccdi_bank_statement bs
where 1 = 0
</select>
</mapper>

View File

@@ -7,12 +7,41 @@ import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
class CcdiBankTagAnalysisMapperXmlTest {
private static final String RESOURCE = "mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml";
private static final List<String> PLACEHOLDER_SELECT_IDS = List.of(
"selectAbnormalCustomerTransactionStatements",
"selectLowIncomeRelativeLargeTransactionObjects",
"selectMultiPartyGamblingTransferObjects",
"selectGamblingSensitiveKeywordStatements",
"selectSpecialAmountTransactionStatements",
"selectMonthlyFixedIncomeObjects",
"selectFixedCounterpartyTransferObjects",
"selectSuspiciousIncomeKeywordStatements",
"selectHouseRegistrationMismatchStatements",
"selectPropertyFeeRegistrationMismatchStatements",
"selectTaxAssetRegistrationMismatchStatements",
"selectIncomeAssetMismatchStatements",
"selectForexBuyAmtStatements",
"selectForexSellAmtStatements",
"selectCrossBorderAmtStatements",
"selectInterestPaymentByOthersObjects",
"selectLargePurchaseTransactionStatements",
"selectSupplierConcentrationObjects",
"selectStockTfrLargeStatements",
"selectWithdrawCntObjects",
"selectWithdrawAmtObjects",
"selectSalaryQuickTransferObjects",
"selectSalaryUnusedObjects",
"selectLargeStockTradingStatements",
"selectProxyAccountOperationObjects"
);
@Test
void statementRuleSql_shouldSelectGroupIdAndLogId() throws Exception {
@@ -42,6 +71,21 @@ class CcdiBankTagAnalysisMapperXmlTest {
assertTrue(xml.contains("selectLargeTransferStatements"));
}
@Test
void allPlaceholderRules_shouldExistInAnalysisMapperXml() throws Exception {
String xml = readXml(RESOURCE);
for (String selectId : PLACEHOLDER_SELECT_IDS) {
assertTrue(xml.contains(selectId), () -> "缺少占位规则 SQL: " + selectId);
}
}
@Test
void placeholderRules_shouldUseEmptyResultSqlTemplate() throws Exception {
String xml = readXml(RESOURCE);
assertTrue(xml.contains("占位SQL待补充真实规则"));
assertEquals(25, countMatches(xml, "where 1 = 0"));
}
@Test
void analysisMapperXml_shouldBeWellFormed() throws Exception {
String xml = readXml(RESOURCE);
@@ -56,4 +100,14 @@ class CcdiBankTagAnalysisMapperXmlTest {
return new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
}
}
private int countMatches(String text, String target) {
int count = 0;
int index = 0;
while ((index = text.indexOf(target, index)) >= 0) {
count++;
index += target.length();
}
return count;
}
}

View File

@@ -90,6 +90,46 @@ class BankTagRuleConfigResolverTest {
}
}
@Test
void resolve_shouldReturnEmptyThresholdsForPlaceholderRulesWithoutIndicatorCode() {
CcdiProject project = new CcdiProject();
project.setProjectId(40L);
project.setConfigType("default");
when(projectMapper.selectById(40L)).thenReturn(project);
when(modelParamMapper.selectByProjectAndModel(0L, "ABNORMAL_TRANSACTION")).thenReturn(List.of(
buildParam("IGNORED_PARAM", "999")
));
CcdiBankTagRule ruleMeta = new CcdiBankTagRule();
ruleMeta.setModelCode("ABNORMAL_TRANSACTION");
ruleMeta.setRuleCode("ABNORMAL_CUSTOMER_TRANSACTION");
ruleMeta.setIndicatorCode(null);
BankTagRuleExecutionConfig config = resolver.resolve(40L, ruleMeta);
assertTrue(config.getThresholdValues().isEmpty());
}
@Test
void resolve_shouldReadUppercaseAnnualTurnoverParamCode() {
CcdiProject project = new CcdiProject();
project.setProjectId(40L);
project.setConfigType("default");
when(projectMapper.selectById(40L)).thenReturn(project);
when(modelParamMapper.selectByProjectAndModel(0L, "LARGE_TRANSACTION")).thenReturn(List.of(
buildParam("ANNUAL_TURNOVER", "8888")
));
CcdiBankTagRule ruleMeta = new CcdiBankTagRule();
ruleMeta.setModelCode("LARGE_TRANSACTION");
ruleMeta.setRuleCode("ANNUAL_TURNOVER");
ruleMeta.setIndicatorCode("ANNUAL_TURNOVER");
BankTagRuleExecutionConfig config = resolver.resolve(40L, ruleMeta);
assertEquals("8888", config.getThresholdValue("ANNUAL_TURNOVER"));
}
private CcdiModelParam buildParam(String paramCode, String paramValue) {
CcdiModelParam param = new CcdiModelParam();
param.setProjectId(0L);

View File

@@ -28,8 +28,10 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -175,4 +177,61 @@ class CcdiBankTagServiceImplTest {
logger.detachAppender(logAppender);
}
}
@Test
void rebuildProject_shouldDispatchPlaceholderStatementRuleAndFinishWithoutResults() {
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
CcdiBankTagRule rule = buildRule("ABNORMAL_TRANSACTION", "异常交易",
"ABNORMAL_CUSTOMER_TRANSACTION", "与客户之间非正常资金往来", "STATEMENT");
BankTagRuleExecutionConfig config = buildConfig(40L, rule);
when(ruleMapper.selectEnabledRules("ABNORMAL_TRANSACTION")).thenReturn(List.of(rule));
when(configResolver.resolve(40L, rule)).thenReturn(config);
when(analysisMapper.selectAbnormalCustomerTransactionStatements(40L)).thenReturn(List.of());
service.rebuildProject(40L, "ABNORMAL_TRANSACTION", "admin", TriggerType.MANUAL);
verify(resultMapper).deleteByProjectAndModel(40L, "ABNORMAL_TRANSACTION");
verify(analysisMapper).selectAbnormalCustomerTransactionStatements(40L);
verify(resultMapper, never()).insertBatch(anyList());
verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus()) && task.getHitCount() == 0));
}
@Test
void rebuildProject_shouldDispatchPlaceholderObjectRuleAndFinishWithoutResults() {
ReflectionTestUtils.setField(service, "tagRuleExecutor", (Executor) Runnable::run);
CcdiBankTagRule rule = buildRule("SUSPICIOUS_PURCHASE", "可疑采购",
"SUPPLIER_CONCENTRATION", "可疑采购", "OBJECT");
BankTagRuleExecutionConfig config = buildConfig(40L, rule);
when(ruleMapper.selectEnabledRules("SUSPICIOUS_PURCHASE")).thenReturn(List.of(rule));
when(configResolver.resolve(40L, rule)).thenReturn(config);
when(analysisMapper.selectSupplierConcentrationObjects(40L)).thenReturn(List.of());
service.rebuildProject(40L, "SUSPICIOUS_PURCHASE", "admin", TriggerType.MANUAL);
verify(analysisMapper).selectSupplierConcentrationObjects(40L);
verify(resultMapper).deleteByProjectAndModel(40L, "SUSPICIOUS_PURCHASE");
verify(resultMapper, never()).insertBatch(anyList());
verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus()) && task.getFailedRuleCount() == 0));
}
private CcdiBankTagRule buildRule(String modelCode, String modelName, String ruleCode, String ruleName, String resultType) {
CcdiBankTagRule rule = new CcdiBankTagRule();
rule.setModelCode(modelCode);
rule.setModelName(modelName);
rule.setRuleCode(ruleCode);
rule.setRuleName(ruleName);
rule.setResultType(resultType);
return rule;
}
private BankTagRuleExecutionConfig buildConfig(Long projectId, CcdiBankTagRule rule) {
BankTagRuleExecutionConfig config = new BankTagRuleExecutionConfig();
config.setProjectId(projectId);
config.setRuleMeta(rule);
return config;
}
}

View File

@@ -65,7 +65,7 @@ class CcdiModelParamServiceImplTest {
when(projectMapper.selectById(123L)).thenReturn(project);
when(modelParamMapper.selectByProjectId(0L)).thenReturn(List.of(
buildParam(1L, 0L, "LARGE_TRANSACTION", "大额交易模型", "SINGLE_TRANSACTION_AMOUNT", "1111"),
buildParam(2L, 0L, "SUSPICIOUS_GAMBLING", "疑似赌博交易模型", "multi_party_amt_min", "500")
buildParam(2L, 0L, "SUSPICIOUS_GAMBLING", "疑似赌博交易模型", "MULTI_PARTY_AMT_MIN", "500")
));
when(modelParamMapper.insertBatch(anyList())).thenReturn(2);
when(modelParamMapper.updateParamValue(123L, "LARGE_TRANSACTION", "SINGLE_TRANSACTION_AMOUNT", "2222", "admin"))

View File

@@ -22,6 +22,15 @@ class CcdiModelParamSqlDefaultsTest {
assertQuarterlyStableIncomeRangeConfig(updateSql);
}
@Test
void defaultSql_shouldUseUppercaseParamCodesForBankTagModels() throws IOException {
String initSql = readProjectFile("sql", "ccdi_model_param.sql");
String updateSql = readProjectFile("sql", "2026-03-16-update-ccdi-model-param-defaults.sql");
assertUppercaseBankTagParamCodes(initSql);
assertUppercaseBankTagParamCodes(updateSql);
}
private void assertQuarterlyStableIncomeRangeConfig(String sqlContent) {
assertAll(
() -> assertTrue(sqlContent.contains("FIXED_COUNTERPARTY_TRANSFER_MIN"),
@@ -41,6 +50,35 @@ class CcdiModelParamSqlDefaultsTest {
);
}
private void assertUppercaseBankTagParamCodes(String sqlContent) {
assertAll(
() -> assertTrue(sqlContent.contains("ANNUAL_TURNOVER"),
"应包含大写参数编码 ANNUAL_TURNOVER"),
() -> assertTrue(sqlContent.contains("STOCK_TFR_LARGE"),
"应包含大写参数编码 STOCK_TFR_LARGE"),
() -> assertTrue(sqlContent.contains("WITHDRAW_CNT"),
"应包含大写参数编码 WITHDRAW_CNT"),
() -> assertTrue(sqlContent.contains("WITHDRAW_AMT"),
"应包含大写参数编码 WITHDRAW_AMT"),
() -> assertTrue(sqlContent.contains("MULTI_PARTY_AMT_MIN"),
"应包含大写参数编码 MULTI_PARTY_AMT_MIN"),
() -> assertTrue(sqlContent.contains("MULTI_PARTY_AMT_MAX"),
"应包含大写参数编码 MULTI_PARTY_AMT_MAX"),
() -> assertFalse(sqlContent.contains("'annual_turnover'"),
"不应继续保留小写参数编码 annual_turnover"),
() -> assertFalse(sqlContent.contains("'stock_tfr_large'"),
"不应继续保留小写参数编码 stock_tfr_large"),
() -> assertFalse(sqlContent.contains("'withdraw_cnt'"),
"不应继续保留小写参数编码 withdraw_cnt"),
() -> assertFalse(sqlContent.contains("'withdraw_amt'"),
"不应继续保留小写参数编码 withdraw_amt"),
() -> assertFalse(sqlContent.contains("'multi_party_amt_min'"),
"不应继续保留小写参数编码 multi_party_amt_min"),
() -> assertFalse(sqlContent.contains("'multi_party_amt_max'"),
"不应继续保留小写参数编码 multi_party_amt_max")
);
}
private String readProjectFile(String... parts) throws IOException {
Path path = Path.of("..", parts);
return Files.readString(path, StandardCharsets.UTF_8);

View File

@@ -151,18 +151,14 @@
1. 已有现存规则编码的,保持不变
2. Excel 提供了明确英文指标名且适合复用为规则编码的,直接使用英文指标名
3. Excel 未提供英文指标名的,使用稳定占位编码
占位编码格式:
- `<MODEL_CODE>_<两位序号>`
3. Excel 未提供英文指标名的,结合规则实际业务含义生成稳定的语义化编码
示例:
- `ABNORMAL_TRANSACTION_01`
- `SUSPICIOUS_PROPERTY_03`
- `ABNORMAL_CUSTOMER_TRANSACTION`
- `TAX_ASSET_REGISTRATION_MISMATCH`
这样可确保编码稳定、可批量生成、可回溯到 Excel 顺序,同时避免为无英文名规则主观造词
这样可确保编码稳定可读,又能直接体现规则指标语义,避免仅靠数字序号区分规则
### 自动补齐字段规则

View File

@@ -0,0 +1,40 @@
# 银行流水占位规则后端实施记录
## 变更概述
-`assets/模型信息.xlsx` 补齐银行流水打标缺失的 25 条规则初始化数据。
- 为新增规则补齐 `CcdiBankTagAnalysisMapper` 方法声明与 `CcdiBankTagAnalysisMapper.xml` 占位 SQL。
-`CcdiBankTagServiceImpl` 中补齐新增规则分发,保证空结果规则也能正常执行完成。
- 为占位规则补充 XML、Service、参数解析回归测试。
## 涉及文件
- `sql/2026-03-16-bank-tagging.sql`
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiBankTagAnalysisMapper.java`
- `ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml`
- `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImpl.java`
- `ccdi-project/src/test/java/com/ruoyi/ccdi/project/mapper/CcdiBankTagAnalysisMapperXmlTest.java`
- `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImplTest.java`
- `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/BankTagRuleConfigResolverTest.java`
## 实施结果
- 初始化 SQL 中规则总数补齐为 33 条,覆盖 10 个模型组。
- 数字占位 `rule_code` 已按业务语义改为可读编码,例如 `ABNORMAL_CUSTOMER_TRANSACTION``SUPPLIER_CONCENTRATION``SALARY_QUICK_TRANSFER`
- 规则元数据中的 `rule_code``indicator_code` 已统一为全大写;默认参数脚本中的相关 `param_code` 也已同步切换为全大写,并同步调整了解析映射。
- 新增 25 个占位 Mapper 方法与对应 XML `select`,全部使用独立 `where 1 = 0` 空结果 SQL。
- Service 已按 `rule_code` 分发到新增占位方法,空结果不会触发批量写入,任务状态可正常收敛为 `SUCCESS`
- 参数解析器现有逻辑已可安全处理无参数映射的占位规则,因此本次未修改 `BankTagRuleConfigResolver.java`
## 验证记录
- `mvn test -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=CcdiBankTagAnalysisMapperXmlTest`
- `mvn test -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=CcdiBankTagServiceImplTest`
- `mvn test -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=BankTagRuleConfigResolverTest`
- `mvn test -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=CcdiBankTagAnalysisMapperXmlTest,BankTagRuleConfigResolverTest,CcdiBankTagServiceImplTest`
- `mvn -pl ccdi-project -am -DskipTests compile`
## 注意事项
- 计划中的 Maven 单测命令在当前多模块 Reactor 下需要补 `-Dsurefire.failIfNoSpecifiedTests=false`,否则上游无匹配测试的模块会提前失败。
- `assets/模型信息.xlsx` 中“工资无使用记录”对应业务口径原始单元格存在乱码,本次按源数据原样落库,后续若拿到修正版设计数据建议同步修正。

View File

@@ -0,0 +1,34 @@
# 银行流水打标编码大写与数据库同步实施记录
## 变更概述
- 在 [`AGENTS.md`](/Users/wkc/Desktop/ccdi/ccdi/AGENTS.md) 补充银行流水打标相关 `rule_code``indicator_code``param_code` 必须统一全大写的协作约束。
- 将默认参数脚本中遗漏的 `SUSPICIOUS_GAMBLING` 参数编码改为全大写:`MULTI_PARTY_AMT_MIN``MULTI_PARTY_AMT_MAX`
- 新增可重复执行的增量脚本 [`sql/migration/2026-03-18-sync-bank-tag-uppercase-and-rules.sql`](/Users/wkc/Desktop/ccdi/ccdi/sql/migration/2026-03-18-sync-bank-tag-uppercase-and-rules.sql),用于同步规则表、指标编码和参数编码。
## 涉及文件
- [`AGENTS.md`](/Users/wkc/Desktop/ccdi/ccdi/AGENTS.md)
- [`sql/ccdi_model_param.sql`](/Users/wkc/Desktop/ccdi/ccdi/sql/ccdi_model_param.sql)
- [`sql/2026-03-16-update-ccdi-model-param-defaults.sql`](/Users/wkc/Desktop/ccdi/ccdi/sql/2026-03-16-update-ccdi-model-param-defaults.sql)
- [`sql/migration/2026-03-18-sync-bank-tag-uppercase-and-rules.sql`](/Users/wkc/Desktop/ccdi/ccdi/sql/migration/2026-03-18-sync-bank-tag-uppercase-and-rules.sql)
- [`ccdi-project/src/test/java/com/ruoyi/ccdi/project/sql/CcdiModelParamSqlDefaultsTest.java`](/Users/wkc/Desktop/ccdi/ccdi/ccdi-project/src/test/java/com/ruoyi/ccdi/project/sql/CcdiModelParamSqlDefaultsTest.java)
- [`ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImplTest.java`](/Users/wkc/Desktop/ccdi/ccdi/ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImplTest.java)
## 实施结果
- 默认参数 SQL 中银行流水打标相关 `param_code` 已全部统一为全大写,不再保留 `annual_turnover``stock_tfr_large``withdraw_cnt``withdraw_amt``multi_party_amt_min``multi_party_amt_max` 等小写残留。
- 增量脚本已执行,规则表已补齐到 33 条,数据库中的 `rule_code``indicator_code` 均为全大写或 `NULL`
- 参数表中 `LARGE_TRANSACTION``ABNORMAL_BEHAVIOR``SUSPICIOUS_GAMBLING` 模型的默认参数编码已同步为全大写。
## 执行与验证
- 执行脚本:
- `bin/mysql_utf8_exec.sh sql/migration/2026-03-18-sync-bank-tag-uppercase-and-rules.sql`
- 数据库核验:
- `ccdi_bank_tag_rule` 共 33 条规则,`rule_code`/`indicator_code` 全部满足全大写约束。
- `ccdi_model_param` 中相关参数编码核验结果为 `ANNUAL_TURNOVER``STOCK_TFR_LARGE``WITHDRAW_CNT``WITHDRAW_AMT``MULTI_PARTY_AMT_MIN``MULTI_PARTY_AMT_MAX`
## 备注
- 初始化脚本 [`sql/2026-03-16-bank-tagging.sql`](/Users/wkc/Desktop/ccdi/ccdi/sql/2026-03-16-bank-tagging.sql) 因唯一键限制不适合直接重复执行,本次通过增量迁移脚本完成数据库同步,避免重复插入失败。

View File

@@ -0,0 +1,81 @@
# 银行流水打标功能测试记录
## 测试时间
- 2026-03-18
## 测试范围
- 后端规则分发与结果写入
- 手动重算接口
- 项目级重算协调逻辑
- 批量上传完成后的自动触发逻辑
- 项目 `40` 的真实重算结果校验
## 环境信息
- 本地后端服务:`http://127.0.0.1:62318`
- 测试项目:`project_id = 40`
- 项目名称:`大额交易模型测试`
- 数据库现状:
- `ccdi_bank_statement` 中项目 `40` 现有流水 `1289`
- `ccdi_bank_tag_rule` 启用规则 `33` 条,其中 `LARGE_TRANSACTION``8`
## 单元测试验证
- 执行命令:
- `mvn test -pl ccdi-project -am -Dsurefire.failIfNoSpecifiedTests=false -Dtest=CcdiBankTagAnalysisMapperXmlTest,CcdiBankTagResultMapperXmlTest,CcdiBankTagControllerTest,CcdiBankTagServiceImplTest,ProjectBankTagRebuildCoordinatorTest,BankTagRuleConfigResolverTest,CcdiBankTagEntityMappingTest,CcdiFileUploadServiceImplTest`
- 执行结果:
- `BUILD SUCCESS`
- 共执行 `45` 个用例,`0` 失败,`0` 错误,`0` 跳过
- 覆盖点:
- `CcdiBankTagAnalysisMapper.xml` 中 8 条大额交易规则与 25 条占位规则 SQL 存在性校验
- 标签结果删除与批量写入 XML 校验
- 手动重算接口参数透传与日志校验
- 打标任务创建、规则执行、失败日志、空结果规则收敛校验
- 运行中任务拒绝手动重算、自动重算补跑标记校验
- 上传完成触发自动重算校验
## 接口回归验证
- 登录接口:
- `POST /login/test`
- 结果:成功获取测试 token
- 手动重算接口:
- `POST /ccdi/project/tags/rebuild`
- 请求体:`{"projectId":40,"modelCode":"LARGE_TRANSACTION"}`
- 返回结果:`{"msg":"标签重算任务已提交","code":200}`
## 数据库校验
- 重算前:
- 最新任务 ID`8`
- `LARGE_TRANSACTION` 结果数:`26`
- 重算后:
- 新增任务 ID`9`
- 任务状态:`SUCCESS`
- `success_rule_count = 8`
- `failed_rule_count = 0`
- `hit_count = 26`
- 运行中任务数:`0`
## 命中结果分布
- `ANNUAL_TURNOVER``1`
- `CUMULATIVE_INCOME``1`
- `FREQUENT_CASH_DEPOSIT``1`
- `HOUSE_OR_CAR_EXPENSE``2`
- `LARGE_CASH_DEPOSIT``6`
- `LARGE_TRANSFER``3`
- `SINGLE_LARGE_INCOME``10`
- `TAX_EXPENSE``2`
## 结论
- 银行流水打标主链路测试通过。
- 手动重算接口可正常提交并完成 `LARGE_TRANSACTION` 模型重算。
- 项目 `40` 本次重算后结果总数仍为 `26`8 条大额交易规则命中分布与历史预期一致,未发现结果漂移。
## 环境清理
- 本次未新启动前后端测试进程,复用了已在运行的本地后端服务,因此无需额外清理进程。

View File

@@ -75,7 +75,32 @@ VALUES
('LARGE_TRANSACTION', '大额交易', 'TAX_EXPENSE', '税务支出交易', 'TAX_EXPENSE', 'STATEMENT', 'HIGH', '识别税务类大额支出流水', 1, 20, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'SINGLE_LARGE_INCOME', '大额单笔收入', 'SINGLE_TRANSACTION_AMOUNT', 'STATEMENT', 'HIGH', '识别超过单笔阈值的收入流水', 1, 30, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'CUMULATIVE_INCOME', '累计收入超限', 'CUMULATIVE_TRANSACTION_AMOUNT', 'OBJECT', 'HIGH', '识别累计收入超过阈值的对象', 1, 40, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'ANNUAL_TURNOVER', '年流水交易额超限', 'annual_turnover', 'OBJECT', 'HIGH', '识别年交易额超过阈值的对象', 1, 50, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'ANNUAL_TURNOVER', '年流水交易额超限', 'ANNUAL_TURNOVER', 'OBJECT', 'HIGH', '识别年交易额超过阈值的对象', 1, 50, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'LARGE_CASH_DEPOSIT', '大额存现交易', 'LARGE_CASH_DEPOSIT', 'STATEMENT', 'HIGH', '识别大额现金存入流水', 1, 60, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'FREQUENT_CASH_DEPOSIT', '短时间多次存现', 'FREQUENT_CASH_DEPOSIT', 'OBJECT', 'HIGH', '识别短时间多次现金存入对象', 1, 70, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'LARGE_TRANSFER', '大额转账交易', 'FREQUENT_TRANSFER', 'STATEMENT', 'HIGH', '识别大额转账流水', 1, 80, 'system', '初始化规则');
('LARGE_TRANSACTION', '大额交易', 'LARGE_TRANSFER', '大额转账交易', 'FREQUENT_TRANSFER', 'STATEMENT', 'HIGH', '识别大额转账流水', 1, 80, 'system', '初始化规则'),
('ABNORMAL_TRANSACTION', '异常交易', 'ABNORMAL_CUSTOMER_TRANSACTION', '与客户之间非正常资金往来', NULL, 'STATEMENT', 'HIGH', '员工及关系人与客户及关系人之间有超过1000元以上的资金往来客户指信贷类客户包括贷款户、担保人中介库人员包括中介注册的主体及主体关系人。', 1, 10, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_TRANSACTION', '异常交易', 'LOW_INCOME_RELATIVE_LARGE_TRANSACTION', '低收入亲属大额交易', NULL, 'OBJECT', 'GENERAL', '关系人中没有收入或月收入低于3000元的人员累计交易金额超过10万元。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_GAMBLING', '疑似赌博', 'MULTI_PARTY_GAMBLING_TRANSFER', '疑似赌博交易', NULL, 'OBJECT', 'HIGH', '多人2人及以上、多次2次以上、相近时间同一天有转账、微信转账、支付宝转账发生且额度在可疑区间。金额区间可在排查设置页面进行设置', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_GAMBLING', '疑似赌博', 'GAMBLING_SENSITIVE_KEYWORD', '疑似敏感交易', NULL, 'STATEMENT', 'HIGH', '备注或交易摘要、对手有“游戏、抖币、体彩、福彩”等字眼。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_RELATION', '可疑关系', 'SPECIAL_AMOUNT_TRANSACTION', '特殊金额交易', NULL, 'STATEMENT', NULL, '除与配偶、子女外发生特殊金额交易如1314元、520元等具有特殊含义的金额。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'MONTHLY_FIXED_INCOME', '疑似兼职', 'MONTHLY_FIXED_INCOME', 'OBJECT', NULL, '除本行工资收入外,每月有固定收入,固定收入金额自行设置。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'FIXED_COUNTERPARTY_TRANSFER', '疑似兼职', 'FIXED_COUNTERPARTY_TRANSFER', 'OBJECT', NULL, '每季或每年从固定交易对手转入金额金额可设区间值如5000-10000。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'SUSPICIOUS_INCOME_KEYWORD', '疑似兼职', NULL, 'STATEMENT', 'HIGH', '转入资金摘要有“工资”、“分红”、“红利”、“利息(非银行结息)”等收入', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'HOUSE_REGISTRATION_MISMATCH', '购房交易与房产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有购房交易,但名下房产无新增登记;有新增登记购房,但无相关购房交易记录。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'PROPERTY_FEE_REGISTRATION_MISMATCH', '物业缴费与房产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有物业缴费记录,但名下房产无新增登记。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'TAX_ASSET_REGISTRATION_MISMATCH', '大额纳税与资产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有5000元以上的纳税记录但名下无房产车产新增登记。', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'INCOME_ASSET_MISMATCH', '收入资产不符', NULL, 'STATEMENT', 'HIGH', '豪华房产价值超家庭年收入10倍', 1, 40, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'FOREX_BUY_AMT', '可疑外汇交易', 'FOREX_BUY_AMT', 'STATEMENT', NULL, '单笔购汇金额超限', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'FOREX_SELL_AMT', '可疑外汇交易', 'FOREX_SELL_AMT', 'STATEMENT', NULL, '单笔结汇金额超限', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'CROSS_BORDER_AMT', '可疑外汇交易', 'CROSS_BORDER_AMT', 'STATEMENT', NULL, '单笔跨境汇款金额超限', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_INTEREST_PAYMENT', '可疑付息', 'INTEREST_PAYMENT_BY_OTHERS', '可疑付息', NULL, 'OBJECT', 'HIGH', '客户经理管户的客户在智柜、柜面连续代交利息且代交人数超过2人。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PURCHASE', '可疑采购', 'LARGE_PURCHASE_TRANSACTION', '可疑采购', NULL, 'STATEMENT', NULL, '单笔采购金额超过10万元。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PURCHASE', '可疑采购', 'SUPPLIER_CONCENTRATION', '可疑采购', NULL, 'OBJECT', NULL, '单个供应商采购额占总采购额比例超过70%。', 1, 20, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'STOCK_TFR_LARGE', '可疑银证大额转账', 'STOCK_TFR_LARGE', 'STATEMENT', NULL, '家庭老人/非关系人银证大额转账', 1, 10, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'WITHDRAW_CNT', '微信支付宝频繁提现', 'WITHDRAW_CNT', 'OBJECT', NULL, '微信、支付宝单日提现次数超过设置次数', 1, 20, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'WITHDRAW_AMT', '微信支付宝提现超额', 'WITHDRAW_AMT', 'OBJECT', NULL, '微信、支付宝单日累计提现金额超过限额', 1, 30, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'SALARY_QUICK_TRANSFER', '工资快速转出', NULL, 'OBJECT', NULL, '工资发放后24小时内转出超过80%的资金', 1, 40, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'SALARY_UNUSED', '工资无使用记录', NULL, 'OBJECT', NULL, '工资发放后除代扣项目外连续30天犖奕魏蜗鸦蜃思锹肌', 1, 50, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'LARGE_STOCK_TRADING', '大额炒股', NULL, 'STATEMENT', 'HIGH', '单次三方资管交易金额超过100万元。', 1, 60, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'PROXY_ACCOUNT_OPERATION', '疑似代理他人账户', NULL, 'OBJECT', NULL, NULL, 1, 70, 'system', '占位规则待补充真实SQL');

View File

@@ -18,7 +18,7 @@ INSERT INTO ccdi_model_param (
) VALUES
(0, 'LARGE_TRANSACTION', '大额交易模型', 'SINGLE_TRANSACTION_AMOUNT', '单笔大额收入金额', '单笔收入超过该金额', '1111', '', 1, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'CUMULATIVE_TRANSACTION_AMOUNT', '累计大额收入金额', '年累计收入超过该金额', '50000001', '', 2, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'annual_turnover', '年累计交易额', '年累计交易额超过该金额', '50000001', '', 3, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'ANNUAL_TURNOVER', '年累计交易额', '年累计交易额超过该金额', '50000001', '', 3, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'LARGE_CASH_DEPOSIT', '单笔大额存现金额', '单笔存现金额超过', '2000001', '', 4, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '', 5, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
@@ -28,10 +28,10 @@ INSERT INTO ccdi_model_param (
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_PURCHASE_AMOUNT', '单笔购汇金额', '单笔购汇超过该金额', '50000', '美元/笔', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'stock_tfr_large', '银证转账大额金额', '', '1000000', '', 1, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'withdraw_cnt', '微信、支付宝单日提现次数', '', '3', '次/日', 2, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'withdraw_amt', '微信、支付宝单日提现金额', '', '50000', '元/日', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'multi_party_amt_min', '疑似赌博金额下限', '', '500', '', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'multi_party_amt_max', '疑似赌博金额上限', '', '5000', '', 2, 'admin', '系统默认参数');
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'STOCK_TFR_LARGE', '银证转账大额金额', '', '1000000', '', 1, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_CNT', '微信、支付宝单日提现次数', '', '3', '次/日', 2, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_AMT', '微信、支付宝单日提现金额', '', '50000', '元/日', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MIN', '疑似赌博金额下限', '', '500', '', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MAX', '疑似赌博金额上限', '', '5000', '', 2, 'admin', '系统默认参数');
COMMIT;

View File

@@ -30,7 +30,7 @@ CREATE TABLE `ccdi_model_param` (
INSERT INTO ccdi_model_param (project_id, model_code, model_name, param_code, param_name, param_desc, param_value, param_unit, sort_order, create_by, remark) VALUES
(0, 'LARGE_TRANSACTION', '大额交易模型', 'SINGLE_TRANSACTION_AMOUNT', '单笔大额收入金额', '单笔收入超过该金额', '1111', '', 1, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'CUMULATIVE_TRANSACTION_AMOUNT', '累计大额收入金额', '年累计收入超过该金额', '50000001', '', 2, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'annual_turnover', '年累计交易额', '年累计交易额超过该金额', '50000001', '', 3, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'ANNUAL_TURNOVER', '年累计交易额', '年累计交易额超过该金额', '50000001', '', 3, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'LARGE_CASH_DEPOSIT', '单笔大额存现金额', '单笔存现金额超过', '2000001', '', 4, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '', 5, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
@@ -40,8 +40,8 @@ INSERT INTO ccdi_model_param (project_id, model_code, model_name, param_code, pa
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_PURCHASE_AMOUNT', '单笔购汇金额', '单笔购汇超过该金额', '50000', '美元/笔', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'stock_tfr_large', '银证转账大额金额', '', '1000000', '', 1, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'withdraw_cnt', '微信、支付宝单日提现次数', '', '3', '次/日', 2, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'withdraw_amt', '微信、支付宝单日提现金额', '', '50000', '元/日', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'multi_party_amt_min', '疑似赌博金额下限', '', '500', '', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'multi_party_amt_max', '疑似赌博金额上限', '', '5000', '', 2, 'admin', '系统默认参数');
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'STOCK_TFR_LARGE', '银证转账大额金额', '', '1000000', '', 1, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_CNT', '微信、支付宝单日提现次数', '', '3', '次/日', 2, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_AMT', '微信、支付宝单日提现金额', '', '50000', '元/日', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MIN', '疑似赌博金额下限', '', '500', '', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MAX', '疑似赌博金额上限', '', '5000', '', 2, 'admin', '系统默认参数');

View File

@@ -0,0 +1,384 @@
START TRANSACTION;
INSERT INTO ccdi_bank_tag_rule (
model_code,
model_name,
rule_code,
rule_name,
indicator_code,
result_type,
risk_level,
business_caliber,
enabled,
sort_order,
create_by,
remark
) VALUES
('LARGE_TRANSACTION', '大额交易', 'HOUSE_OR_CAR_EXPENSE', '房车消费支出交易', 'HOUSE_OR_CAR_EXPENSE', 'STATEMENT', 'HIGH', '识别房产、购车等大额消费支出流水', 1, 10, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'TAX_EXPENSE', '税务支出交易', 'TAX_EXPENSE', 'STATEMENT', 'HIGH', '识别税务类大额支出流水', 1, 20, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'SINGLE_LARGE_INCOME', '大额单笔收入', 'SINGLE_TRANSACTION_AMOUNT', 'STATEMENT', 'HIGH', '识别超过单笔阈值的收入流水', 1, 30, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'CUMULATIVE_INCOME', '累计收入超限', 'CUMULATIVE_TRANSACTION_AMOUNT', 'OBJECT', 'HIGH', '识别累计收入超过阈值的对象', 1, 40, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'ANNUAL_TURNOVER', '年流水交易额超限', 'ANNUAL_TURNOVER', 'OBJECT', 'HIGH', '识别年交易额超过阈值的对象', 1, 50, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'LARGE_CASH_DEPOSIT', '大额存现交易', 'LARGE_CASH_DEPOSIT', 'STATEMENT', 'HIGH', '识别大额现金存入流水', 1, 60, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'FREQUENT_CASH_DEPOSIT', '短时间多次存现', 'FREQUENT_CASH_DEPOSIT', 'OBJECT', 'HIGH', '识别短时间多次现金存入对象', 1, 70, 'system', '初始化规则'),
('LARGE_TRANSACTION', '大额交易', 'LARGE_TRANSFER', '大额转账交易', 'FREQUENT_TRANSFER', 'STATEMENT', 'HIGH', '识别大额转账流水', 1, 80, 'system', '初始化规则'),
('ABNORMAL_TRANSACTION', '异常交易', 'ABNORMAL_CUSTOMER_TRANSACTION', '与客户之间非正常资金往来', NULL, 'STATEMENT', 'HIGH', '员工及关系人与客户及关系人之间有超过1000元以上的资金往来客户指信贷类客户包括贷款户、担保人中介库人员包括中介注册的主体及主体关系人。', 1, 10, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_TRANSACTION', '异常交易', 'LOW_INCOME_RELATIVE_LARGE_TRANSACTION', '低收入亲属大额交易', NULL, 'OBJECT', 'GENERAL', '关系人中没有收入或月收入低于3000元的人员累计交易金额超过10万元。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_GAMBLING', '疑似赌博', 'MULTI_PARTY_GAMBLING_TRANSFER', '疑似赌博交易', NULL, 'OBJECT', 'HIGH', '多人2人及以上、多次2次以上、相近时间同一天有转账、微信转账、支付宝转账发生且额度在可疑区间。金额区间可在排查设置页面进行设置', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_GAMBLING', '疑似赌博', 'GAMBLING_SENSITIVE_KEYWORD', '疑似敏感交易', NULL, 'STATEMENT', 'HIGH', '备注或交易摘要、对手有“游戏、抖币、体彩、福彩”等字眼。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_RELATION', '可疑关系', 'SPECIAL_AMOUNT_TRANSACTION', '特殊金额交易', NULL, 'STATEMENT', NULL, '除与配偶、子女外发生特殊金额交易如1314元、520元等具有特殊含义的金额。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'MONTHLY_FIXED_INCOME', '疑似兼职', 'MONTHLY_FIXED_INCOME', 'OBJECT', NULL, '除本行工资收入外,每月有固定收入,固定收入金额自行设置。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'FIXED_COUNTERPARTY_TRANSFER', '疑似兼职', 'FIXED_COUNTERPARTY_TRANSFER', 'OBJECT', NULL, '每季或每年从固定交易对手转入金额金额可设区间值如5000-10000。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PART_TIME', '可疑兼职', 'SUSPICIOUS_INCOME_KEYWORD', '疑似兼职', NULL, 'STATEMENT', 'HIGH', '转入资金摘要有“工资”、“分红”、“红利”、“利息(非银行结息)”等收入', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'HOUSE_REGISTRATION_MISMATCH', '购房交易与房产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有购房交易,但名下房产无新增登记;有新增登记购房,但无相关购房交易记录。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'PROPERTY_FEE_REGISTRATION_MISMATCH', '物业缴费与房产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有物业缴费记录,但名下房产无新增登记。', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'TAX_ASSET_REGISTRATION_MISMATCH', '大额纳税与资产登记不匹配', NULL, 'STATEMENT', NULL, '员工及关系人有5000元以上的纳税记录但名下无房产车产新增登记。', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PROPERTY', '可疑财产', 'INCOME_ASSET_MISMATCH', '收入资产不符', NULL, 'STATEMENT', 'HIGH', '豪华房产价值超家庭年收入10倍', 1, 40, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'FOREX_BUY_AMT', '可疑外汇交易', 'FOREX_BUY_AMT', 'STATEMENT', NULL, '单笔购汇金额超限', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'FOREX_SELL_AMT', '可疑外汇交易', 'FOREX_SELL_AMT', 'STATEMENT', NULL, '单笔结汇金额超限', 1, 20, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易', 'CROSS_BORDER_AMT', '可疑外汇交易', 'CROSS_BORDER_AMT', 'STATEMENT', NULL, '单笔跨境汇款金额超限', 1, 30, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_INTEREST_PAYMENT', '可疑付息', 'INTEREST_PAYMENT_BY_OTHERS', '可疑付息', NULL, 'OBJECT', 'HIGH', '客户经理管户的客户在智柜、柜面连续代交利息且代交人数超过2人。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PURCHASE', '可疑采购', 'LARGE_PURCHASE_TRANSACTION', '可疑采购', NULL, 'STATEMENT', NULL, '单笔采购金额超过10万元。', 1, 10, 'system', '占位规则待补充真实SQL'),
('SUSPICIOUS_PURCHASE', '可疑采购', 'SUPPLIER_CONCENTRATION', '可疑采购', NULL, 'OBJECT', NULL, '单个供应商采购额占总采购额比例超过70%。', 1, 20, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'STOCK_TFR_LARGE', '可疑银证大额转账', 'STOCK_TFR_LARGE', 'STATEMENT', NULL, '家庭老人/非关系人银证大额转账', 1, 10, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'WITHDRAW_CNT', '微信支付宝频繁提现', 'WITHDRAW_CNT', 'OBJECT', NULL, '微信、支付宝单日提现次数超过设置次数', 1, 20, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'WITHDRAW_AMT', '微信支付宝提现超额', 'WITHDRAW_AMT', 'OBJECT', NULL, '微信、支付宝单日累计提现金额超过限额', 1, 30, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'SALARY_QUICK_TRANSFER', '工资快速转出', NULL, 'OBJECT', NULL, '工资发放后24小时内转出超过80%的资金', 1, 40, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'SALARY_UNUSED', '工资无使用记录', NULL, 'OBJECT', NULL, '工资发放后除代扣项目外连续30天犖奕魏蜗鸦蜃思锹肌', 1, 50, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'LARGE_STOCK_TRADING', '大额炒股', NULL, 'STATEMENT', 'HIGH', '单次三方资管交易金额超过100万元。', 1, 60, 'system', '占位规则待补充真实SQL'),
('ABNORMAL_BEHAVIOR', '异常行为', 'PROXY_ACCOUNT_OPERATION', '疑似代理他人账户', NULL, 'OBJECT', NULL, NULL, 1, 70, 'system', '占位规则待补充真实SQL')
ON DUPLICATE KEY UPDATE
model_code = VALUES(model_code),
model_name = VALUES(model_name),
rule_name = VALUES(rule_name),
indicator_code = VALUES(indicator_code),
result_type = VALUES(result_type),
risk_level = VALUES(risk_level),
business_caliber = VALUES(business_caliber),
enabled = VALUES(enabled),
sort_order = VALUES(sort_order),
update_by = 'system',
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'ANNUAL_TURNOVER',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'LARGE_TRANSACTION'
AND param_code = 'annual_turnover'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'STOCK_TFR_LARGE',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'ABNORMAL_BEHAVIOR'
AND param_code = 'stock_tfr_large'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'WITHDRAW_CNT',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'ABNORMAL_BEHAVIOR'
AND param_code = 'withdraw_cnt'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'WITHDRAW_AMT',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'ABNORMAL_BEHAVIOR'
AND param_code = 'withdraw_amt'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'MULTI_PARTY_AMT_MIN',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'SUSPICIOUS_GAMBLING'
AND param_code = 'multi_party_amt_min'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
update_by,
update_time,
remark
)
SELECT
project_id,
model_code,
model_name,
'MULTI_PARTY_AMT_MAX',
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
create_time,
COALESCE(update_by, create_by),
update_time,
remark
FROM ccdi_model_param
WHERE model_code = 'SUSPICIOUS_GAMBLING'
AND param_code = 'multi_party_amt_max'
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
DELETE FROM ccdi_model_param
WHERE param_code IN (
'annual_turnover',
'stock_tfr_large',
'withdraw_cnt',
'withdraw_amt',
'multi_party_amt_min',
'multi_party_amt_max'
);
INSERT INTO ccdi_model_param (
project_id,
model_code,
model_name,
param_code,
param_name,
param_desc,
param_value,
param_unit,
sort_order,
create_by,
remark
) VALUES
(0, 'LARGE_TRANSACTION', '大额交易模型', 'SINGLE_TRANSACTION_AMOUNT', '单笔大额收入金额', '单笔收入超过该金额', '1111', '', 1, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'CUMULATIVE_TRANSACTION_AMOUNT', '累计大额收入金额', '年累计收入超过该金额', '50000001', '', 2, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'ANNUAL_TURNOVER', '年累计交易额', '年累计交易额超过该金额', '50000001', '', 3, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'LARGE_CASH_DEPOSIT', '单笔大额存现金额', '单笔存现金额超过', '2000001', '', 4, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '', 5, 'admin', '系统默认参数'),
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'MONTHLY_FIXED_INCOME', '月度非本行工资收入金额', '除本行工资外,每月固定收入超过', '5000', '元/月', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'FIXED_COUNTERPARTY_TRANSFER_MIN', '季度稳定收入金额下限', '每季从固定交易对手转入金额下限', '3000', '元/季', 2, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'FIXED_COUNTERPARTY_TRANSFER_MAX', '季度稳定收入金额上限', '每季从固定交易对手转入金额上限', '15000', '元/季', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_PURCHASE_AMOUNT', '单笔购汇金额', '单笔购汇超过该金额', '50000', '美元/笔', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'STOCK_TFR_LARGE', '银证转账大额金额', '', '1000000', '', 1, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_CNT', '微信、支付宝单日提现次数', '', '3', '次/日', 2, 'admin', '系统默认参数'),
(0, 'ABNORMAL_BEHAVIOR', '异常行为模型', 'WITHDRAW_AMT', '微信、支付宝单日提现金额', '', '50000', '元/日', 3, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MIN', '疑似赌博金额下限', '', '500', '', 1, 'admin', '系统默认参数'),
(0, 'SUSPICIOUS_GAMBLING', '疑似赌博交易模型', 'MULTI_PARTY_AMT_MAX', '疑似赌博金额上限', '', '5000', '', 2, 'admin', '系统默认参数')
ON DUPLICATE KEY UPDATE
model_name = VALUES(model_name),
param_name = VALUES(param_name),
param_desc = VALUES(param_desc),
param_value = VALUES(param_value),
param_unit = VALUES(param_unit),
sort_order = VALUES(sort_order),
update_by = 'system',
update_time = NOW(),
remark = VALUES(remark);
COMMIT;