diff --git a/DB/version4.2.5toMASTER.sql b/DB/version4.2.5to4.3.sql similarity index 99% rename from DB/version4.2.5toMASTER.sql rename to DB/version4.2.5to4.3.sql index 8170a2c5b..adb7f16fe 100644 --- a/DB/version4.2.5toMASTER.sql +++ b/DB/version4.2.5to4.3.sql @@ -84,7 +84,7 @@ ALTER TABLE li_foot_print ADD `store_id` varchar(255) DEFAULT NULL COMMENT '店 /** - 订单增加自提信息 + 用户提现申请增加字段 */ ALTER TABLE li_member_withdraw_apply ADD `real_name` varchar(255) DEFAULT NULL; ALTER TABLE li_member_withdraw_apply ADD `connect_number` varchar(255) DEFAULT NULL; diff --git a/DB/version4.3toMASTER.sql b/DB/version4.3toMASTER.sql new file mode 100644 index 000000000..e69de29bb diff --git a/README.md b/README.md index a94031b2c..5052027eb 100644 --- a/README.md +++ b/README.md @@ -74,14 +74,36 @@ PS:手机验证码为 ‘111111’ #### 平台管理端功能 + -![平台管理端功能](https://static.pickmall.cn/images/other/managerList1.jpg) +| 模块 | 功能 | +|--------------------|-----------------------------------------------------------------| +| 首页 | 平台基础信息统计、待办事项 | +| 会员 | 会员列表、评价列表、积分历史、会员资金、会员充值 | +| 订单 | 商品订单、虚拟订单、订单售后、订单投诉、售后原因维护、收款流水、退款流水 | +| 商品 | 商品列表、商品审核、商品分类、商品品牌、商品规格、商品计量单位 | +| 促销 | 优惠券、券活动(每日&每月&每周&邀新 赠券)、秒杀活动、砍价活动、拼团活动、积分商品 | +| 店铺 | 店铺管理、店铺审核、店铺结算、店铺对账 | +| 运营 | 楼层装修、分销商管理、文章管理、意见反馈、站内信、短信、搜索热词管理 | +| 统计 | 会员统计、订单统计、流量统计、商品销量统计 | +| 设置 | 菜单管理、角色管理、部门管理、管理员管理、系统设置、行政地区管理、OSS管理、联合登陆、支付、物流公司、敏感词、验证码资源 | #### 卖家功能 -![商家端功能](https://static.pickmall.cn/images/other/storeList.jpg) + +| 模块 | 功能 | +|----|-------------------------------| +| 首页 | 店铺基础信息统计、待办事项、店铺公告 | +| 商品 | 商品发布、商品列表、商品模板、店铺分类 | +| 订单 | 商品订单、虚拟订单、订单评价、订单投诉、退款申请、退货申请 | +| 财务 | 店铺对账、店铺结算、发票管理 | +| 促销 | 优惠券、满额优惠、秒杀、拼团 、分销商品、分校订单 | +| 统计 |单统计、流量统计、商品销量统计 | + +| 设置 | 配送公司、物流模板、店铺设置、店铺自提设置、PC装修、移动端装修、店员管理、部门管理、角色管理 | +| 消息 | 站内信 | ### 商城前端功能展示 diff --git a/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java b/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java index bbe988eae..90bf661fe 100644 --- a/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java +++ b/buyer-api/src/main/java/cn/lili/controller/passport/connect/ConnectBuyerWebController.java @@ -76,8 +76,8 @@ public class ConnectBuyerWebController { } @ApiOperation(value = "APP-unionID登录") - @GetMapping("/app/login") - public ResultMessage unionLogin(ConnectAuthUser authUser, @RequestHeader("uuid") String uuid) { + @PostMapping("/app/login") + public ResultMessage unionLogin(@RequestBody ConnectAuthUser authUser, @RequestHeader("uuid") String uuid) { try { return ResultUtil.data(connectService.unionLoginCallback(authUser, uuid)); } catch (Exception e) { diff --git a/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java b/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java index 4cee6641d..eac79b151 100644 --- a/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/connect/serviceimpl/ConnectServiceImpl.java @@ -5,7 +5,6 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import cn.lili.cache.Cache; -import cn.lili.cache.CachePrefix; import cn.lili.common.enums.ClientTypeEnum; import cn.lili.common.enums.ResultCode; import cn.lili.common.exception.ServiceException; @@ -125,24 +124,18 @@ public class ConnectServiceImpl extends ServiceImpl impl @Transactional public Token miniProgramAutoLogin(WechatMPLoginParams params) { - Object cacheData = cache.get(CachePrefix.WECHAT_SESSION_PARAMS.getPrefix() + params.getUuid()); Map map = new HashMap<>(3); - if (cacheData == null) { - //得到微信小程序联合登陆信息 - JSONObject json = this.getConnect(params.getCode()); - //存储session key 后续登录用得到 - String sessionKey = json.getStr("session_key"); - String unionId = json.getStr("unionid"); - String openId = json.getStr("openid"); - map.put("sessionKey", sessionKey); - map.put("unionId", unionId); - map.put("openId", openId); - cache.put(CachePrefix.WECHAT_SESSION_PARAMS.getPrefix() + params.getUuid(), map, 900L); - } else { - map = (Map) cacheData; - } - //微信联合登陆参数 + //得到微信小程序联合登陆信息 + JSONObject json = this.getConnect(params.getCode()); + //存储session key 后续登录用得到 + String sessionKey = json.getStr("session_key"); + String unionId = json.getStr("unionid"); + String openId = json.getStr("openid"); + map.put("sessionKey", sessionKey); + map.put("unionId", unionId); + map.put("openId", openId); + //微信联合登陆参数 return phoneMpBindAndLogin(map.get("sessionKey"), params, map.get("openId"), map.get("unionId")); } @@ -217,7 +210,7 @@ public class ConnectServiceImpl extends ServiceImpl impl connectQueryDTO.getUnionType()) .eq(CharSequenceUtil.isNotEmpty(connectQueryDTO.getUnionId()), Connect::getUnionId, connectQueryDTO.getUnionId()); - return this.getOne(queryWrapper,false); + return this.getOne(queryWrapper, false); } @Override @@ -267,16 +260,16 @@ public class ConnectServiceImpl extends ServiceImpl impl private Token unionLoginCallback(ConnectAuthUser authUser, boolean longTerm) { try { - Member member =null; + Member member = null; //判断是否传递手机号,如果传递手机号则使用手机号登录 - if(StrUtil.isNotBlank(authUser.getPhone())){ + if (StrUtil.isNotBlank(authUser.getPhone())) { member = memberService.findByMobile(authUser.getPhone()); } //如果未查到手机号的会员则使用第三方登录 - if(member==null){ + if (member == null) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); //使用UnionId登录 - if (StrUtil.isNotBlank(authUser.getToken().getUnionId())) { + if (authUser.getToken() != null && StrUtil.isNotBlank(authUser.getToken().getUnionId())) { queryWrapper.eq(Connect::getUnionId, authUser.getToken().getUnionId()) .eq(Connect::getUnionType, authUser.getSource()); } else { diff --git a/framework/src/main/java/cn/lili/modules/file/plugin/impl/MinioFilePlugin.java b/framework/src/main/java/cn/lili/modules/file/plugin/impl/MinioFilePlugin.java index 87d580b30..657823ea5 100644 --- a/framework/src/main/java/cn/lili/modules/file/plugin/impl/MinioFilePlugin.java +++ b/framework/src/main/java/cn/lili/modules/file/plugin/impl/MinioFilePlugin.java @@ -7,6 +7,7 @@ import cn.lili.modules.file.plugin.FilePlugin; import cn.lili.modules.system.entity.dto.OssSetting; import io.minio.*; import io.minio.errors.ErrorResponseException; +import io.minio.messages.DeleteError; import io.minio.messages.DeleteObject; import lombok.extern.slf4j.Slf4j; @@ -96,8 +97,20 @@ public class MinioFilePlugin implements FilePlugin { return; } MinioClient ossClient = getOssClient(); - List objectList = key.stream().map(DeleteObject::new).collect(Collectors.toList()); - ossClient.removeObjects(RemoveObjectsArgs.builder().objects(objectList).bucket(ossSetting.getM_bucketName()).build()); + List objectList = key.stream().map(DeleteObject::new).collect(Collectors.toList()); Iterable> results = + ossClient.removeObjects(RemoveObjectsArgs.builder().objects(objectList).bucket(ossSetting.getM_bucketName()).build()); + for (Result result : results) { + DeleteError error = null; + try { + error = result.get(); + log.error( + "Error in deleting object " + error.objectName() + "; " + error.message()); + } catch (Exception e) { + + log.error( + "Error in deleting object " + e.getMessage()); + } + } } diff --git a/framework/src/main/java/cn/lili/modules/file/plugin/impl/TencentFilePlugin.java b/framework/src/main/java/cn/lili/modules/file/plugin/impl/TencentFilePlugin.java index 0ccd9145e..0c5b0599c 100644 --- a/framework/src/main/java/cn/lili/modules/file/plugin/impl/TencentFilePlugin.java +++ b/framework/src/main/java/cn/lili/modules/file/plugin/impl/TencentFilePlugin.java @@ -65,7 +65,7 @@ public class TencentFilePlugin implements FilePlugin { * @return */ private String getUrlPrefix() { - return "https://" + ossSetting.getTencentCOSBucket() + ".cos" + ossSetting.getTencentCOSEndPoint() + ".myqcloud.com/"; + return "https://" + ossSetting.getTencentCOSBucket() + ".cos" + ossSetting.getTencentCOSRegion() + ".myqcloud.com/"; } @Override diff --git a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java index 1095544a4..a14d773d4 100644 --- a/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/goods/serviceimpl/CategoryServiceImpl.java @@ -106,10 +106,10 @@ public class CategoryServiceImpl extends ServiceImpl i @Override public List categoryTree() { - List categoryVOList = (List) cache.get(CachePrefix.CATEGORY.getPrefix()); - if (categoryVOList != null) { - return categoryVOList; - } +// List categoryVOList = (List) cache.get(CachePrefix.CATEGORY.getPrefix()); +// if (categoryVOList != null) { +// return categoryVOList; +// } //获取全部分类 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); @@ -117,7 +117,7 @@ public class CategoryServiceImpl extends ServiceImpl i List list = this.list(queryWrapper); //构造分类树 - categoryVOList = new ArrayList<>(); + List categoryVOList = new ArrayList<>(); for (Category category : list) { if ("0".equals(category.getParentId())) { CategoryVO categoryVO = new CategoryVO(category); diff --git a/framework/src/main/java/cn/lili/modules/page/serviceimpl/PageDataServiceImpl.java b/framework/src/main/java/cn/lili/modules/page/serviceimpl/PageDataServiceImpl.java index a3c9cebc2..1f1027134 100644 --- a/framework/src/main/java/cn/lili/modules/page/serviceimpl/PageDataServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/page/serviceimpl/PageDataServiceImpl.java @@ -77,7 +77,8 @@ public class PageDataServiceImpl extends ServiceImpl i //如果页面为发布,则关闭其他页面,开启此页面 if (pageData.getPageShow().equals(SwitchEnum.OPEN.name())) { LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); - lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, UserContext.getCurrentUser().getStoreId()); + lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum + , UserContext.getCurrentUser().getStoreId()); lambdaUpdateWrapper.eq(PageData::getPageType, pageData.getPageType()); lambdaUpdateWrapper.eq(PageData::getPageClientType, pageData.getPageClientType()); lambdaUpdateWrapper.set(PageData::getPageShow, SwitchEnum.CLOSE.name()); @@ -96,8 +97,16 @@ public class PageDataServiceImpl extends ServiceImpl i if (pageData.getPageShow() != null && pageData.getPageShow().equals(SwitchEnum.OPEN.name())) { LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageType()), PageData::getPageType, pageData.getPageType()); - lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageClientType()), PageData::getPageClientType, pageData.getPageClientType()); - lambdaUpdateWrapper.eq(PageData::getNum, pageData.getNum()); + lambdaUpdateWrapper.eq(CharSequenceUtil.isNotEmpty(pageData.getPageClientType()), PageData::getPageClientType, + pageData.getPageClientType()); + + //如果是管理员,则判定页面num为null + if (UserContext.getCurrentUser().getRole().name().equals(UserEnums.MANAGER.name())) { + lambdaUpdateWrapper.isNull(PageData::getNum); + } else { + lambdaUpdateWrapper.eq(PageData::getNum, pageData.getNum()); + } + lambdaUpdateWrapper.set(PageData::getPageShow, SwitchEnum.CLOSE.name()); this.update(lambdaUpdateWrapper); } else { @@ -107,8 +116,10 @@ public class PageDataServiceImpl extends ServiceImpl i LambdaUpdateWrapper lambdaUpdateWrapper = Wrappers.lambdaUpdate(); lambdaUpdateWrapper.set(PageData::getPageData, pageData.getPageData()); lambdaUpdateWrapper.eq(PageData::getId, pageData.getId()); - lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getPageType, PageEnum.STORE.name()); - lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, UserContext.getCurrentUser().getStoreId()); + lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), + PageData::getPageType, PageEnum.STORE.name()); + lambdaUpdateWrapper.eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, + UserContext.getCurrentUser().getStoreId()); this.updateById(pageData); return pageData; } @@ -117,8 +128,10 @@ public class PageDataServiceImpl extends ServiceImpl i @Transactional(rollbackFor = Exception.class) public PageData releasePageData(String id) { PageData pageData = this.getOne(new LambdaQueryWrapper() - .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getPageType, PageEnum.STORE.name()) - .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, UserContext.getCurrentUser().getStoreId()) + .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getPageType, + PageEnum.STORE.name()) + .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, + UserContext.getCurrentUser().getStoreId()) .eq(PageData::getId, id)); if (pageData == null) { throw new ServiceException(ResultCode.PAGE_NOT_EXIST); @@ -152,8 +165,10 @@ public class PageDataServiceImpl extends ServiceImpl i @Transactional(rollbackFor = Exception.class) public boolean removePageData(String id) { PageData pageData = this.getOne(new LambdaQueryWrapper() - .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getPageType, PageEnum.STORE.name()) - .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, UserContext.getCurrentUser().getStoreId()) + .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getPageType, + PageEnum.STORE.name()) + .eq(CharSequenceUtil.equals(UserContext.getCurrentUser().getRole().name(), UserEnums.STORE.name()), PageData::getNum, + UserContext.getCurrentUser().getStoreId()) .eq(PageData::getId, id)); if (pageData == null) { throw new ServiceException(ResultCode.PAGE_NOT_EXIST); diff --git a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/KanjiaActivityGoodsServiceImpl.java b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/KanjiaActivityGoodsServiceImpl.java index 6dd7cbbe1..cc9bf4df0 100644 --- a/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/KanjiaActivityGoodsServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/promotion/serviceimpl/KanjiaActivityGoodsServiceImpl.java @@ -232,8 +232,15 @@ public class KanjiaActivityGoodsServiceImpl extends AbstractPromotionsServiceImp KanjiaActivityGoodsVO kanJiaActivityGoodsVO = new KanjiaActivityGoodsVO(); //获取砍价商品 KanjiaActivityGoods kanJiaActivityGoods = this.getById(id); + if (kanJiaActivityGoods == null) { + throw new ServiceException(ResultCode.KANJIA_ACTIVITY_NOT_FOUND_ERROR); + } //获取商品SKU GoodsSku goodsSku = this.goodsSkuService.getCanPromotionGoodsSkuByIdFromCache(kanJiaActivityGoods.getSkuId()); + + if (goodsSku == null) { + throw new ServiceException(ResultCode.KANJIA_ACTIVITY_NOT_FOUND_ERROR); + } //填写活动商品价格、剩余数量 kanJiaActivityGoodsVO.setGoodsSku(goodsSku); kanJiaActivityGoodsVO.setStock(kanJiaActivityGoods.getStock()); diff --git a/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java b/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java index f1a2d374b..5b88478e3 100644 --- a/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java +++ b/framework/src/main/java/cn/lili/modules/search/utils/SqlFilter.java @@ -1,8 +1,9 @@ package cn.lili.modules.search.utils; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; +import cn.lili.common.utils.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * sql 关键字过滤 @@ -15,13 +16,17 @@ import java.util.Set; public class SqlFilter { - private static final Set SQL_KEYWORDS = new HashSet<>(Arrays.asList( - "SELECT", "FROM", "WHERE", "AND", "OR", "NOT", "INSERT", "UPDATE", "DELETE", "CREATE", - "TABLE", "INDEX", "VIEW", "DROP", "ALTER", "COLUMN", "ADD", "SET", "GROUP", "BY", - "HAVING", "ORDER", "ASC", "DESC", "LIKE", "IN", "BETWEEN", "IS", "NULL", "TRUE", "FALSE", - "JOIN", "LEFT", "RIGHT", "INNER", "OUTER", "FULL", "ON", "AS", "DISTINCT", "COUNT", - "MAX", "MIN", "SUM", "AVG" - )); + + // SQL注入过滤 + static final String SQL_KEYWORDS_PATTERN = + "(?i)(SELECT|FROM|WHERE|CONCAT|AND|NOT|INSERT|UPDATE|DELETE" + + "|TABLE|INDEX|VIEW|DROP|ALTER|COLUMN|ADD|SET|GROUP|BY" + + "|HAVING|ORDER|ASC|DESC|LIKE|IN|BETWEEN|IS|NULL|TRUE|FALSE" + + "|JOIN|LEFT|RIGHT|INNER|OUTER|FULL|ON|AS|DISTINCT|COUNT" + + "|MAX|MIN|SUM|AVG|IF|RAND|UPDATEXML|EXTRACTVALUE|LOAD_FILE|SLEEP|OFFSET)"; + // OR 影响排序字段 sort,所以暂时不过滤 + // CREATE 影响常用排序字段, CREATE_TIME,所以暂时不过滤 + static final Pattern keywordPattern = Pattern.compile(SQL_KEYWORDS_PATTERN, Pattern.CASE_INSENSITIVE); /** @@ -31,29 +36,12 @@ public class SqlFilter { * @return */ public static Boolean hit(String sql) { - String[] tokens = sql.split("\\s+"); - for (String token : tokens) { - if (!SQL_KEYWORDS.contains(token.toUpperCase())) { - return true; - } + if (StringUtils.isEmpty(sql)) { + return false; } - return false; + Matcher matcher = keywordPattern.matcher(sql); + return matcher.find(); } - /** - * 关键字替换 - * - * @param sql - * @return - */ - public static String filterSql(String sql) { - String[] tokens = sql.split("\\s+"); - StringBuilder filteredSql = new StringBuilder(); - for (String token : tokens) { - if (!SQL_KEYWORDS.contains(token.toUpperCase())) { - filteredSql.append(token).append(" "); - } - } - return filteredSql.toString().trim(); - } + } diff --git a/framework/src/main/java/cn/lili/modules/system/service/RegionService.java b/framework/src/main/java/cn/lili/modules/system/service/RegionService.java index 3696d7c32..e33387ef5 100644 --- a/framework/src/main/java/cn/lili/modules/system/service/RegionService.java +++ b/framework/src/main/java/cn/lili/modules/system/service/RegionService.java @@ -19,6 +19,27 @@ import java.util.Map; @CacheConfig(cacheNames = "{regions}") public interface RegionService extends IService { + + /** + * 更新地区 + * + * @param region 地区 + * @return + */ + @CacheEvict(allEntries = true) + boolean updateById(Region region); + /** + * 更新地区 + * + * @param region 地区 + * @return + */ + @CacheEvict(allEntries = true) + boolean save(Region region); + + + @CacheEvict(allEntries = true) + boolean removeByIds(List idList); /** * 同步行政数据 * diff --git a/framework/src/main/java/cn/lili/modules/system/serviceimpl/RegionServiceImpl.java b/framework/src/main/java/cn/lili/modules/system/serviceimpl/RegionServiceImpl.java index cccf18607..8844dc724 100644 --- a/framework/src/main/java/cn/lili/modules/system/serviceimpl/RegionServiceImpl.java +++ b/framework/src/main/java/cn/lili/modules/system/serviceimpl/RegionServiceImpl.java @@ -16,6 +16,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.*; @@ -36,6 +37,24 @@ public class RegionServiceImpl extends ServiceImpl impleme @Autowired private Cache cache; + + @Override + @Transactional + public boolean updateById(Region region) { + return super.updateById(region); + } + + @Transactional + @Override + public boolean save(Region region) { + return super.save(region); + } + + @Override + public boolean removeByIds(List idList) { + return super.removeByIds(idList); + } + @Override public void synchronizationData(String url) { try { diff --git a/framework/src/main/java/cn/lili/mybatis/util/PageUtil.java b/framework/src/main/java/cn/lili/mybatis/util/PageUtil.java index e2d5f63a2..9dfeaf770 100644 --- a/framework/src/main/java/cn/lili/mybatis/util/PageUtil.java +++ b/framework/src/main/java/cn/lili/mybatis/util/PageUtil.java @@ -1,15 +1,17 @@ package cn.lili.mybatis.util; import cn.hutool.core.date.DateUtil; -import cn.hutool.core.util.StrUtil; +import cn.hutool.core.text.CharSequenceUtil; import cn.lili.common.utils.BeanUtil; import cn.lili.common.utils.StringUtils; import cn.lili.common.vo.PageVO; import cn.lili.common.vo.SearchVO; +import cn.lili.modules.search.utils.SqlFilter; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.OrderItem; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import lombok.extern.slf4j.Slf4j; import java.util.ArrayList; import java.util.Date; @@ -22,19 +24,21 @@ import java.util.List; * @version v4.0 * @since 2020/11/26 15:23 */ +@Slf4j public class PageUtil { + //有order by 注入风险,限制长度 + static final Integer orderByLengthLimit = 20; /** * Mybatis-Plus分页封装 * * @param page 分页VO - * @param 范型 + * @param 范型 * @return 分页响应 */ public static Page initPage(PageVO page) { - Page p; int pageNumber = page.getPageNumber(); int pageSize = page.getPageSize(); String sort = page.getSort(); @@ -49,30 +53,39 @@ public class PageUtil { if (pageSize > 100) { pageSize = 100; } - if (StrUtil.isNotBlank(sort)) { - Boolean isAsc = false; - if (StrUtil.isBlank(order)) { - isAsc = false; - } else { + + Page p = new Page<>(pageNumber, pageSize); + + if (CharSequenceUtil.isNotBlank(sort)) { + + if (sort.length() > orderByLengthLimit || SqlFilter.hit(sort)) { + log.error("排序字段长度超过限制或包含sql关键字,请关注:{}", sort); + return p; + } + + boolean isAsc = false; + if (!CharSequenceUtil.isBlank(order)) { if ("desc".equals(order.toLowerCase())) { isAsc = false; } else if ("asc".equals(order.toLowerCase())) { isAsc = true; } } - p = new Page<>(pageNumber, pageSize); + if (isAsc) { p.addOrder(OrderItem.asc(sort)); } else { p.addOrder(OrderItem.desc(sort)); } - } else { - p = new Page<>(pageNumber, pageSize); } return p; } + private void orderByHandler() { + + } + /** * 生成条件搜索 全对象对比 equals * 如果需要like 需要另行处理 @@ -87,14 +100,14 @@ public class PageUtil { /** * 生成条件搜索 全对象对比 * - * @param object 对象 + * @param object 对象 * @param searchVo 查询条件 * @return 查询wrapper */ public static QueryWrapper initWrapper(Object object, SearchVO searchVo) { QueryWrapper queryWrapper = new QueryWrapper<>(); //创建时间区间判定 - if (searchVo != null && StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) { + if (searchVo != null && CharSequenceUtil.isNotBlank(searchVo.getStartDate()) && CharSequenceUtil.isNotBlank(searchVo.getEndDate())) { Date start = DateUtil.parse(searchVo.getStartDate()); Date end = DateUtil.parse(searchVo.getEndDate()); queryWrapper.between("create_time", start, DateUtil.endOfDay(end)); @@ -156,8 +169,8 @@ public class PageUtil { * 转换分页类型 * * @param originPage 原分页 - * @param records 新分页数据 - * @param 新类型 + * @param records 新分页数据 + * @param 新类型 * @return 新类型分页 */ public static IPage convertPage(IPage originPage, List records) { diff --git a/pom.xml b/pom.xml index 84a36127f..4245d25fe 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ 1.8 - 4.2.5 + 4.3 UTF-8 UTF-8 true