Merge branch 'master-jdk17' of https://gitee.com/zhijiantianya/ruoyi-vue-pro
# Conflicts: # yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java # yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
This commit is contained in:
commit
5d3bb791fd
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
|
@ -112,7 +112,7 @@
|
|||
|
||||
* 通用模块(必选):系统功能、基础设施
|
||||
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
|
||||
* 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号
|
||||
* 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
|
||||
|
||||
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
|
||||
>
|
||||
|
@ -248,6 +248,12 @@
|
|||
|
||||
演示地址:<https://doc.iocoder.cn/crm-preview/>
|
||||
|
||||
### AI 大模型
|
||||
|
||||
![功能图](/.image/common/ai-feature.png)
|
||||
|
||||
演示地址:<https://doc.iocoder.cn/ai-preview/>
|
||||
|
||||
## 🐨 技术栈
|
||||
|
||||
### 模块
|
||||
|
@ -265,6 +271,7 @@
|
|||
| `yudao-module-mall` | 商城系统的 Module 模块 |
|
||||
| `yudao-module-erp` | ERP 系统的 Module 模块 |
|
||||
| `yudao-module-crm` | CRM 系统的 Module 模块 |
|
||||
| `yudao-module-ai` | AI 大模型的 Module 模块 |
|
||||
| `yudao-module-mp` | 微信公众号的 Module 模块 |
|
||||
| `yudao-module-report` | 大屏报表 Module 模块 |
|
||||
|
||||
|
|
|
@ -34,20 +34,24 @@ public class CronUtils {
|
|||
* @return 满足条件的执行时间
|
||||
*/
|
||||
public static List<LocalDateTime> getNextTimes(String cronExpression, int n) {
|
||||
// 获得 CronExpression 对象
|
||||
// 1. 获得 CronExpression 对象
|
||||
CronExpression cron;
|
||||
try {
|
||||
cron = new CronExpression(cronExpression);
|
||||
} catch (ParseException e) {
|
||||
throw new IllegalArgumentException(e.getMessage());
|
||||
}
|
||||
// 从当前开始计算,n 个满足条件的
|
||||
// 2. 从当前开始计算,n 个满足条件的
|
||||
Date now = new Date();
|
||||
List<LocalDateTime> nextTimes = new ArrayList<>(n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
Date nextTime = cron.getNextValidTimeAfter(now);
|
||||
// 2.1 如果 nextTime 为 null,说明没有更多的有效时间,退出循环
|
||||
if (nextTime == null) {
|
||||
break;
|
||||
}
|
||||
nextTimes.add(LocalDateTimeUtil.of(nextTime));
|
||||
// 切换现在,为下一个触发时间;
|
||||
// 2.2 切换现在,为下一个触发时间;
|
||||
now = nextTime;
|
||||
}
|
||||
return nextTimes;
|
||||
|
|
|
@ -262,7 +262,9 @@ public class BpmModelServiceImpl implements BpmModelService {
|
|||
}
|
||||
|
||||
private Model getModelByKey(String key) {
|
||||
return repositoryService.createModelQuery().modelKey(key).singleResult();
|
||||
return repositoryService.createModelQuery()
|
||||
.modelTenantId(FlowableUtils.getTenantId())
|
||||
.modelKey(key).singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -79,7 +79,9 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
|||
|
||||
@Override
|
||||
public ProcessDefinition getActiveProcessDefinition(String key) {
|
||||
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult();
|
||||
return repositoryService.createProcessDefinitionQuery()
|
||||
.processDefinitionTenantId(FlowableUtils.getTenantId())
|
||||
.processDefinitionKey(key).active().singleResult();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -172,6 +174,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
|
|||
@Override
|
||||
public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
|
||||
ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
|
||||
query.processDefinitionTenantId(FlowableUtils.getTenantId());
|
||||
if (StrUtil.isNotBlank(pageVO.getKey())) {
|
||||
query.processDefinitionKey(pageVO.getKey());
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
|
|||
.likeIfPresent(ProductSpuDO::getName, reqVO.getName())
|
||||
.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
|
||||
.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(ProductSpuDO::getSort);
|
||||
.orderByDesc(ProductSpuDO::getSort)
|
||||
.orderByDesc(ProductSpuDO::getId);
|
||||
appendTabQuery(tabType, queryWrapper);
|
||||
return selectPage(reqVO, queryWrapper);
|
||||
}
|
||||
|
|
|
@ -1,33 +1,49 @@
|
|||
package cn.iocoder.yudao.module.trade.service.order;
|
||||
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||
import cn.iocoder.yudao.module.member.api.address.MemberAddressApi;
|
||||
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
|
||||
import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
|
||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.delivery.vo.express.DeliveryExpressCreateReqVO;
|
||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
|
||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
|
||||
import cn.iocoder.yudao.module.trade.dal.redis.no.TradeNoRedisDAO;
|
||||
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
|
||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig;
|
||||
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties;
|
||||
import cn.iocoder.yudao.module.trade.service.cart.CartServiceImpl;
|
||||
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService;
|
||||
import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressServiceImpl;
|
||||
import cn.iocoder.yudao.module.trade.service.message.TradeMessageServiceImpl;
|
||||
import cn.iocoder.yudao.module.trade.service.order.handler.TradeOrderHandler;
|
||||
import cn.iocoder.yudao.module.trade.service.price.TradePriceServiceImpl;
|
||||
import cn.iocoder.yudao.module.trade.service.price.calculator.TradePriceCalculator;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.Duration;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
|
@ -38,7 +54,9 @@ import static org.mockito.Mockito.when;
|
|||
* @since 2022-09-07
|
||||
*/
|
||||
@Disabled // TODO 芋艿:后续 fix 补充的单测
|
||||
@Import({TradeOrderUpdateServiceImpl.class, TradeOrderConfig.class})
|
||||
@Import({TradeOrderUpdateServiceImpl.class, TradeOrderConfig.class, CartServiceImpl.class, TradePriceServiceImpl.class,
|
||||
DeliveryExpressServiceImpl.class, TradeMessageServiceImpl.class
|
||||
})
|
||||
public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
||||
|
||||
@Resource
|
||||
|
@ -55,6 +73,8 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
|||
private ProductSpuApi productSpuApi;
|
||||
@MockBean
|
||||
private ProductSkuApi productSkuApi;
|
||||
@MockBean
|
||||
private ProductCommentApi productCommentApi;
|
||||
// @MockBean
|
||||
// private PriceApi priceApi;
|
||||
@MockBean
|
||||
|
@ -66,11 +86,22 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
|||
|
||||
@MockBean
|
||||
private TradeOrderProperties tradeOrderProperties;
|
||||
@MockBean
|
||||
private TradeNoRedisDAO tradeNoRedisDAO;
|
||||
@MockBean
|
||||
private TradeOrderHandler tradeOrderHandler;
|
||||
@MockBean
|
||||
private TradePriceCalculator tradePriceCalculator;
|
||||
@MockBean
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
@MockBean
|
||||
private DeliveryExpressService deliveryExpressService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(tradeOrderProperties.getAppId()).thenReturn(888L);
|
||||
when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1));
|
||||
when(tradeNoRedisDAO.generate(anyString())).thenReturn(IdUtil.randomUUID());
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
@ -259,11 +290,18 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
|
|||
TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> {
|
||||
o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus());
|
||||
o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null);
|
||||
o.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
|
||||
o.setDeliveryType(DeliveryTypeEnum.EXPRESS.getType());
|
||||
});
|
||||
tradeOrderMapper.insert(order);
|
||||
|
||||
DeliveryExpressCreateReqVO expressCreateReqVO = new DeliveryExpressCreateReqVO();
|
||||
expressCreateReqVO.setCode("code").setName("Name").setLogo("logo").setSort(0).setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
Long deliveryExpressId = deliveryExpressService.createDeliveryExpress(expressCreateReqVO);
|
||||
// 准备参数
|
||||
TradeOrderDeliveryReqVO deliveryReqVO = new TradeOrderDeliveryReqVO().setId(1L)
|
||||
.setLogisticsId(10L).setLogisticsNo("100");
|
||||
.setLogisticsId(deliveryExpressId).setLogisticsNo("100");
|
||||
|
||||
// mock 方法(支付单)
|
||||
|
||||
// 调用
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
CREATE TABLE IF NOT EXISTS "trade_order" (
|
||||
CREATE TABLE IF NOT EXISTS "trade_order"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"no" varchar NOT NULL,
|
||||
"type" int NOT NULL,
|
||||
|
@ -10,16 +11,19 @@ CREATE TABLE IF NOT EXISTS "trade_order" (
|
|||
"product_count" int NOT NULL,
|
||||
"cancel_type" int,
|
||||
"remark" varchar,
|
||||
"comment_status" boolean,
|
||||
"brokerage_user_id" bigint,
|
||||
"pay_status" bit NOT NULL,
|
||||
"pay_time" datetime,
|
||||
"finish_time" datetime,
|
||||
"cancel_time" datetime,
|
||||
"original_price" int NOT NULL,
|
||||
"order_price" int NOT NULL,
|
||||
"total_price" int NULL,
|
||||
"order_price" int NULL,
|
||||
"discount_price" int NOT NULL,
|
||||
"delivery_price" int NOT NULL,
|
||||
"adjust_price" int NOT NULL,
|
||||
"pay_price" int NOT NULL,
|
||||
"delivery_type" int NOT NULL,
|
||||
"pay_order_id" bigint,
|
||||
"pay_channel_code" varchar,
|
||||
"delivery_template_id" bigint,
|
||||
|
@ -32,11 +36,24 @@ CREATE TABLE IF NOT EXISTS "trade_order" (
|
|||
"receiver_area_id" int NOT NULL,
|
||||
"receiver_post_code" int,
|
||||
"receiver_detail_address" varchar NOT NULL,
|
||||
"after_sale_status" int NOT NULL,
|
||||
"refund_price" int NOT NULL,
|
||||
"pick_up_store_id" long NULL,
|
||||
"pick_up_verify_code" varchar NULL,
|
||||
"refund_status" int NULL,
|
||||
"refund_price" int NULL,
|
||||
"after_sale_status" int NULL,
|
||||
"coupon_id" bigint NOT NULL,
|
||||
"coupon_price" int NOT NULL,
|
||||
"use_point" int NULL,
|
||||
"point_price" int NOT NULL,
|
||||
"give_point" int NULL,
|
||||
"refund_point" int NULL,
|
||||
"vip_price" int NULL,
|
||||
"seckill_activity_id" long NULL,
|
||||
"bargain_activity_id" long NULL,
|
||||
"bargain_record_id" long NULL,
|
||||
"combination_activity_id" long NULL,
|
||||
"combination_head_id" long NULL,
|
||||
"combination_record_id" long NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
|
@ -45,22 +62,30 @@ CREATE TABLE IF NOT EXISTS "trade_order" (
|
|||
PRIMARY KEY ("id")
|
||||
) COMMENT '交易订单表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "trade_order_item" (
|
||||
CREATE TABLE IF NOT EXISTS "trade_order_item"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"order_id" bigint NOT NULL,
|
||||
"cart_id" int NULL,
|
||||
"spu_id" bigint NOT NULL,
|
||||
"spu_name" varchar NOT NULL,
|
||||
"sku_id" bigint NOT NULL,
|
||||
"properties" varchar,
|
||||
"pic_url" varchar,
|
||||
"count" int NOT NULL,
|
||||
"original_price" int NOT NULL,
|
||||
"original_unit_price" int NOT NULL,
|
||||
"comment_status" boolean NULL,
|
||||
"price" int NOT NULL,
|
||||
"discount_price" int NOT NULL,
|
||||
"delivery_price" int NULL,
|
||||
"adjust_price" int NULL,
|
||||
"pay_price" int NOT NULL,
|
||||
"order_part_price" int NOT NULL,
|
||||
"order_divide_price" int NOT NULL,
|
||||
"coupon_price" int NULL,
|
||||
"point_price" int NULL,
|
||||
"use_point" int NULL,
|
||||
"give_point" int NULL,
|
||||
"vip_price" int NULL,
|
||||
"after_sale_id" long NULL,
|
||||
"after_sale_status" int NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
@ -70,7 +95,8 @@ CREATE TABLE IF NOT EXISTS "trade_order_item" (
|
|||
PRIMARY KEY ("id")
|
||||
) COMMENT '交易订单明细表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "trade_after_sale" (
|
||||
CREATE TABLE IF NOT EXISTS "trade_after_sale"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"no" varchar NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
|
@ -108,7 +134,8 @@ CREATE TABLE IF NOT EXISTS "trade_after_sale" (
|
|||
PRIMARY KEY ("id")
|
||||
) COMMENT '交易售后表';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "trade_after_sale_log" (
|
||||
CREATE TABLE IF NOT EXISTS "trade_after_sale_log"
|
||||
(
|
||||
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"user_id" bigint NOT NULL,
|
||||
"user_type" int NOT NULL,
|
||||
|
@ -189,3 +216,19 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
|
|||
"tenant_id" bigint not null default '0',
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '佣金提现';
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "trade_delivery_express"
|
||||
(
|
||||
"id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||
"code" varchar NULL,
|
||||
"name" varchar,
|
||||
"logo" varchar NULL,
|
||||
"sort" int NOT NULL,
|
||||
"status" int NOT NULL,
|
||||
"creator" varchar DEFAULT '',
|
||||
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updater" varchar DEFAULT '',
|
||||
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||
PRIMARY KEY ("id")
|
||||
) COMMENT '佣金提现';
|
|
@ -88,6 +88,12 @@ public class MemberAuthServiceImpl implements MemberAuthService {
|
|||
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp, getTerminal());
|
||||
Assert.notNull(user, "获取用户失败,结果为空");
|
||||
|
||||
// 校验是否禁用
|
||||
if (CommonStatusEnum.isDisable(user.getStatus())) {
|
||||
createLoginLog(user.getId(), reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, LoginResultEnum.USER_DISABLED);
|
||||
throw exception(AUTH_LOGIN_USER_DISABLED);
|
||||
}
|
||||
|
||||
// 如果 socialType 非空,说明需要绑定社交用户
|
||||
String openid = null;
|
||||
if (reqVO.getSocialType() != null) {
|
||||
|
@ -177,7 +183,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
|
|||
throw exception(AUTH_LOGIN_BAD_CREDENTIALS);
|
||||
}
|
||||
// 校验是否禁用
|
||||
if (ObjectUtil.notEqual(user.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
|
||||
if (CommonStatusEnum.isDisable(user.getStatus())) {
|
||||
createLoginLog(user.getId(), mobile, logTypeEnum, LoginResultEnum.USER_DISABLED);
|
||||
throw exception(AUTH_LOGIN_USER_DISABLED);
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ public class AuthController {
|
|||
// 1.3 获得菜单列表
|
||||
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
|
||||
List<MenuDO> menuList = menuService.getMenuList(menuIds);
|
||||
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单
|
||||
menuList = menuService.filterDisableMenus(menuList);
|
||||
|
||||
// 2. 拼接结果返回
|
||||
return success(AuthConvert.INSTANCE.convert(user, roles, menuList));
|
||||
|
|
|
@ -72,6 +72,7 @@ public class MenuController {
|
|||
public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
|
||||
List<MenuDO> list = menuService.getMenuListByTenant(
|
||||
new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
|
||||
list = menuService.filterDisableMenus(list);
|
||||
list.sort(Comparator.comparing(MenuDO::getSort));
|
||||
return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
|
||||
}
|
||||
|
|
|
@ -52,6 +52,14 @@ public interface MenuService {
|
|||
*/
|
||||
List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 过滤掉关闭的菜单及其子菜单
|
||||
*
|
||||
* @param list 菜单列表
|
||||
* @return 过滤后的菜单列表
|
||||
*/
|
||||
List<MenuDO> filterDisableMenus(List<MenuDO> list);
|
||||
|
||||
/**
|
||||
* 筛选菜单列表
|
||||
*
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package cn.iocoder.yudao.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
|
||||
|
@ -11,6 +13,7 @@ import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
|
|||
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.collect.Lists;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
|
@ -18,12 +21,11 @@ import org.springframework.context.annotation.Lazy;
|
|||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
|
||||
import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
|
||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||
|
||||
|
@ -106,12 +108,57 @@ public class MenuServiceImpl implements MenuService {
|
|||
|
||||
@Override
|
||||
public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) {
|
||||
// 查询所有菜单,并过滤掉关闭的节点
|
||||
List<MenuDO> menus = getMenuList(reqVO);
|
||||
// 开启多租户的情况下,需要过滤掉未开通的菜单
|
||||
tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
|
||||
return menus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuDO> filterDisableMenus(List<MenuDO> menuList) {
|
||||
if (CollUtil.isEmpty(menuList)){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Map<Long, MenuDO> menuMap = convertMap(menuList, MenuDO::getId);
|
||||
|
||||
// 遍历 menu 菜单,查找不是禁用的菜单,添加到 enabledMenus 结果
|
||||
List<MenuDO> enabledMenus = new ArrayList<>();
|
||||
Set<Long> disabledMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索
|
||||
for (MenuDO menu : menuList) {
|
||||
if (isMenuDisabled(menu, menuMap, disabledMenuCache)) {
|
||||
continue;
|
||||
}
|
||||
enabledMenus.add(menu);
|
||||
}
|
||||
return enabledMenus;
|
||||
}
|
||||
|
||||
private boolean isMenuDisabled(MenuDO node, Map<Long, MenuDO> menuMap, Set<Long> disabledMenuCache) {
|
||||
// 如果已经判定是禁用的节点,直接结束
|
||||
if (disabledMenuCache.contains(node.getId())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 1. 遍历到 parentId 为根节点,则无需判断
|
||||
Long parentId = node.getParentId();
|
||||
if (ObjUtil.equal(parentId, ID_ROOT)) {
|
||||
if (CommonStatusEnum.isDisable(node.getStatus())) {
|
||||
disabledMenuCache.add(node.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 2. 继续遍历 parent 节点
|
||||
MenuDO parent = menuMap.get(parentId);
|
||||
if (parent == null || isMenuDisabled(parent, menuMap, disabledMenuCache)) {
|
||||
disabledMenuCache.add(node.getId());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuDO> getMenuList(MenuListReqVO reqVO) {
|
||||
return menuMapper.selectList(reqVO);
|
||||
|
|
Loading…
Reference in New Issue