调整季度稳定收入参数并补充UTF8执行脚本
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
- 前端开发直接在当前分支进行,不需要额外创建 git worktree
|
- 前端开发直接在当前分支进行,不需要额外创建 git worktree
|
||||||
- 测试结束后,自动关闭测试过程中启动的前后端进程
|
- 测试结束后,自动关闭测试过程中启动的前后端进程
|
||||||
- 遇到 MCP 数据库操作时,使用项目配置文件中的数据库连接信息
|
- 遇到 MCP 数据库操作时,使用项目配置文件中的数据库连接信息
|
||||||
|
- 执行包含中文内容的 MySQL SQL 脚本时,禁止直接手写 `mysql -e` 或普通重定向执行;必须优先使用 `bin/mysql_utf8_exec.sh <sql-file>`,确保会话字符集为 `utf8mb4`,避免写入乱码
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -160,6 +161,7 @@ return AjaxResult.success(result);
|
|||||||
- 非业务字段如 `create_by`、`create_time` 由后端自动维护
|
- 非业务字段如 `create_by`、`create_time` 由后端自动维护
|
||||||
- 前端表单不要暴露通用审计字段
|
- 前端表单不要暴露通用审计字段
|
||||||
- 新增菜单、字典、初始化数据时,同步补充 SQL 脚本
|
- 新增菜单、字典、初始化数据时,同步补充 SQL 脚本
|
||||||
|
- 执行数据库脚本前,需确认客户端会话字符集为 `utf8mb4`;涉及中文插入、更新时默认使用 `bin/mysql_utf8_exec.sh`
|
||||||
|
|
||||||
### 前端规范
|
### 前端规范
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ id,project_id,model_code,model_name,param_code,param_name,param_desc,param_value
|
|||||||
6,0,LARGE_TRANSACTION,大额交易模型,FREQUENT_TRANSFER,单笔大额转账金额,单日转账次数超过,100001,次/日
|
6,0,LARGE_TRANSACTION,大额交易模型,FREQUENT_TRANSFER,单笔大额转账金额,单日转账次数超过,100001,次/日
|
||||||
,,,,,,,,
|
,,,,,,,,
|
||||||
7,0,SUSPICIOUS_PART_TIME,可疑兼职模型,MONTHLY_FIXED_INCOME,月度非本行工资收入金额,"除本行工资外,每月固定收入超过",5000,元/月
|
7,0,SUSPICIOUS_PART_TIME,可疑兼职模型,MONTHLY_FIXED_INCOME,月度非本行工资收入金额,"除本行工资外,每月固定收入超过",5000,元/月
|
||||||
8,0,SUSPICIOUS_PART_TIME,可疑兼职模型,FIXED_COUNTERPARTY_TRANSFER,季度稳定收入金额,每季从固定交易对手转入金额,15000,元/季
|
8,0,SUSPICIOUS_PART_TIME,可疑兼职模型,FIXED_COUNTERPARTY_TRANSFER_MIN,季度稳定收入金额下限,每季从固定交易对手转入金额下限,3000,元/季
|
||||||
|
9,0,SUSPICIOUS_PART_TIME,可疑兼职模型,FIXED_COUNTERPARTY_TRANSFER_MAX,季度稳定收入金额上限,每季从固定交易对手转入金额上限,15000,元/季
|
||||||
,,,,,,,,
|
,,,,,,,,
|
||||||
10,0,SUSPICIOUS_FOREIGN_EXCHANGE,可疑外汇交易模型,SINGLE_PURCHASE_AMOUNT,单笔购汇金额,单笔购汇超过该金额,50000,美元/笔
|
10,0,SUSPICIOUS_FOREIGN_EXCHANGE,可疑外汇交易模型,SINGLE_PURCHASE_AMOUNT,单笔购汇金额,单笔购汇超过该金额,50000,美元/笔
|
||||||
11,0,SUSPICIOUS_FOREIGN_EXCHANGE,可疑外汇交易模型,SINGLE_SETTLEMENT_AMOUNT,单笔结汇金额,单笔结汇超过该金额,50000,美元/笔
|
11,0,SUSPICIOUS_FOREIGN_EXCHANGE,可疑外汇交易模型,SINGLE_SETTLEMENT_AMOUNT,单笔结汇金额,单笔结汇超过该金额,50000,美元/笔
|
||||||
|
|||||||
|
55
bin/mysql_utf8_exec.sh
Executable file
55
bin/mysql_utf8_exec.sh
Executable file
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ "$#" -ne 1 ]; then
|
||||||
|
echo "Usage: bin/mysql_utf8_exec.sh <sql-file>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
APP_CONFIG="${PROJECT_ROOT}/ruoyi-admin/src/main/resources/application-dev.yml"
|
||||||
|
SQL_FILE_INPUT="$1"
|
||||||
|
|
||||||
|
if [ ! -f "${APP_CONFIG}" ]; then
|
||||||
|
echo "Config file not found: ${APP_CONFIG}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "${SQL_FILE_INPUT}" ]; then
|
||||||
|
echo "SQL file not found: ${SQL_FILE_INPUT}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v mysql >/dev/null 2>&1; then
|
||||||
|
echo "mysql command not found in PATH" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DB_URL="$(awk '/master:/{flag=1;next} flag && /url: jdbc:mysql:\/\//{sub(/.*url: /, ""); print; exit}' "${APP_CONFIG}")"
|
||||||
|
DB_USER="$(awk '/master:/{flag=1;next} flag && /username:/{sub(/.*username: /, ""); print; exit}' "${APP_CONFIG}")"
|
||||||
|
DB_PASS="$(awk '/master:/{flag=1;next} flag && /password:/{sub(/.*password: /, ""); print; exit}' "${APP_CONFIG}")"
|
||||||
|
|
||||||
|
if [ -z "${DB_URL}" ] || [ -z "${DB_USER}" ]; then
|
||||||
|
echo "Failed to parse database config from application-dev.yml" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
DB_URL_NO_PREFIX="${DB_URL#jdbc:mysql://}"
|
||||||
|
DB_HOST_PORT="${DB_URL_NO_PREFIX%%/*}"
|
||||||
|
DB_NAME="${DB_URL_NO_PREFIX#*/}"
|
||||||
|
DB_NAME="${DB_NAME%%\?*}"
|
||||||
|
|
||||||
|
DB_HOST="${DB_HOST_PORT%%:*}"
|
||||||
|
DB_PORT="${DB_HOST_PORT##*:}"
|
||||||
|
|
||||||
|
ABS_SQL_FILE="$(cd "$(dirname "${SQL_FILE_INPUT}")" && pwd)/$(basename "${SQL_FILE_INPUT}")"
|
||||||
|
|
||||||
|
MYSQL_PWD="${DB_PASS}" mysql \
|
||||||
|
-h "${DB_HOST}" \
|
||||||
|
-P "${DB_PORT}" \
|
||||||
|
-u "${DB_USER}" \
|
||||||
|
--default-character-set=utf8mb4 \
|
||||||
|
--init-command="SET NAMES utf8mb4" \
|
||||||
|
"${DB_NAME}" < "${ABS_SQL_FILE}"
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.ruoyi.ccdi.project.sql;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class CcdiModelParamSqlDefaultsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void defaultSql_shouldUseQuarterlyStableIncomeMinAndMaxParams() throws IOException {
|
||||||
|
String initSql = readProjectFile("sql", "ccdi_model_param.sql");
|
||||||
|
String updateSql = readProjectFile("sql", "2026-03-16-update-ccdi-model-param-defaults.sql");
|
||||||
|
|
||||||
|
assertQuarterlyStableIncomeRangeConfig(initSql);
|
||||||
|
assertQuarterlyStableIncomeRangeConfig(updateSql);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertQuarterlyStableIncomeRangeConfig(String sqlContent) {
|
||||||
|
assertAll(
|
||||||
|
() -> assertTrue(sqlContent.contains("FIXED_COUNTERPARTY_TRANSFER_MIN"),
|
||||||
|
"应包含季度稳定收入金额下限参数编码"),
|
||||||
|
() -> assertTrue(sqlContent.contains("FIXED_COUNTERPARTY_TRANSFER_MAX"),
|
||||||
|
"应包含季度稳定收入金额上限参数编码"),
|
||||||
|
() -> assertTrue(sqlContent.contains("季度稳定收入金额下限"),
|
||||||
|
"应包含季度稳定收入金额下限参数名称"),
|
||||||
|
() -> assertTrue(sqlContent.contains("季度稳定收入金额上限"),
|
||||||
|
"应包含季度稳定收入金额上限参数名称"),
|
||||||
|
() -> assertTrue(sqlContent.contains("'3000'"),
|
||||||
|
"应包含季度稳定收入金额下限默认值3000"),
|
||||||
|
() -> assertTrue(sqlContent.contains("'15000'"),
|
||||||
|
"应包含季度稳定收入金额上限默认值15000"),
|
||||||
|
() -> assertFalse(sqlContent.contains("'FIXED_COUNTERPARTY_TRANSFER'"),
|
||||||
|
"不应继续保留旧的单值季度稳定收入金额参数编码")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readProjectFile(String... parts) throws IOException {
|
||||||
|
Path path = Path.of("..", parts);
|
||||||
|
return Files.readString(path, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.ruoyi.ccdi.project.sql;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
class MysqlUtf8ExecScriptTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void mysqlUtf8ExecScript_shouldForceUtf8SessionAndSourceSqlFile() throws IOException {
|
||||||
|
String script = Files.readString(
|
||||||
|
Path.of("..", "bin", "mysql_utf8_exec.sh"),
|
||||||
|
StandardCharsets.UTF_8
|
||||||
|
);
|
||||||
|
|
||||||
|
assertAll(
|
||||||
|
() -> assertTrue(script.contains("application-dev.yml"),
|
||||||
|
"脚本应读取 application-dev.yml 中的数据库连接信息"),
|
||||||
|
() -> assertTrue(script.contains("--default-character-set=utf8mb4"),
|
||||||
|
"脚本应强制 mysql 客户端使用 utf8mb4"),
|
||||||
|
() -> assertTrue(script.contains("--init-command")
|
||||||
|
&& script.contains("SET NAMES utf8mb4"),
|
||||||
|
"脚本应在 mysql 会话初始化时显式执行 SET NAMES utf8mb4"),
|
||||||
|
() -> assertTrue(script.contains("< \"${ABS_SQL_FILE}\""),
|
||||||
|
"脚本应直接重定向 SQL 文件执行")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,8 @@ INSERT INTO ccdi_model_param (
|
|||||||
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '次', 5, 'admin', '系统默认参数'),
|
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '次', 5, 'admin', '系统默认参数'),
|
||||||
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
|
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'MONTHLY_FIXED_INCOME', '月度非本行工资收入金额', '除本行工资外,每月固定收入超过', '5000', '元/月', 1, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'MONTHLY_FIXED_INCOME', '月度非本行工资收入金额', '除本行工资外,每月固定收入超过', '5000', '元/月', 1, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'FIXED_COUNTERPARTY_TRANSFER', '季度稳定收入金额', '每季从固定交易对手转入金额', '15000', '元/季', 2, '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_PURCHASE_AMOUNT', '单笔购汇金额', '单笔购汇超过该金额', '50000', '美元/笔', 1, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ INSERT INTO ccdi_model_param (project_id, model_code, model_name, param_code, pa
|
|||||||
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '次', 5, 'admin', '系统默认参数'),
|
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_CASH_DEPOSIT', '单日多次存现次数', '24小时内累计存现超过', '5', '次', 5, 'admin', '系统默认参数'),
|
||||||
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
|
(0, 'LARGE_TRANSACTION', '大额交易模型', 'FREQUENT_TRANSFER', '单笔大额转账金额', '单日转账次数超过', '100001', '次/日', 6, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'MONTHLY_FIXED_INCOME', '月度非本行工资收入金额', '除本行工资外,每月固定收入超过', '5000', '元/月', 1, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'MONTHLY_FIXED_INCOME', '月度非本行工资收入金额', '除本行工资外,每月固定收入超过', '5000', '元/月', 1, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_PART_TIME', '可疑兼职模型', 'FIXED_COUNTERPARTY_TRANSFER', '季度稳定收入金额', '每季从固定交易对手转入金额', '15000', '元/季', 2, '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_PURCHASE_AMOUNT', '单笔购汇金额', '单笔购汇超过该金额', '50000', '美元/笔', 1, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'SINGLE_SETTLEMENT_AMOUNT', '单笔结汇金额', '单笔结汇超过该金额', '50000', '美元/笔', 2, 'admin', '系统默认参数'),
|
||||||
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
|
(0, 'SUSPICIOUS_FOREIGN_EXCHANGE', '可疑外汇交易模型', 'CROSS_BORDER_REMITTANCE', '跨境汇款金额', '跨境汇款金额超过', '200000', '美元/笔', 3, 'admin', '系统默认参数'),
|
||||||
|
|||||||
Reference in New Issue
Block a user