Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/yudao-cloud
commit
e7ac652a9c
|
|
@ -89,6 +89,7 @@
|
||||||
<jimureport.version>2.3.2</jimureport.version>
|
<jimureport.version>2.3.2</jimureport.version>
|
||||||
<jimubi.version>2.3.2</jimubi.version>
|
<jimubi.version>2.3.2</jimubi.version>
|
||||||
<weixin-java.version>4.8.2-20260501.180637</weixin-java.version>
|
<weixin-java.version>4.8.2-20260501.180637</weixin-java.version>
|
||||||
|
<bouncycastle.version>1.80</bouncycastle.version>
|
||||||
<alipay-sdk-java.version>4.40.771.ALL</alipay-sdk-java.version>
|
<alipay-sdk-java.version>4.40.771.ALL</alipay-sdk-java.version>
|
||||||
<!-- 专属于 JDK8 安全漏洞升级 -->
|
<!-- 专属于 JDK8 安全漏洞升级 -->
|
||||||
<logback.version>1.2.13</logback.version> <!-- 无法使用 1.3.X 版本,启动会报错 -->
|
<logback.version>1.2.13</logback.version> <!-- 无法使用 1.3.X 版本,启动会报错 -->
|
||||||
|
|
@ -735,6 +736,24 @@
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 锁定 weixin-java 传递依赖,避免 Maven 版本范围自动升级到 1.80.2 后 Fat Jar 启动失败。
|
||||||
|
反馈:https://t.zsxq.com/pCVBo -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcprov-jdk18on</artifactId>
|
||||||
|
<version>${bouncycastle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcutil-jdk18on</artifactId>
|
||||||
|
<version>${bouncycastle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcpkix-jdk18on</artifactId>
|
||||||
|
<version>${bouncycastle.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.binarywang</groupId>
|
<groupId>com.github.binarywang</groupId>
|
||||||
<artifactId>weixin-java-pay</artifactId>
|
<artifactId>weixin-java-pay</artifactId>
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,13 @@
|
||||||
<groupId>com.fhs-opensource</groupId>
|
<groupId>com.fhs-opensource</groupId>
|
||||||
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
<artifactId>easy-trans-mybatis-plus-extend</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Test 测试相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import net.sf.jsqlparser.schema.Table;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MyBatis 工具类
|
* MyBatis 工具类
|
||||||
|
|
@ -31,6 +32,8 @@ public class MyBatisUtils {
|
||||||
|
|
||||||
private static final String MYSQL_ESCAPE_CHARACTER = "`";
|
private static final String MYSQL_ESCAPE_CHARACTER = "`";
|
||||||
|
|
||||||
|
private static final Pattern SAFE_COLUMN_NAME_PATTERN = Pattern.compile("^[a-zA-Z0-9_]+(\\.[a-zA-Z0-9_]+)*$");
|
||||||
|
|
||||||
public static <T> Page<T> buildPage(PageParam pageParam) {
|
public static <T> Page<T> buildPage(PageParam pageParam) {
|
||||||
return buildPage(pageParam, null);
|
return buildPage(pageParam, null);
|
||||||
}
|
}
|
||||||
|
|
@ -42,8 +45,11 @@ public class MyBatisUtils {
|
||||||
// 排序字段
|
// 排序字段
|
||||||
if (CollUtil.isNotEmpty(sortingFields)) {
|
if (CollUtil.isNotEmpty(sortingFields)) {
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
page.addOrder(new OrderItem().setAsc(SortingField.ORDER_ASC.equals(sortingField.getOrder()))
|
String columnName = buildSafeOrderColumn(sortingField.getField());
|
||||||
.setColumn(StrUtil.toUnderlineCase(sortingField.getField())));
|
if (columnName == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
page.addOrder(new OrderItem().setAsc(isAscOrder(sortingField.getOrder())).setColumn(columnName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
|
|
@ -57,23 +63,29 @@ public class MyBatisUtils {
|
||||||
if (wrapper instanceof QueryWrapper) {
|
if (wrapper instanceof QueryWrapper) {
|
||||||
QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
|
QueryWrapper<T> query = (QueryWrapper<T>) wrapper;
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
query.orderBy(true,
|
String columnName = buildSafeOrderColumn(sortingField.getField());
|
||||||
SortingField.ORDER_ASC.equals(sortingField.getOrder()),
|
if (columnName == null) {
|
||||||
StrUtil.toUnderlineCase(sortingField.getField()));
|
continue;
|
||||||
|
}
|
||||||
|
query.orderBy(true, isAscOrder(sortingField.getOrder()), columnName);
|
||||||
}
|
}
|
||||||
} else if (wrapper instanceof LambdaQueryWrapper) {
|
} else if (wrapper instanceof LambdaQueryWrapper) {
|
||||||
// LambdaQueryWrapper 不直接支持字符串字段排序,使用 last 方法拼接 ORDER BY
|
// LambdaQueryWrapper 不直接支持字符串字段排序,使用 last 方法拼接 ORDER BY
|
||||||
LambdaQueryWrapper<T> lambdaQuery = (LambdaQueryWrapper<T>) wrapper;
|
LambdaQueryWrapper<T> lambdaQuery = (LambdaQueryWrapper<T>) wrapper;
|
||||||
StringBuilder orderBy = new StringBuilder();
|
StringBuilder orderBy = new StringBuilder();
|
||||||
for (SortingField sortingField : sortingFields) {
|
for (SortingField sortingField : sortingFields) {
|
||||||
|
String columnName = buildSafeOrderColumn(sortingField.getField());
|
||||||
|
if (columnName == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (StrUtil.isNotEmpty(orderBy)) {
|
if (StrUtil.isNotEmpty(orderBy)) {
|
||||||
orderBy.append(", ");
|
orderBy.append(", ");
|
||||||
}
|
}
|
||||||
orderBy.append(StrUtil.toUnderlineCase(sortingField.getField()))
|
orderBy.append(columnName).append(" ").append(getOrderDirection(sortingField.getOrder()));
|
||||||
.append(" ")
|
}
|
||||||
.append(SortingField.ORDER_ASC.equals(sortingField.getOrder()) ? "ASC" : "DESC");
|
if (StrUtil.isNotEmpty(orderBy)) {
|
||||||
|
lambdaQuery.last("ORDER BY " + orderBy);
|
||||||
}
|
}
|
||||||
lambdaQuery.last("ORDER BY " + orderBy);
|
|
||||||
// 另外个思路:https://blog.csdn.net/m0_59084856/article/details/138450913
|
// 另外个思路:https://blog.csdn.net/m0_59084856/article/details/138450913
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported wrapper type: " + wrapper.getClass().getName());
|
throw new IllegalArgumentException("Unsupported wrapper type: " + wrapper.getClass().getName());
|
||||||
|
|
@ -81,6 +93,22 @@ public class MyBatisUtils {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isAscOrder(String order) {
|
||||||
|
return SortingField.ORDER_ASC.equals(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getOrderDirection(String order) {
|
||||||
|
return isAscOrder(order) ? "ASC" : "DESC";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildSafeOrderColumn(String field) {
|
||||||
|
String columnName = StrUtil.toUnderlineCase(field);
|
||||||
|
if (StrUtil.isEmpty(columnName) || !SAFE_COLUMN_NAME_PATTERN.matcher(columnName).matches()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return columnName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将拦截器添加到链中
|
* 将拦截器添加到链中
|
||||||
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
* 由于 MybatisPlusInterceptor 不支持添加拦截器,所以只能全量设置
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
package cn.iocoder.yudao.framework.mybatis.core.util;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.SortingField;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.OrderItem;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link MyBatisUtils} 的单元测试
|
||||||
|
*/
|
||||||
|
public class MyBatisUtilsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBuildPage_sortingFields() {
|
||||||
|
// 准备参数
|
||||||
|
PageParam pageParam = new PageParam();
|
||||||
|
pageParam.setPageNo(2);
|
||||||
|
pageParam.setPageSize(20);
|
||||||
|
List<SortingField> sortingFields = Arrays.asList(
|
||||||
|
new SortingField("userName", SortingField.ORDER_ASC),
|
||||||
|
new SortingField("u.id", SortingField.ORDER_DESC),
|
||||||
|
new SortingField("name desc", SortingField.ORDER_DESC));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Page<Object> page = MyBatisUtils.buildPage(pageParam, sortingFields);
|
||||||
|
|
||||||
|
// 断言
|
||||||
|
assertEquals(2, page.getCurrent());
|
||||||
|
assertEquals(20, page.getSize());
|
||||||
|
assertEquals(2, page.orders().size());
|
||||||
|
assertOrderItem(page.orders().get(0), "user_name", true);
|
||||||
|
assertOrderItem(page.orders().get(1), "u.id", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddOrder_queryWrapper() {
|
||||||
|
// 准备参数
|
||||||
|
QueryWrapper<Object> query = new QueryWrapper<>();
|
||||||
|
List<SortingField> sortingFields = Arrays.asList(
|
||||||
|
new SortingField("userName", SortingField.ORDER_ASC),
|
||||||
|
new SortingField("u.id", SortingField.ORDER_DESC),
|
||||||
|
new SortingField("name;drop", SortingField.ORDER_ASC));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
MyBatisUtils.addOrder(query, sortingFields);
|
||||||
|
|
||||||
|
// 断言
|
||||||
|
assertEquals(" ORDER BY user_name ASC,u.id DESC", query.getSqlSegment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddOrder_lambdaQueryWrapper() {
|
||||||
|
// 准备参数
|
||||||
|
LambdaQueryWrapper<Object> query = new LambdaQueryWrapper<>();
|
||||||
|
List<SortingField> sortingFields = Arrays.asList(
|
||||||
|
new SortingField("userName", SortingField.ORDER_ASC),
|
||||||
|
new SortingField("u.id", SortingField.ORDER_DESC),
|
||||||
|
new SortingField("name`", SortingField.ORDER_ASC));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
MyBatisUtils.addOrder(query, sortingFields);
|
||||||
|
|
||||||
|
// 断言
|
||||||
|
assertEquals(" ORDER BY user_name ASC, u.id DESC", query.getSqlSegment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddOrder_lambdaQueryWrapper_invalidSortingFields() {
|
||||||
|
// 准备参数
|
||||||
|
LambdaQueryWrapper<Object> query = new LambdaQueryWrapper<>();
|
||||||
|
List<SortingField> sortingFields = Arrays.asList(
|
||||||
|
new SortingField("name desc", SortingField.ORDER_ASC),
|
||||||
|
new SortingField("name;drop", SortingField.ORDER_DESC));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
MyBatisUtils.addOrder(query, sortingFields);
|
||||||
|
|
||||||
|
// 断言
|
||||||
|
assertEquals("", query.getSqlSegment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOrderDirection() {
|
||||||
|
assertTrue(MyBatisUtils.isAscOrder(SortingField.ORDER_ASC));
|
||||||
|
assertFalse(MyBatisUtils.isAscOrder(SortingField.ORDER_DESC));
|
||||||
|
assertEquals("ASC", MyBatisUtils.getOrderDirection(SortingField.ORDER_ASC));
|
||||||
|
assertEquals("DESC", MyBatisUtils.getOrderDirection(SortingField.ORDER_DESC));
|
||||||
|
assertEquals("DESC", MyBatisUtils.getOrderDirection(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertOrderItem(OrderItem orderItem, String column, boolean asc) {
|
||||||
|
assertEquals(column, orderItem.getColumn());
|
||||||
|
assertEquals(asc, orderItem.isAsc());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -69,7 +69,7 @@ public class ApiAccessLogFilter extends ApiRequestFilter {
|
||||||
LocalDateTime beginTime = LocalDateTime.now();
|
LocalDateTime beginTime = LocalDateTime.now();
|
||||||
// 提前获得参数,避免 XssFilter 过滤处理
|
// 提前获得参数,避免 XssFilter 过滤处理
|
||||||
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
||||||
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
|
String requestBody = ServletUtils.getBody(request);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 继续过滤器
|
// 继续过滤器
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class ApiAccessLogInterceptor implements HandlerInterceptor {
|
||||||
// 打印 request 日志
|
// 打印 request 日志
|
||||||
if (!SpringUtils.isProd()) {
|
if (!SpringUtils.isProd()) {
|
||||||
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
Map<String, String> queryString = ServletUtils.getParamMap(request);
|
||||||
String requestBody = ServletUtils.isJsonRequest(request) ? ServletUtils.getBody(request) : null;
|
String requestBody = ServletUtils.getBody(request);
|
||||||
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
|
if (CollUtil.isEmpty(queryString) && StrUtil.isEmpty(requestBody)) {
|
||||||
log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
|
log.info("[preHandle][开始请求 URL({}) 无参数]", request.getRequestURI());
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,19 @@
|
||||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
|
<mapper namespace="cn.iocoder.yudao.module.trade.dal.mysql.brokerage.BrokerageUserMapper">
|
||||||
|
|
||||||
|
<sql id="OrderDirection">
|
||||||
|
<choose>
|
||||||
|
<when test="@cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils@isAscOrder(sortingField.order)">
|
||||||
|
ASC
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
DESC
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</sql>
|
||||||
|
|
||||||
<select id="selectSummaryPageByUserId"
|
<select id="selectSummaryPageByUserId"
|
||||||
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
resultType="cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.AppBrokerageUserChildSummaryRespVO">
|
||||||
|
|
||||||
SELECT bu.id, bu.bind_user_time AS brokerageTime,
|
SELECT bu.id, bu.bind_user_time AS brokerageTime,
|
||||||
(SELECT SUM(price) FROM trade_brokerage_record r
|
(SELECT SUM(price) FROM trade_brokerage_record r
|
||||||
WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice,
|
WHERE r.user_id = bu.id AND biz_type = #{bizType} AND r.status = #{status} AND r.deleted = FALSE) AS brokeragePrice,
|
||||||
|
|
@ -23,14 +33,17 @@
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
<choose>
|
<choose>
|
||||||
<when test="sortingField.field == 'userCount'">
|
<when test="sortingField != null and sortingField.field == 'userCount'">
|
||||||
ORDER BY brokerageUserCount ${sortingField.order}
|
ORDER BY brokerageUserCount
|
||||||
|
<include refid="OrderDirection"/>
|
||||||
</when>
|
</when>
|
||||||
<when test="sortingField.field == 'orderCount'">
|
<when test="sortingField != null and sortingField.field == 'orderCount'">
|
||||||
ORDER BY brokerageOrderCount ${sortingField.order}
|
ORDER BY brokerageOrderCount
|
||||||
|
<include refid="OrderDirection"/>
|
||||||
</when>
|
</when>
|
||||||
<when test="sortingField.field == 'price'">
|
<when test="sortingField != null and sortingField.field == 'price'">
|
||||||
ORDER BY brokeragePrice ${sortingField.order}
|
ORDER BY brokeragePrice
|
||||||
|
<include refid="OrderDirection"/>
|
||||||
</when>
|
</when>
|
||||||
<otherwise>
|
<otherwise>
|
||||||
ORDER BY bu.bind_user_time DESC
|
ORDER BY bu.bind_user_time DESC
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,7 @@ public class MemberUserController {
|
||||||
}
|
}
|
||||||
MemberUserRespVO userVO = MemberUserConvert.INSTANCE.convert03(user);
|
MemberUserRespVO userVO = MemberUserConvert.INSTANCE.convert03(user);
|
||||||
if (user.getLevelId() != null) {
|
if (user.getLevelId() != null) {
|
||||||
MemberLevelDO level = memberLevelService.getLevel(userVO.getId());
|
MemberLevelDO level = memberLevelService.getLevel(userVO.getLevelId());
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
userVO.setLevelName(level.getName());
|
userVO.setLevelName(level.getName());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue