修复流水明细时间金额筛选SQL问题」}{

This commit is contained in:
wkc
2026-03-11 10:06:17 +08:00
parent b69064b68d
commit 0de248a039
2 changed files with 72 additions and 4 deletions

View File

@@ -156,7 +156,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
AND IFNULL(bs.AMOUNT_DR, 0) > 0
</if>
<if test="query.transactionStartTime != null and query.transactionStartTime != ''">
AND <include refid="parsedTrxDateExpr"/> <![CDATA[ >= ]]>
AND (<include refid="parsedTrxDateExpr"/>) <![CDATA[ >= ]]>
CASE
WHEN LENGTH(TRIM(#{query.transactionStartTime})) = 10
THEN STR_TO_DATE(CONCAT(TRIM(#{query.transactionStartTime}), ' 00:00:00'), '%Y-%m-%d %H:%i:%s')
@@ -164,7 +164,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
END
</if>
<if test="query.transactionEndTime != null and query.transactionEndTime != ''">
AND <include refid="parsedTrxDateExpr"/> <![CDATA[ <= ]]>
AND (<include refid="parsedTrxDateExpr"/>) <![CDATA[ <= ]]>
CASE
WHEN LENGTH(TRIM(#{query.transactionEndTime})) = 10
THEN STR_TO_DATE(CONCAT(TRIM(#{query.transactionEndTime}), ' 23:59:59'), '%Y-%m-%d %H:%i:%s')
@@ -216,10 +216,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</foreach>
</if>
<if test="query.amountMin != null">
AND <include refid="absoluteAmountExpr"/> <![CDATA[ >= ]]> #{query.amountMin}
AND (<include refid="absoluteAmountExpr"/>) <![CDATA[ >= ]]> #{query.amountMin}
</if>
<if test="query.amountMax != null">
AND <include refid="absoluteAmountExpr"/> <![CDATA[ <= ]]> #{query.amountMax}
AND (<include refid="absoluteAmountExpr"/>) <![CDATA[ <= ]]> #{query.amountMax}
</if>
<if test="(query.counterpartyAccount != null and query.counterpartyAccount != '') or query.counterpartyAccountEmpty">
AND (

View File

@@ -69,6 +69,74 @@ class CcdiBankStatementMapperXmlTest {
}
}
@Test
void statementFilterWhere_shouldWrapIncludedCaseExpressionsToAvoidAndCaseCollision() throws Exception {
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
String xml = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
assertTrue(xml.contains("AND (<include refid=\"parsedTrxDateExpr\"/>) <![CDATA[ >= ]]>"), xml);
assertTrue(xml.contains("AND (<include refid=\"parsedTrxDateExpr\"/>) <![CDATA[ <= ]]>"), xml);
assertTrue(xml.contains("AND (<include refid=\"absoluteAmountExpr\"/>) <![CDATA[ >= ]]>"), xml);
assertTrue(xml.contains("AND (<include refid=\"absoluteAmountExpr\"/>) <![CDATA[ <= ]]>"), xml);
}
}
@Test
void selectStatementPage_shouldKeepWhitespaceBeforeDateRangeExpressions() throws Exception {
MappedStatement mappedStatement = loadMappedStatement(
"com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper.selectStatementPage");
CcdiBankStatementQueryDTO queryDTO = new CcdiBankStatementQueryDTO();
queryDTO.setProjectId(33L);
queryDTO.setTransactionStartTime("2024-01-01 00:00:00");
queryDTO.setTransactionEndTime("2024-01-31 23:59:59");
String sql = renderSql(mappedStatement, queryDTO);
assertFalse(sql.contains("ANDCASE"), sql);
assertTrue(sql.contains("AND ( CASE WHEN bs.TRX_DATE"), sql);
assertTrue(sql.contains("END ) >="), sql);
assertTrue(sql.contains("END ) <="), sql);
}
@Test
void selectStatementPage_shouldKeepWhitespaceBeforeAmountRangeExpressions() throws Exception {
MappedStatement mappedStatement = loadMappedStatement(
"com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper.selectStatementPage");
CcdiBankStatementQueryDTO queryDTO = new CcdiBankStatementQueryDTO();
queryDTO.setProjectId(33L);
queryDTO.setAmountMin(java.math.BigDecimal.ONE);
queryDTO.setAmountMax(new java.math.BigDecimal("100"));
String sql = renderSql(mappedStatement, queryDTO);
assertFalse(sql.contains("ANDCASE"), sql);
assertTrue(sql.contains("AND ( CASE WHEN IFNULL(bs.AMOUNT_CR, 0) > 0"), sql);
assertTrue(sql.contains("END ) >= ?"), sql);
assertTrue(sql.contains("END ) <= ?"), 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(CcdiBankStatementMapper.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, CcdiBankStatementQueryDTO queryDTO) {
Map<String, Object> params = new HashMap<>();
params.put("query", queryDTO);
BoundSql boundSql = mappedStatement.getBoundSql(params);
return boundSql.getSql().replaceAll("\\s+", " ").trim();
}
private void registerTypeAliases(TypeAliasRegistry typeAliasRegistry) {
typeAliasRegistry.registerAlias("map", Map.class);
}