diff --git a/.image/common/ai-feature.png b/.image/common/ai-feature.png
new file mode 100644
index 0000000000..b4a55f547c
Binary files /dev/null and b/.image/common/ai-feature.png differ
diff --git a/README.md b/README.md
index 59e5e427ed..cd8e578747 100644
--- a/README.md
+++ b/README.md
@@ -112,7 +112,7 @@
* 通用模块(必选):系统功能、基础设施
* 通用模块(可选):工作流程、支付系统、数据报表、会员中心
-* 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号
+* 业务系统(按需):ERP 系统、CRM 系统、商城系统、微信公众号、AI 大模型
> 友情提示:本项目基于 RuoYi-Vue 修改,**重构优化**后端的代码,**美化**前端的界面。
>
@@ -248,6 +248,12 @@
演示地址:
+### AI 大模型
+
+![功能图](/.image/common/ai-feature.png)
+
+演示地址:
+
## 🐨 技术栈
### 模块
@@ -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 模块 |
diff --git a/yudao-framework/yudao-spring-boot-starter-job/src/main/java/cn/iocoder/yudao/framework/quartz/core/util/CronUtils.java b/yudao-framework/yudao-spring-boot-starter-job/src/main/java/cn/iocoder/yudao/framework/quartz/core/util/CronUtils.java
index 9b5a2bff78..5658fa302a 100644
--- a/yudao-framework/yudao-spring-boot-starter-job/src/main/java/cn/iocoder/yudao/framework/quartz/core/util/CronUtils.java
+++ b/yudao-framework/yudao-spring-boot-starter-job/src/main/java/cn/iocoder/yudao/framework/quartz/core/util/CronUtils.java
@@ -34,20 +34,24 @@ public class CronUtils {
* @return 满足条件的执行时间
*/
public static List 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 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;
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
index 0f20f66c8a..245fca2867 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
@@ -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
diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
index fcfc805ce6..37aa477b02 100644
--- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
+++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmProcessDefinitionServiceImpl.java
@@ -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 getProcessDefinitionPage(BpmProcessDefinitionPageReqVO pageVO) {
ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
+ query.processDefinitionTenantId(FlowableUtils.getTenantId());
if (StrUtil.isNotBlank(pageVO.getKey())) {
query.processDefinitionKey(pageVO.getKey());
}
diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
index 68f2d210f4..cf8ae64837 100755
--- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
+++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/mysql/spu/ProductSpuMapper.java
@@ -30,7 +30,8 @@ public interface ProductSpuMapper extends BaseMapperX {
.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);
}
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java
index f3e0337c8b..e9677e665c 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java
+++ b/yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceTest.java
@@ -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,7 +73,9 @@ public class TradeOrderUpdateServiceTest extends BaseDbUnitTest {
private ProductSpuApi productSpuApi;
@MockBean
private ProductSkuApi productSkuApi;
-// @MockBean
+ @MockBean
+ private ProductCommentApi productCommentApi;
+ // @MockBean
// private PriceApi priceApi;
@MockBean
private PayOrderApi payOrderApi;
@@ -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 方法(支付单)
// 调用
diff --git a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
index d263fdfb92..f619c01de2 100644
--- a/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
+++ b/yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
@@ -1,128 +1,155 @@
-CREATE TABLE IF NOT EXISTS "trade_order" (
- "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
- "no" varchar NOT NULL,
- "type" int NOT NULL,
- "terminal" int NOT NULL,
- "user_id" bigint NOT NULL,
- "user_ip" varchar NOT NULL,
- "user_remark" varchar,
- "status" int NOT NULL,
- "product_count" int NOT NULL,
- "cancel_type" int,
- "remark" varchar,
- "pay_status" bit NOT NULL,
- "pay_time" datetime,
- "finish_time" datetime,
- "cancel_time" datetime,
- "original_price" int NOT NULL,
- "order_price" int NOT NULL,
- "discount_price" int NOT NULL,
- "delivery_price" int NOT NULL,
- "adjust_price" int NOT NULL,
- "pay_price" int NOT NULL,
- "pay_order_id" bigint,
- "pay_channel_code" varchar,
- "delivery_template_id" bigint,
- "logistics_id" bigint,
- "logistics_no" varchar,
- "delivery_time" datetime,
- "receive_time" datetime,
- "receiver_name" varchar NOT NULL,
- "receiver_mobile" varchar NOT NULL,
- "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,
- "coupon_id" bigint NOT NULL,
- "coupon_price" int NOT NULL,
- "point_price" 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")
+CREATE TABLE IF NOT EXISTS "trade_order"
+(
+ "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+ "no" varchar NOT NULL,
+ "type" int NOT NULL,
+ "terminal" int NOT NULL,
+ "user_id" bigint NOT NULL,
+ "user_ip" varchar NOT NULL,
+ "user_remark" varchar,
+ "status" int NOT NULL,
+ "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,
+ "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,
+ "logistics_id" bigint,
+ "logistics_no" varchar,
+ "delivery_time" datetime,
+ "receive_time" datetime,
+ "receiver_name" varchar NOT NULL,
+ "receiver_mobile" varchar NOT NULL,
+ "receiver_area_id" int NOT NULL,
+ "receiver_post_code" int,
+ "receiver_detail_address" varchar 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 '',
+ "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ "deleted" bit NOT NULL DEFAULT FALSE,
+ PRIMARY KEY ("id")
) COMMENT '交易订单表';
-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,
- "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,
- "discount_price" int NOT NULL,
- "pay_price" int NOT NULL,
- "order_part_price" int NOT NULL,
- "order_divide_price" int NOT 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")
+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,
+ "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,
+ "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,
+ "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 '交易订单明细表';
-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,
- "type" int NOT NULL,
- "way" int NOT NULL,
- "user_id" bigint NOT NULL,
- "apply_reason" varchar NOT NULL,
+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,
+ "type" int NOT NULL,
+ "way" int NOT NULL,
+ "user_id" bigint NOT NULL,
+ "apply_reason" varchar NOT NULL,
"apply_description" varchar,
"apply_pic_urls" varchar,
- "order_id" bigint NOT NULL,
- "order_no" varchar NOT NULL,
- "order_item_id" bigint NOT 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,
- "audit_time" varchar,
- "audit_user_id" bigint,
- "audit_reason" varchar,
- "refund_price" int NOT NULL,
- "pay_refund_id" bigint,
- "refund_time" varchar,
- "logistics_id" bigint,
- "logistics_no" varchar,
- "delivery_time" varchar,
- "receive_time" varchar,
+ "order_id" bigint NOT NULL,
+ "order_no" varchar NOT NULL,
+ "order_item_id" bigint NOT 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,
+ "audit_time" varchar,
+ "audit_user_id" bigint,
+ "audit_reason" varchar,
+ "refund_price" int NOT NULL,
+ "pay_refund_id" bigint,
+ "refund_time" varchar,
+ "logistics_id" bigint,
+ "logistics_no" varchar,
+ "delivery_time" varchar,
+ "receive_time" varchar,
"receive_reason" varchar,
- "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,
+ "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 '交易售后表';
-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,
- "after_sale_id" bigint NOT NULL,
- "order_id" bigint NOT NULL,
- "order_item_id" bigint NOT NULL,
+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,
+ "after_sale_id" bigint NOT NULL,
+ "order_id" bigint NOT NULL,
+ "order_item_id" bigint NOT NULL,
"before_status" int,
- "after_status" int NOT NULL,
- "content" varchar 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,
+ "after_status" int NOT NULL,
+ "content" varchar 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 '交易售后日志';
@@ -161,7 +188,7 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_record"
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"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_brokerage_withdraw"
@@ -186,6 +213,22 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw"
"updater" varchar DEFAULT '',
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
"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")
) COMMENT '佣金提现';
\ No newline at end of file
diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
index b244b8d1e1..e1a8ec562f 100644
--- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
+++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
@@ -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);
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
index 521e4e7cf7..2128ebe8ad 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
@@ -109,7 +109,7 @@ public class AuthController {
// 1.3 获得菜单列表
Set menuIds = permissionService.getRoleMenuListByRoleId(convertSet(roles, RoleDO::getId));
List 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));
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
index 1a0dca3313..3ee384e9be 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java
@@ -72,6 +72,7 @@ public class MenuController {
public CommonResult> getSimpleMenuList() {
List 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));
}
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java
index adc2b31518..d74dc61340 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java
@@ -52,6 +52,14 @@ public interface MenuService {
*/
List getMenuListByTenant(MenuListReqVO reqVO);
+ /**
+ * 过滤掉关闭的菜单及其子菜单
+ *
+ * @param list 菜单列表
+ * @return 过滤后的菜单列表
+ */
+ List filterDisableMenus(List list);
+
/**
* 筛选菜单列表
*
diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
index e20bd70af4..730958f82e 100644
--- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
+++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java
@@ -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 getMenuListByTenant(MenuListReqVO reqVO) {
+ // 查询所有菜单,并过滤掉关闭的节点
List menus = getMenuList(reqVO);
// 开启多租户的情况下,需要过滤掉未开通的菜单
tenantService.handleTenantMenu(menuIds -> menus.removeIf(menu -> !CollUtil.contains(menuIds, menu.getId())));
return menus;
}
+ @Override
+ public List filterDisableMenus(List menuList) {
+ if (CollUtil.isEmpty(menuList)){
+ return Collections.emptyList();
+ }
+ Map menuMap = convertMap(menuList, MenuDO::getId);
+
+ // 遍历 menu 菜单,查找不是禁用的菜单,添加到 enabledMenus 结果
+ List enabledMenus = new ArrayList<>();
+ Set disabledMenuCache = new HashSet<>(); // 存下递归搜索过被禁用的菜单,防止重复的搜索
+ for (MenuDO menu : menuList) {
+ if (isMenuDisabled(menu, menuMap, disabledMenuCache)) {
+ continue;
+ }
+ enabledMenus.add(menu);
+ }
+ return enabledMenus;
+ }
+
+ private boolean isMenuDisabled(MenuDO node, Map menuMap, Set 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 getMenuList(MenuListReqVO reqVO) {
return menuMapper.selectList(reqVO);