mirror of
				https://github.com/continew-org/continew-starter.git
				synced 2025-10-31 10:57:15 +08:00 
			
		
		
		
	refactor(curd): 重构排序字段处理,预防 SQL 注入问题
This commit is contained in:
		| @@ -24,6 +24,12 @@ | ||||
|             <artifactId>spring-data-commons</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Web 模块 --> | ||||
|         <dependency> | ||||
|             <groupId>top.continew</groupId> | ||||
|             <artifactId>continew-starter-web</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- 认证模块 - SaToken --> | ||||
|         <dependency> | ||||
|             <groupId>top.continew</groupId> | ||||
| @@ -36,16 +42,16 @@ | ||||
|             </exclusions> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- 数据访问模块 - 核心模块 --> | ||||
|         <dependency> | ||||
|             <groupId>top.continew</groupId> | ||||
|             <artifactId>continew-starter-data-core</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- 文件处理模块 - Excel --> | ||||
|         <dependency> | ||||
|             <groupId>top.continew</groupId> | ||||
|             <artifactId>continew-starter-file-excel</artifactId> | ||||
|         </dependency> | ||||
|  | ||||
|         <!-- Web 模块 --> | ||||
|         <dependency> | ||||
|             <groupId>top.continew</groupId> | ||||
|             <artifactId>continew-starter-web</artifactId> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| </project> | ||||
| @@ -21,6 +21,8 @@ import cn.hutool.core.util.ArrayUtil; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import org.springframework.data.domain.Sort; | ||||
| import top.continew.starter.core.constant.StringConstants; | ||||
| import top.continew.starter.core.util.validate.ValidationUtils; | ||||
| import top.continew.starter.data.core.util.SqlInjectionUtils; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| @@ -54,20 +56,17 @@ public class SortQuery implements Serializable { | ||||
|         if (ArrayUtil.isEmpty(sort)) { | ||||
|             return Sort.unsorted(); | ||||
|         } | ||||
|  | ||||
|         ValidationUtils.throwIf(sort.length < 2, "排序条件非法"); | ||||
|         List<Sort.Order> orders = new ArrayList<>(sort.length); | ||||
|         if (CharSequenceUtil.contains(sort[0], StringConstants.COMMA)) { | ||||
|             // e.g "sort=createTime,desc&sort=name,asc" | ||||
|             for (String s : sort) { | ||||
|                 List<String> sortList = CharSequenceUtil.splitTrim(s, StringConstants.COMMA); | ||||
|                 Sort.Order order = new Sort.Order(Sort.Direction.valueOf(sortList.get(1).toUpperCase()), sortList | ||||
|                     .get(0)); | ||||
|                 orders.add(order); | ||||
|                 orders.add(this.getOrder(sortList.get(0), sortList.get(1))); | ||||
|             } | ||||
|         } else { | ||||
|             // e.g "sort=createTime,desc" | ||||
|             Sort.Order order = new Sort.Order(Sort.Direction.valueOf(sort[1].toUpperCase()), sort[0]); | ||||
|             orders.add(order); | ||||
|             orders.add(this.getOrder(sort[0], sort[1])); | ||||
|         } | ||||
|         return Sort.by(orders); | ||||
|     } | ||||
| @@ -75,4 +74,16 @@ public class SortQuery implements Serializable { | ||||
|     public void setSort(String[] sort) { | ||||
|         this.sort = sort; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取排序条件 | ||||
|      * | ||||
|      * @param field     字段 | ||||
|      * @param direction 排序方向 | ||||
|      * @return 排序条件 | ||||
|      */ | ||||
|     private Sort.Order getOrder(String field, String direction) { | ||||
|         ValidationUtils.throwIf(SqlInjectionUtils.check(field), "排序字段包含非法字符"); | ||||
|         return new Sort.Order(Sort.Direction.valueOf(direction.toUpperCase()), field); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,73 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.continew.starter.extension.crud.model.resp; | ||||
|  | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 分页信息 | ||||
|  * | ||||
|  * @param <T> 列表数据类型 | ||||
|  * @author Charles7c | ||||
|  * @since 2.5.2 | ||||
|  */ | ||||
| @Schema(description = "分页信息") | ||||
| public class BasePageResp<T> implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 列表数据 | ||||
|      */ | ||||
|     @Schema(description = "列表数据") | ||||
|     private List<T> list; | ||||
|  | ||||
|     /** | ||||
|      * 总记录数 | ||||
|      */ | ||||
|     @Schema(description = "总记录数", example = "10") | ||||
|     private long total; | ||||
|  | ||||
|     public BasePageResp() { | ||||
|     } | ||||
|  | ||||
|     public BasePageResp(final List<T> list, final long total) { | ||||
|         this.list = list; | ||||
|         this.total = total; | ||||
|     } | ||||
|  | ||||
|     public List<T> getList() { | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
|     public void setList(List<T> list) { | ||||
|         this.list = list; | ||||
|     } | ||||
|  | ||||
|     public long getTotal() { | ||||
|         return total; | ||||
|     } | ||||
|  | ||||
|     public void setTotal(long total) { | ||||
|         this.total = total; | ||||
|     } | ||||
| } | ||||
| @@ -22,7 +22,6 @@ import com.mybatisflex.core.paginate.Page; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
| @@ -35,22 +34,17 @@ import java.util.List; | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| @Schema(description = "分页信息") | ||||
| public class PageResp<L> implements Serializable { | ||||
| public class PageResp<L> extends BasePageResp<L> { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 列表数据 | ||||
|      */ | ||||
|     @Schema(description = "列表数据") | ||||
|     private List<L> list; | ||||
|     public PageResp() { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 总记录数 | ||||
|      */ | ||||
|     @Schema(description = "总记录数", example = "10") | ||||
|     private long total; | ||||
|     public PageResp(final List<L> list, final long total) { | ||||
|         super(list, total); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 基于 MyBatis Plus 分页数据构建分页信息,并将源数据转换为指定类型数据 | ||||
| @@ -65,10 +59,7 @@ public class PageResp<L> implements Serializable { | ||||
|         if (null == page) { | ||||
|             return empty(); | ||||
|         } | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(BeanUtil.copyToList(page.getRecords(), targetClass)); | ||||
|         pageResp.setTotal(page.getTotalRow()); | ||||
|         return pageResp; | ||||
|         return new PageResp<>(BeanUtil.copyToList(page.getRecords(), targetClass), page.getTotalRow()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -82,10 +73,7 @@ public class PageResp<L> implements Serializable { | ||||
|         if (null == page) { | ||||
|             return empty(); | ||||
|         } | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(page.getRecords()); | ||||
|         pageResp.setTotal(page.getTotalRow()); | ||||
|         return pageResp; | ||||
|         return new PageResp<>(page.getRecords(), page.getTotalRow()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -123,24 +111,6 @@ public class PageResp<L> implements Serializable { | ||||
|      * @return 分页信息 | ||||
|      */ | ||||
|     private static <L> PageResp<L> empty() { | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(Collections.emptyList()); | ||||
|         return pageResp; | ||||
|     } | ||||
|  | ||||
|     public List<L> getList() { | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
|     public void setList(List<L> list) { | ||||
|         this.list = list; | ||||
|     } | ||||
|  | ||||
|     public long getTotal() { | ||||
|         return total; | ||||
|     } | ||||
|  | ||||
|     public void setTotal(long total) { | ||||
|         this.total = total; | ||||
|         return new PageResp<>(Collections.emptyList(), 0L); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,7 +20,6 @@ import cn.crane4j.core.support.OperateTemplate; | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.bean.copier.CopyOptions; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.lang.Opt; | ||||
| import cn.hutool.core.lang.tree.Tree; | ||||
| import cn.hutool.core.lang.tree.TreeNodeConfig; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| @@ -35,7 +34,7 @@ import top.continew.starter.core.constant.StringConstants; | ||||
| import top.continew.starter.core.util.ReflectUtils; | ||||
| import top.continew.starter.core.util.validate.ValidationUtils; | ||||
| import top.continew.starter.data.mybatis.flex.base.BaseMapper; | ||||
| import top.continew.starter.data.mybatis.flex.query.QueryWrapperHelper; | ||||
| import top.continew.starter.data.mybatis.flex.util.QueryWrapperHelper; | ||||
| import top.continew.starter.data.mybatis.flex.service.impl.ServiceImpl; | ||||
| import top.continew.starter.extension.crud.annotation.TreeField; | ||||
| import top.continew.starter.extension.crud.model.query.PageQuery; | ||||
| @@ -73,6 +72,7 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdD | ||||
|     @Override | ||||
|     public PageResp<L> page(Q query, PageQuery pageQuery) { | ||||
|         QueryWrapper queryWrapper = this.buildQueryWrapper(query); | ||||
|         this.sort(queryWrapper, pageQuery); | ||||
|         Page<T> page = mapper.paginate(pageQuery.getPage(), pageQuery.getSize(), queryWrapper); | ||||
|         PageResp<L> pageResp = PageResp.build(page, listClass); | ||||
|         pageResp.getList().forEach(this::fill); | ||||
| @@ -185,12 +185,12 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdD | ||||
|      * @param sortQuery    排序查询条件 | ||||
|      */ | ||||
|     protected void sort(QueryWrapper queryWrapper, SortQuery sortQuery) { | ||||
|         Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort(); | ||||
|         if (sortQuery == null || sortQuery.getSort().isUnsorted()) { | ||||
|             return; | ||||
|         } | ||||
|         Sort sort = sortQuery.getSort(); | ||||
|         List<Field> entityFields = ReflectUtils.getNonStaticFields(this.entityClass); | ||||
|         for (Sort.Order order : sort) { | ||||
|             if (null == order) { | ||||
|                 continue; | ||||
|             } | ||||
|             String property = order.getProperty(); | ||||
|             String checkProperty; | ||||
|             // 携带表别名则获取 . 后面的字段名 | ||||
|   | ||||
| @@ -1,102 +0,0 @@ | ||||
| /* | ||||
|  * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. | ||||
|  * <p> | ||||
|  * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * <p> | ||||
|  * http://www.gnu.org/licenses/lgpl.html | ||||
|  * <p> | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| package top.continew.starter.extension.crud.model.query; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.core.metadata.OrderItem; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
| import jakarta.validation.constraints.Min; | ||||
| import org.hibernate.validator.constraints.Range; | ||||
| import org.springdoc.core.annotations.ParameterObject; | ||||
| import org.springframework.data.domain.Sort; | ||||
|  | ||||
| import java.io.Serial; | ||||
|  | ||||
| /** | ||||
|  * 分页查询条件 | ||||
|  * | ||||
|  * @author Charles7c | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| @ParameterObject | ||||
| @Schema(description = "分页查询条件") | ||||
| public class PageQuery extends SortQuery { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|     /** | ||||
|      * 默认页码:1 | ||||
|      */ | ||||
|     private static final int DEFAULT_PAGE = 1; | ||||
|     /** | ||||
|      * 默认每页条数:10 | ||||
|      */ | ||||
|     private static final int DEFAULT_SIZE = 10; | ||||
|  | ||||
|     /** | ||||
|      * 页码 | ||||
|      */ | ||||
|     @Schema(description = "页码", example = "1") | ||||
|     @Min(value = 1, message = "页码最小值为 {value}") | ||||
|     private Integer page = DEFAULT_PAGE; | ||||
|  | ||||
|     /** | ||||
|      * 每页条数 | ||||
|      */ | ||||
|     @Schema(description = "每页条数", example = "10") | ||||
|     @Range(min = 1, max = 1000, message = "每页条数(取值范围 {min}-{max})") | ||||
|     private Integer size = DEFAULT_SIZE; | ||||
|  | ||||
|     /** | ||||
|      * 基于分页查询条件转换为 MyBatis Plus 分页条件 | ||||
|      * | ||||
|      * @param <T> 列表数据类型 | ||||
|      * @return MyBatis Plus 分页条件 | ||||
|      */ | ||||
|     public <T> IPage<T> toPage() { | ||||
|         Page<T> mybatisPage = new Page<>(this.getPage(), this.getSize()); | ||||
|         Sort pageSort = this.getSort(); | ||||
|         if (CollUtil.isNotEmpty(pageSort)) { | ||||
|             for (Sort.Order order : pageSort) { | ||||
|                 OrderItem orderItem = new OrderItem(); | ||||
|                 orderItem.setAsc(order.isAscending()); | ||||
|                 orderItem.setColumn(CharSequenceUtil.toUnderlineCase(order.getProperty())); | ||||
|                 mybatisPage.addOrder(orderItem); | ||||
|             } | ||||
|         } | ||||
|         return mybatisPage; | ||||
|     } | ||||
|  | ||||
|     public Integer getPage() { | ||||
|         return page; | ||||
|     } | ||||
|  | ||||
|     public void setPage(Integer page) { | ||||
|         this.page = page; | ||||
|     } | ||||
|  | ||||
|     public Integer getSize() { | ||||
|         return size; | ||||
|     } | ||||
|  | ||||
|     public void setSize(Integer size) { | ||||
|         this.size = size; | ||||
|     } | ||||
| } | ||||
| @@ -22,8 +22,8 @@ import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import io.swagger.v3.oas.annotations.media.Schema; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Collections; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
| @@ -34,22 +34,17 @@ import java.util.List; | ||||
|  * @since 1.0.0 | ||||
|  */ | ||||
| @Schema(description = "分页信息") | ||||
| public class PageResp<L> implements Serializable { | ||||
| public class PageResp<L> extends BasePageResp<L> { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     /** | ||||
|      * 列表数据 | ||||
|      */ | ||||
|     @Schema(description = "列表数据") | ||||
|     private List<L> list; | ||||
|     public PageResp() { | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 总记录数 | ||||
|      */ | ||||
|     @Schema(description = "总记录数", example = "10") | ||||
|     private long total; | ||||
|     public PageResp(final List<L> list, final long total) { | ||||
|         super(list, total); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 基于 MyBatis Plus 分页数据构建分页信息,并将源数据转换为指定类型数据 | ||||
| @@ -64,10 +59,7 @@ public class PageResp<L> implements Serializable { | ||||
|         if (null == page) { | ||||
|             return empty(); | ||||
|         } | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(BeanUtil.copyToList(page.getRecords(), targetClass)); | ||||
|         pageResp.setTotal(page.getTotal()); | ||||
|         return pageResp; | ||||
|         return new PageResp<>(BeanUtil.copyToList(page.getRecords(), targetClass), page.getTotal()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -81,10 +73,7 @@ public class PageResp<L> implements Serializable { | ||||
|         if (null == page) { | ||||
|             return empty(); | ||||
|         } | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(page.getRecords()); | ||||
|         pageResp.setTotal(page.getTotal()); | ||||
|         return pageResp; | ||||
|         return new PageResp<>(page.getRecords(), page.getTotal()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -122,24 +111,6 @@ public class PageResp<L> implements Serializable { | ||||
|      * @return 分页信息 | ||||
|      */ | ||||
|     private static <L> PageResp<L> empty() { | ||||
|         PageResp<L> pageResp = new PageResp<>(); | ||||
|         pageResp.setList(new ArrayList<>(0)); | ||||
|         return pageResp; | ||||
|     } | ||||
|  | ||||
|     public List<L> getList() { | ||||
|         return list; | ||||
|     } | ||||
|  | ||||
|     public void setList(List<L> list) { | ||||
|         this.list = list; | ||||
|     } | ||||
|  | ||||
|     public long getTotal() { | ||||
|         return total; | ||||
|     } | ||||
|  | ||||
|     public void setTotal(long total) { | ||||
|         this.total = total; | ||||
|         return new PageResp<>(Collections.emptyList(), 0L); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,15 +20,15 @@ import cn.crane4j.core.support.OperateTemplate; | ||||
| import cn.hutool.core.bean.BeanUtil; | ||||
| import cn.hutool.core.bean.copier.CopyOptions; | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.lang.Opt; | ||||
| import cn.hutool.core.lang.tree.Tree; | ||||
| import cn.hutool.core.lang.tree.TreeNodeConfig; | ||||
| import cn.hutool.core.map.MapUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.hutool.core.text.CharSequenceUtil; | ||||
| import cn.hutool.core.util.ReflectUtil; | ||||
| import cn.hutool.extra.spring.SpringUtil; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import org.springframework.data.domain.Sort; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
| @@ -38,21 +38,24 @@ import top.continew.starter.core.util.ReflectUtils; | ||||
| import top.continew.starter.core.util.validate.CheckUtils; | ||||
| import top.continew.starter.core.util.validate.ValidationUtils; | ||||
| import top.continew.starter.data.mybatis.plus.base.BaseMapper; | ||||
| import top.continew.starter.data.mybatis.plus.query.QueryWrapperHelper; | ||||
| import top.continew.starter.data.mybatis.plus.service.impl.ServiceImpl; | ||||
| import top.continew.starter.data.mybatis.plus.util.QueryWrapperHelper; | ||||
| import top.continew.starter.extension.crud.annotation.DictField; | ||||
| import top.continew.starter.extension.crud.annotation.TreeField; | ||||
| import top.continew.starter.extension.crud.model.entity.BaseIdDO; | ||||
| import top.continew.starter.extension.crud.model.query.PageQuery; | ||||
| import top.continew.starter.extension.crud.model.query.SortQuery; | ||||
| import top.continew.starter.extension.crud.model.resp.LabelValueResp; | ||||
| import top.continew.starter.extension.crud.model.resp.PageResp; | ||||
| import top.continew.starter.extension.crud.service.BaseService; | ||||
| import top.continew.starter.extension.crud.util.TreeUtils; | ||||
| import top.continew.starter.extension.crud.model.query.PageQuery; | ||||
| import top.continew.starter.file.excel.util.ExcelUtils; | ||||
|  | ||||
| import java.lang.reflect.Field; | ||||
| import java.util.*; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Optional; | ||||
|  | ||||
| /** | ||||
|  * 业务实现基类 | ||||
| @@ -76,7 +79,8 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdD | ||||
|     @Override | ||||
|     public PageResp<L> page(Q query, PageQuery pageQuery) { | ||||
|         QueryWrapper<T> queryWrapper = this.buildQueryWrapper(query); | ||||
|         IPage<T> page = baseMapper.selectPage(pageQuery.toPage(), queryWrapper); | ||||
|         this.sort(queryWrapper, pageQuery); | ||||
|         IPage<T> page = baseMapper.selectPage(new Page<>(pageQuery.getPage(), pageQuery.getSize()), queryWrapper); | ||||
|         PageResp<L> pageResp = PageResp.build(page, this.getListClass()); | ||||
|         pageResp.getList().forEach(this::fill); | ||||
|         return pageResp; | ||||
| @@ -253,23 +257,24 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseIdD | ||||
|      * @param sortQuery    排序查询条件 | ||||
|      */ | ||||
|     protected void sort(QueryWrapper<T> queryWrapper, SortQuery sortQuery) { | ||||
|         Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort(); | ||||
|         if (sortQuery == null || sortQuery.getSort().isUnsorted()) { | ||||
|             return; | ||||
|         } | ||||
|         Sort sort = sortQuery.getSort(); | ||||
|         for (Sort.Order order : sort) { | ||||
|             if (null != order) { | ||||
|                 String property = order.getProperty(); | ||||
|                 String checkProperty; | ||||
|                 // 携带表别名则获取 . 后面的字段名 | ||||
|                 if (property.contains(StringConstants.DOT)) { | ||||
|                     checkProperty = CollUtil.getLast(CharSequenceUtil.split(property, StringConstants.DOT)); | ||||
|                 } else { | ||||
|                     checkProperty = property; | ||||
|                 } | ||||
|                 Optional<Field> optional = super.getEntityFields().stream() | ||||
|                     .filter(field -> checkProperty.equals(field.getName())) | ||||
|                     .findFirst(); | ||||
|                 ValidationUtils.throwIf(optional.isEmpty(), "无效的排序字段 [{}]", property); | ||||
|                 queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property)); | ||||
|             String property = order.getProperty(); | ||||
|             String checkProperty; | ||||
|             // 携带表别名则获取 . 后面的字段名 | ||||
|             if (property.contains(StringConstants.DOT)) { | ||||
|                 checkProperty = CollUtil.getLast(CharSequenceUtil.split(property, StringConstants.DOT)); | ||||
|             } else { | ||||
|                 checkProperty = property; | ||||
|             } | ||||
|             Optional<Field> optional = super.getEntityFields().stream() | ||||
|                 .filter(field -> checkProperty.equals(field.getName())) | ||||
|                 .findFirst(); | ||||
|             ValidationUtils.throwIf(optional.isEmpty(), "无效的排序字段 [{}]", property); | ||||
|             queryWrapper.orderBy(true, order.isAscending(), CharSequenceUtil.toUnderlineCase(property)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user