# 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:
YunaiV 2024-07-07 09:14:36 +08:00
commit 5d3bb791fd
13 changed files with 292 additions and 132 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -112,7 +112,7 @@
* 通用模块(必选):系统功能、基础设施 * 通用模块(必选):系统功能、基础设施
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心 * 通用模块(可选):工作流程、支付系统、数据报表、会员中心
* 业务系统按需ERP 系统、CRM 系统、商城系统、微信公众号 * 业务系统按需ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。 > 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
> >
@ -248,6 +248,12 @@
演示地址:<https://doc.iocoder.cn/crm-preview/> 演示地址:<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-mall` | 商城系统的 Module 模块 |
| `yudao-module-erp` | ERP 系统的 Module 模块 | | `yudao-module-erp` | ERP 系统的 Module 模块 |
| `yudao-module-crm` | CRM 系统的 Module 模块 | | `yudao-module-crm` | CRM 系统的 Module 模块 |
| `yudao-module-ai` | AI 大模型的 Module 模块 |
| `yudao-module-mp` | 微信公众号的 Module 模块 | | `yudao-module-mp` | 微信公众号的 Module 模块 |
| `yudao-module-report` | 大屏报表 Module 模块 | | `yudao-module-report` | 大屏报表 Module 模块 |

View File

@ -34,20 +34,24 @@ public class CronUtils {
* @return 满足条件的执行时间 * @return 满足条件的执行时间
*/ */
public static List<LocalDateTime> getNextTimes(String cronExpression, int n) { public static List<LocalDateTime> getNextTimes(String cronExpression, int n) {
// 获得 CronExpression 对象 // 1. 获得 CronExpression 对象
CronExpression cron; CronExpression cron;
try { try {
cron = new CronExpression(cronExpression); cron = new CronExpression(cronExpression);
} catch (ParseException e) { } catch (ParseException e) {
throw new IllegalArgumentException(e.getMessage()); throw new IllegalArgumentException(e.getMessage());
} }
// 从当前开始计算n 个满足条件的 // 2. 从当前开始计算n 个满足条件的
Date now = new Date(); Date now = new Date();
List<LocalDateTime> nextTimes = new ArrayList<>(n); List<LocalDateTime> nextTimes = new ArrayList<>(n);
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
Date nextTime = cron.getNextValidTimeAfter(now); Date nextTime = cron.getNextValidTimeAfter(now);
// 2.1 如果 nextTime null说明没有更多的有效时间退出循环
if (nextTime == null) {
break;
}
nextTimes.add(LocalDateTimeUtil.of(nextTime)); nextTimes.add(LocalDateTimeUtil.of(nextTime));
// 切换现在为下一个触发时间 // 2.2 切换现在为下一个触发时间
now = nextTime; now = nextTime;
} }
return nextTimes; return nextTimes;

View File

@ -262,7 +262,9 @@ public class BpmModelServiceImpl implements BpmModelService {
} }
private Model getModelByKey(String key) { private Model getModelByKey(String key) {
return repositoryService.createModelQuery().modelKey(key).singleResult(); return repositoryService.createModelQuery()
.modelTenantId(FlowableUtils.getTenantId())
.modelKey(key).singleResult();
} }
@Override @Override

View File

@ -79,7 +79,9 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
@Override @Override
public ProcessDefinition getActiveProcessDefinition(String key) { public ProcessDefinition getActiveProcessDefinition(String key) {
return repositoryService.createProcessDefinitionQuery().processDefinitionKey(key).active().singleResult(); return repositoryService.createProcessDefinitionQuery()
.processDefinitionTenantId(FlowableUtils.getTenantId())
.processDefinitionKey(key).active().singleResult();
} }
@Override @Override
@ -172,6 +174,7 @@ public class BpmProcessDefinitionServiceImpl implements BpmProcessDefinitionServ
@Override @Override
public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) { public PageResult<ProcessDefinition> getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery(); ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
query.processDefinitionTenantId(FlowableUtils.getTenantId());
if (StrUtil.isNotBlank(pageVO.getKey())) { if (StrUtil.isNotBlank(pageVO.getKey())) {
query.processDefinitionKey(pageVO.getKey()); query.processDefinitionKey(pageVO.getKey());
} }

View File

@ -30,7 +30,8 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
.likeIfPresent(ProductSpuDO::getName, reqVO.getName()) .likeIfPresent(ProductSpuDO::getName, reqVO.getName())
.eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId()) .eqIfPresent(ProductSpuDO::getCategoryId, reqVO.getCategoryId())
.betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(ProductSpuDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductSpuDO::getSort); .orderByDesc(ProductSpuDO::getSort)
.orderByDesc(ProductSpuDO::getId);
appendTabQuery(tabType, queryWrapper); appendTabQuery(tabType, queryWrapper);
return selectPage(reqVO, queryWrapper); return selectPage(reqVO, queryWrapper);
} }

View File

@ -1,33 +1,49 @@
package cn.iocoder.yudao.module.trade.service.order; 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.framework.test.core.ut.BaseDbUnitTest;
import cn.iocoder.yudao.module.member.api.address.MemberAddressApi; import cn.iocoder.yudao.module.member.api.address.MemberAddressApi;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 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.PayOrderApi;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO; import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum; 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.sku.ProductSkuApi;
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi; 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.controller.admin.order.vo.TradeOrderDeliveryReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 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.TradeOrderItemMapper;
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; 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.enums.order.TradeOrderStatusEnum;
import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderConfig; 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.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.BeforeEach;
import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.time.Duration; import java.time.Duration;
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -38,7 +54,9 @@ import static org.mockito.Mockito.when;
* @since 2022-09-07 * @since 2022-09-07
*/ */
@Disabled // TODO 芋艿后续 fix 补充的单测 @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 { public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
@Resource @Resource
@ -55,7 +73,9 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
private ProductSpuApi productSpuApi; private ProductSpuApi productSpuApi;
@MockBean @MockBean
private ProductSkuApi productSkuApi; private ProductSkuApi productSkuApi;
// @MockBean @MockBean
private ProductCommentApi productCommentApi;
// @MockBean
// private PriceApi priceApi; // private PriceApi priceApi;
@MockBean @MockBean
private PayOrderApi payOrderApi; private PayOrderApi payOrderApi;
@ -66,11 +86,22 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
@MockBean @MockBean
private TradeOrderProperties tradeOrderProperties; private TradeOrderProperties tradeOrderProperties;
@MockBean
private TradeNoRedisDAO tradeNoRedisDAO;
@MockBean
private TradeOrderHandler tradeOrderHandler;
@MockBean
private TradePriceCalculator tradePriceCalculator;
@MockBean
private NotifyMessageSendApi notifyMessageSendApi;
@MockBean
private DeliveryExpressService deliveryExpressService;
@BeforeEach @BeforeEach
public void setUp() { public void setUp() {
when(tradeOrderProperties.getAppId()).thenReturn(888L); when(tradeOrderProperties.getAppId()).thenReturn(888L);
when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1)); when(tradeOrderProperties.getPayExpireTime()).thenReturn(Duration.ofDays(1));
when(tradeNoRedisDAO.generate(anyString())).thenReturn(IdUtil.randomUUID());
} }
// @Test // @Test
@ -259,11 +290,18 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> { TradeOrderDO order = randomPojo(TradeOrderDO.class, o -> {
o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus()); o.setId(1L).setStatus(TradeOrderStatusEnum.UNDELIVERED.getStatus());
o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null); o.setLogisticsId(null).setLogisticsNo(null).setDeliveryTime(null);
o.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
o.setDeliveryType(DeliveryTypeEnum.EXPRESS.getType());
}); });
tradeOrderMapper.insert(order); 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) TradeOrderDeliveryReqVO deliveryReqVO = new TradeOrderDeliveryReqVO().setId(1L)
.setLogisticsId(10L).setLogisticsNo("100"); .setLogisticsId(deliveryExpressId).setLogisticsNo("100");
// mock 方法支付单 // mock 方法支付单
// 调用 // 调用

View File

@ -1,128 +1,155 @@
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, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"type" int NOT NULL, "no" varchar NOT NULL,
"terminal" int NOT NULL, "type" int NOT NULL,
"user_id" bigint NOT NULL, "terminal" int NOT NULL,
"user_ip" varchar NOT NULL, "user_id" bigint NOT NULL,
"user_remark" varchar, "user_ip" varchar NOT NULL,
"status" int NOT NULL, "user_remark" varchar,
"product_count" int NOT NULL, "status" int NOT NULL,
"cancel_type" int, "product_count" int NOT NULL,
"remark" varchar, "cancel_type" int,
"pay_status" bit NOT NULL, "remark" varchar,
"pay_time" datetime, "comment_status" boolean,
"finish_time" datetime, "brokerage_user_id" bigint,
"cancel_time" datetime, "pay_status" bit NOT NULL,
"original_price" int NOT NULL, "pay_time" datetime,
"order_price" int NOT NULL, "finish_time" datetime,
"discount_price" int NOT NULL, "cancel_time" datetime,
"delivery_price" int NOT NULL, "total_price" int NULL,
"adjust_price" int NOT NULL, "order_price" int NULL,
"pay_price" int NOT NULL, "discount_price" int NOT NULL,
"pay_order_id" bigint, "delivery_price" int NOT NULL,
"pay_channel_code" varchar, "adjust_price" int NOT NULL,
"delivery_template_id" bigint, "pay_price" int NOT NULL,
"logistics_id" bigint, "delivery_type" int NOT NULL,
"logistics_no" varchar, "pay_order_id" bigint,
"delivery_time" datetime, "pay_channel_code" varchar,
"receive_time" datetime, "delivery_template_id" bigint,
"receiver_name" varchar NOT NULL, "logistics_id" bigint,
"receiver_mobile" varchar NOT NULL, "logistics_no" varchar,
"receiver_area_id" int NOT NULL, "delivery_time" datetime,
"receiver_post_code" int, "receive_time" datetime,
"receiver_detail_address" varchar NOT NULL, "receiver_name" varchar NOT NULL,
"after_sale_status" int NOT NULL, "receiver_mobile" varchar NOT NULL,
"refund_price" int NOT NULL, "receiver_area_id" int NOT NULL,
"coupon_id" bigint NOT NULL, "receiver_post_code" int,
"coupon_price" int NOT NULL, "receiver_detail_address" varchar NOT NULL,
"point_price" int NOT NULL, "pick_up_store_id" long NULL,
"creator" varchar DEFAULT '', "pick_up_verify_code" varchar NULL,
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, "refund_status" int NULL,
"updater" varchar DEFAULT '', "refund_price" int NULL,
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "after_sale_status" int NULL,
"deleted" bit NOT NULL DEFAULT FALSE, "coupon_id" bigint NOT NULL,
PRIMARY KEY ("id") "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 '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '交易订单表'; ) 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, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"order_id" bigint NOT NULL, "user_id" bigint NOT NULL,
"spu_id" bigint NOT NULL, "order_id" bigint NOT NULL,
"spu_name" varchar NOT NULL, "cart_id" int NULL,
"sku_id" bigint NOT NULL, "spu_id" bigint NOT NULL,
"properties" varchar, "spu_name" varchar NOT NULL,
"pic_url" varchar, "sku_id" bigint NOT NULL,
"count" int NOT NULL, "properties" varchar,
"original_price" int NOT NULL, "pic_url" varchar,
"original_unit_price" int NOT NULL, "count" int NOT NULL,
"discount_price" int NOT NULL, "comment_status" boolean NULL,
"pay_price" int NOT NULL, "price" int NOT NULL,
"order_part_price" int NOT NULL, "discount_price" int NOT NULL,
"order_divide_price" int NOT NULL, "delivery_price" int NULL,
"after_sale_status" int NOT NULL, "adjust_price" int NULL,
"creator" varchar DEFAULT '', "pay_price" int NOT NULL,
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, "coupon_price" int NULL,
"updater" varchar DEFAULT '', "point_price" int NULL,
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "use_point" int NULL,
"deleted" bit NOT NULL DEFAULT FALSE, "give_point" int NULL,
PRIMARY KEY ("id") "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,
"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 '交易订单明细表'; ) 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, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"status" int NOT NULL, "no" varchar NOT NULL,
"type" int NOT NULL, "status" int NOT NULL,
"way" int NOT NULL, "type" int NOT NULL,
"user_id" bigint NOT NULL, "way" int NOT NULL,
"apply_reason" varchar NOT NULL, "user_id" bigint NOT NULL,
"apply_reason" varchar NOT NULL,
"apply_description" varchar, "apply_description" varchar,
"apply_pic_urls" varchar, "apply_pic_urls" varchar,
"order_id" bigint NOT NULL, "order_id" bigint NOT NULL,
"order_no" varchar NOT NULL, "order_no" varchar NOT NULL,
"order_item_id" bigint NOT NULL, "order_item_id" bigint NOT NULL,
"spu_id" bigint NOT NULL, "spu_id" bigint NOT NULL,
"spu_name" varchar NOT NULL, "spu_name" varchar NOT NULL,
"sku_id" bigint NOT NULL, "sku_id" bigint NOT NULL,
"properties" varchar, "properties" varchar,
"pic_url" varchar, "pic_url" varchar,
"count" int NOT NULL, "count" int NOT NULL,
"audit_time" varchar, "audit_time" varchar,
"audit_user_id" bigint, "audit_user_id" bigint,
"audit_reason" varchar, "audit_reason" varchar,
"refund_price" int NOT NULL, "refund_price" int NOT NULL,
"pay_refund_id" bigint, "pay_refund_id" bigint,
"refund_time" varchar, "refund_time" varchar,
"logistics_id" bigint, "logistics_id" bigint,
"logistics_no" varchar, "logistics_no" varchar,
"delivery_time" varchar, "delivery_time" varchar,
"receive_time" varchar, "receive_time" varchar,
"receive_reason" varchar, "receive_reason" varchar,
"creator" varchar DEFAULT '', "creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '', "updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE, "deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '交易售后表'; ) 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, "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"user_type" int NOT NULL, "user_id" bigint NOT NULL,
"after_sale_id" bigint NOT NULL, "user_type" int NOT NULL,
"order_id" bigint NOT NULL, "after_sale_id" bigint NOT NULL,
"order_item_id" bigint NOT NULL, "order_id" bigint NOT NULL,
"order_item_id" bigint NOT NULL,
"before_status" int, "before_status" int,
"after_status" int NOT NULL, "after_status" int NOT NULL,
"content" varchar NOT NULL, "content" varchar NOT NULL,
"creator" varchar DEFAULT '', "creator" varchar DEFAULT '',
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar DEFAULT '', "updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE, "deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '交易售后日志'; ) COMMENT '交易售后日志';
@ -161,7 +188,7 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_record"
"updater" varchar DEFAULT '', "updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE, "deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0', "tenant_id" bigint not null default '0',
PRIMARY KEY ("id") PRIMARY KEY ("id")
) COMMENT '佣金记录'; ) COMMENT '佣金记录';
CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw" CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
@ -186,6 +213,22 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
"updater" varchar DEFAULT '', "updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE, "deleted" bit NOT NULL DEFAULT FALSE,
"tenant_id" bigint not null default '0', "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") PRIMARY KEY ("id")
) COMMENT '佣金提现'; ) COMMENT '佣金提现';

View File

@ -88,6 +88,12 @@ public class MemberAuthServiceImpl implements MemberAuthService {
MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp, getTerminal()); MemberUserDO user = userService.createUserIfAbsent(reqVO.getMobile(), userIp, getTerminal());
Assert.notNull(user, "获取用户失败,结果为空"); 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 非空说明需要绑定社交用户 // 如果 socialType 非空说明需要绑定社交用户
String openid = null; String openid = null;
if (reqVO.getSocialType() != null) { if (reqVO.getSocialType() != null) {
@ -177,7 +183,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
throw exception(AUTH_LOGIN_BAD_CREDENTIALS); 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); createLoginLog(user.getId(), mobile, logTypeEnum, LoginResultEnum.USER_DISABLED);
throw exception(AUTH_LOGIN_USER_DISABLED); throw exception(AUTH_LOGIN_USER_DISABLED);
} }

View File

@ -109,7 +109,7 @@ public class AuthController {
// 1.3 获得菜单列表 // 1.3 获得菜单列表
Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId)); Set<Long> menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
List<MenuDO> menuList = menuService.getMenuList(menuIds); List<MenuDO> menuList = menuService.getMenuList(menuIds);
menuList.removeIf(menu -> !CommonStatusEnum.ENABLE.getStatus().equals(menu.getStatus())); // 移除禁用的菜单 menuList = menuService.filterDisableMenus(menuList);
// 2. 拼接结果返回 // 2. 拼接结果返回
return success(AuthConvert.INSTANCE.convert(user, roles, menuList)); return success(AuthConvert.INSTANCE.convert(user, roles, menuList));

View File

@ -72,6 +72,7 @@ public class MenuController {
public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() { public CommonResult<List<MenuSimpleRespVO>> getSimpleMenuList() {
List<MenuDO> list = menuService.getMenuListByTenant( List<MenuDO> list = menuService.getMenuListByTenant(
new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus())); new MenuListReqVO().setStatus(CommonStatusEnum.ENABLE.getStatus()));
list = menuService.filterDisableMenus(list);
list.sort(Comparator.comparing(MenuDO::getSort)); list.sort(Comparator.comparing(MenuDO::getSort));
return success(BeanUtils.toBean(list, MenuSimpleRespVO.class)); return success(BeanUtils.toBean(list, MenuSimpleRespVO.class));
} }

View File

@ -52,6 +52,14 @@ public interface MenuService {
*/ */
List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO); List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO);
/**
* 过滤掉关闭的菜单及其子菜单
*
* @param list 菜单列表
* @return 过滤后的菜单列表
*/
List<MenuDO> filterDisableMenus(List<MenuDO> list);
/** /**
* 筛选菜单列表 * 筛选菜单列表
* *

View File

@ -1,6 +1,8 @@
package cn.iocoder.yudao.module.system.service.permission; package cn.iocoder.yudao.module.system.service.permission;
import cn.hutool.core.collection.CollUtil; 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.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.MenuListReqVO;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO; 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 cn.iocoder.yudao.module.system.service.tenant.TenantService;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
@ -18,12 +21,11 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import java.util.*;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 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.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.dal.dataobject.permission.MenuDO.ID_ROOT;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
@ -106,12 +108,57 @@ public class MenuServiceImpl implements MenuService {
@Override @Override
public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) { public List<MenuDO> getMenuListByTenant(MenuListReqVO reqVO) {
// 查询所有菜单并过滤掉关闭的节点
List<MenuDO> menus = getMenuList(reqVO); List<MenuDO> menus = getMenuList(reqVO);
// 开启多租户的情况下需要过滤掉未开通的菜单 // 开启多租户的情况下需要过滤掉未开通的菜单
tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId()))); tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
return menus; 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 @Override
public List<MenuDO> getMenuList(MenuListReqVO reqVO) { public List<MenuDO> getMenuList(MenuListReqVO reqVO) {
return menuMapper.selectList(reqVO); return menuMapper.selectList(reqVO);