|
@@ -147,11 +147,8 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
|
|
|
throw new RuntimeException("订单金额未达到优惠券最低消费要求");
|
|
throw new RuntimeException("订单金额未达到优惠券最低消费要求");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 计算优惠金额
|
|
|
|
|
- discountAmount = coupon.getNominalValue();
|
|
|
|
|
- if (discountAmount.compareTo(totalWithTableware) > 0) {
|
|
|
|
|
- discountAmount = totalWithTableware;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ // 计算优惠金额:根据优惠券类型(满减券或折扣券)计算
|
|
|
|
|
+ discountAmount = calculateDiscountAmount(coupon, totalWithTableware);
|
|
|
|
|
|
|
|
// 标记桌号已使用优惠券
|
|
// 标记桌号已使用优惠券
|
|
|
cartService.markCouponUsed(dto.getTableId(), dto.getCouponId());
|
|
cartService.markCouponUsed(dto.getTableId(), dto.getCouponId());
|
|
@@ -456,7 +453,7 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public IPage<StoreOrder> getOrderPage(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus) {
|
|
|
|
|
|
|
+ public IPage<StoreOrder> getOrderPage(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus, String keyword) {
|
|
|
LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper<>();
|
|
|
wrapper.eq(StoreOrder::getDeleteFlag, 0);
|
|
wrapper.eq(StoreOrder::getDeleteFlag, 0);
|
|
|
if (storeId != null) {
|
|
if (storeId != null) {
|
|
@@ -468,18 +465,121 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
|
|
|
if (orderStatus != null) {
|
|
if (orderStatus != null) {
|
|
|
wrapper.eq(StoreOrder::getOrderStatus, orderStatus);
|
|
wrapper.eq(StoreOrder::getOrderStatus, orderStatus);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ // 搜索功能:按订单编号模糊搜索
|
|
|
|
|
+ if (StringUtils.hasText(keyword)) {
|
|
|
|
|
+ // 限制搜索关键词长度(15字)
|
|
|
|
|
+ String searchKeyword = keyword.length() > 15 ? keyword.substring(0, 15) : keyword;
|
|
|
|
|
+ wrapper.like(StoreOrder::getOrderNo, searchKeyword);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
wrapper.orderByDesc(StoreOrder::getCreatedTime);
|
|
wrapper.orderByDesc(StoreOrder::getCreatedTime);
|
|
|
return this.page(page, wrapper);
|
|
return this.page(page, wrapper);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
- public IPage<StoreOrderPageVO> getOrderPageWithCuisines(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus) {
|
|
|
|
|
- log.info("分页查询订单列表(包含菜品信息), storeId={}, tableId={}, orderStatus={}", storeId, tableId, orderStatus);
|
|
|
|
|
|
|
+ public IPage<StoreOrderPageVO> getOrderPageWithCuisines(Page<StoreOrder> page, Integer storeId, Integer tableId, Integer orderStatus, String keyword) {
|
|
|
|
|
+ log.info("分页查询订单列表(包含菜品信息), storeId={}, tableId={}, orderStatus={}, keyword={}", storeId, tableId, orderStatus, keyword);
|
|
|
|
|
|
|
|
- // 1. 查询订单列表
|
|
|
|
|
- IPage<StoreOrder> orderPage = getOrderPage(page, storeId, tableId, orderStatus);
|
|
|
|
|
|
|
+ // 限制搜索关键词长度(15字)
|
|
|
|
|
+ String searchKeyword = null;
|
|
|
|
|
+ if (StringUtils.hasText(keyword)) {
|
|
|
|
|
+ searchKeyword = keyword.length() > 15 ? keyword.substring(0, 15) : keyword;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- // 2. 获取所有订单ID
|
|
|
|
|
|
|
+ // 1. 如果有关键词,需要同时支持按订单编号和菜品名称搜索
|
|
|
|
|
+ final Set<Integer> matchingOrderIds;
|
|
|
|
|
+ if (StringUtils.hasText(searchKeyword)) {
|
|
|
|
|
+ Set<Integer> orderIdsSet = new HashSet<>();
|
|
|
|
|
+
|
|
|
|
|
+ // 1.1 按订单编号搜索
|
|
|
|
|
+ LambdaQueryWrapper<StoreOrder> orderNoWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ orderNoWrapper.eq(StoreOrder::getDeleteFlag, 0)
|
|
|
|
|
+ .like(StoreOrder::getOrderNo, searchKeyword);
|
|
|
|
|
+ if (storeId != null) {
|
|
|
|
|
+ orderNoWrapper.eq(StoreOrder::getStoreId, storeId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (tableId != null) {
|
|
|
|
|
+ orderNoWrapper.eq(StoreOrder::getTableId, tableId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (orderStatus != null) {
|
|
|
|
|
+ orderNoWrapper.eq(StoreOrder::getOrderStatus, orderStatus);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<StoreOrder> orderNoMatches = this.list(orderNoWrapper);
|
|
|
|
|
+ orderNoMatches.forEach(order -> orderIdsSet.add(order.getId()));
|
|
|
|
|
+
|
|
|
|
|
+ // 1.2 按菜品名称搜索
|
|
|
|
|
+ LambdaQueryWrapper<StoreOrderDetail> detailSearchWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ detailSearchWrapper.select(StoreOrderDetail::getOrderId)
|
|
|
|
|
+ .like(StoreOrderDetail::getCuisineName, searchKeyword)
|
|
|
|
|
+ .eq(StoreOrderDetail::getDeleteFlag, 0);
|
|
|
|
|
+
|
|
|
|
|
+ // 如果有限制条件,需要先查询符合条件的订单ID
|
|
|
|
|
+ if (storeId != null || tableId != null || orderStatus != null) {
|
|
|
|
|
+ LambdaQueryWrapper<StoreOrder> filterWrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ filterWrapper.eq(StoreOrder::getDeleteFlag, 0)
|
|
|
|
|
+ .select(StoreOrder::getId);
|
|
|
|
|
+ if (storeId != null) {
|
|
|
|
|
+ filterWrapper.eq(StoreOrder::getStoreId, storeId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (tableId != null) {
|
|
|
|
|
+ filterWrapper.eq(StoreOrder::getTableId, tableId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (orderStatus != null) {
|
|
|
|
|
+ filterWrapper.eq(StoreOrder::getOrderStatus, orderStatus);
|
|
|
|
|
+ }
|
|
|
|
|
+ List<StoreOrder> filteredOrders = this.list(filterWrapper);
|
|
|
|
|
+ Set<Integer> filteredOrderIds = filteredOrders.stream()
|
|
|
|
|
+ .map(StoreOrder::getId)
|
|
|
|
|
+ .collect(Collectors.toSet());
|
|
|
|
|
+ if (!filteredOrderIds.isEmpty()) {
|
|
|
|
|
+ detailSearchWrapper.in(StoreOrderDetail::getOrderId, filteredOrderIds);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有符合条件的订单,直接返回空结果
|
|
|
|
|
+ Page<StoreOrderPageVO> emptyPage = new Page<>(page.getCurrent(), page.getSize());
|
|
|
|
|
+ emptyPage.setTotal(0);
|
|
|
|
|
+ emptyPage.setPages(0);
|
|
|
|
|
+ return emptyPage;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ List<StoreOrderDetail> matchingDetails = orderDetailMapper.selectList(detailSearchWrapper);
|
|
|
|
|
+ matchingDetails.forEach(detail -> orderIdsSet.add(detail.getOrderId()));
|
|
|
|
|
+
|
|
|
|
|
+ matchingOrderIds = orderIdsSet;
|
|
|
|
|
+
|
|
|
|
|
+ // 如果没有任何匹配的订单,返回空结果
|
|
|
|
|
+ if (matchingOrderIds.isEmpty()) {
|
|
|
|
|
+ Page<StoreOrderPageVO> emptyPage = new Page<>(page.getCurrent(), page.getSize());
|
|
|
|
|
+ emptyPage.setTotal(0);
|
|
|
|
|
+ emptyPage.setPages(0);
|
|
|
|
|
+ return emptyPage;
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ matchingOrderIds = null;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 查询订单列表
|
|
|
|
|
+ LambdaQueryWrapper<StoreOrder> wrapper = new LambdaQueryWrapper<>();
|
|
|
|
|
+ wrapper.eq(StoreOrder::getDeleteFlag, 0);
|
|
|
|
|
+ if (storeId != null) {
|
|
|
|
|
+ wrapper.eq(StoreOrder::getStoreId, storeId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (tableId != null) {
|
|
|
|
|
+ wrapper.eq(StoreOrder::getTableId, tableId);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (orderStatus != null) {
|
|
|
|
|
+ wrapper.eq(StoreOrder::getOrderStatus, orderStatus);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果有关键词搜索,只查询匹配的订单ID
|
|
|
|
|
+ if (matchingOrderIds != null && !matchingOrderIds.isEmpty()) {
|
|
|
|
|
+ wrapper.in(StoreOrder::getId, matchingOrderIds);
|
|
|
|
|
+ }
|
|
|
|
|
+ wrapper.orderByDesc(StoreOrder::getCreatedTime);
|
|
|
|
|
+
|
|
|
|
|
+ IPage<StoreOrder> orderPage = this.page(page, wrapper);
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 获取所有订单ID
|
|
|
List<StoreOrder> orders = orderPage.getRecords();
|
|
List<StoreOrder> orders = orderPage.getRecords();
|
|
|
if (orders == null || orders.isEmpty()) {
|
|
if (orders == null || orders.isEmpty()) {
|
|
|
// 如果没有订单,返回空的分页结果
|
|
// 如果没有订单,返回空的分页结果
|
|
@@ -1600,4 +1700,44 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
|
|
|
log.info("换桌完成, fromTableId={}, toTableId={}", fromTableId, toTableId);
|
|
log.info("换桌完成, fromTableId={}, toTableId={}", fromTableId, toTableId);
|
|
|
return cart;
|
|
return cart;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算优惠金额:根据优惠券类型(满减券或折扣券)计算
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param coupon 优惠券对象
|
|
|
|
|
+ * @param totalWithTableware 订单总金额(含餐具费)
|
|
|
|
|
+ * @return 优惠金额
|
|
|
|
|
+ */
|
|
|
|
|
+ private BigDecimal calculateDiscountAmount(LifeDiscountCoupon coupon, BigDecimal totalWithTableware) {
|
|
|
|
|
+ if (coupon == null || totalWithTableware == null || totalWithTableware.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Integer couponType = coupon.getCouponType();
|
|
|
|
|
+ BigDecimal discountAmount = BigDecimal.ZERO;
|
|
|
|
|
+
|
|
|
|
|
+ if (couponType != null && couponType == 2) {
|
|
|
|
|
+ // 折扣券:根据折扣率计算优惠金额
|
|
|
|
|
+ // discountRate: 0-100,例如80表示8折,优惠金额 = 订单金额 * (100 - discountRate) / 100
|
|
|
|
|
+ BigDecimal discountRate = coupon.getDiscountRate();
|
|
|
|
|
+ if (discountRate != null && discountRate.compareTo(BigDecimal.ZERO) > 0 && discountRate.compareTo(new BigDecimal(100)) <= 0) {
|
|
|
|
|
+ // 计算折扣后的金额
|
|
|
|
|
+ BigDecimal discountedAmount = totalWithTableware.multiply(discountRate).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
|
|
|
|
|
+ // 优惠金额 = 原价 - 折扣后价格
|
|
|
|
|
+ discountAmount = totalWithTableware.subtract(discountedAmount);
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 满减券(默认或couponType=1):使用nominalValue
|
|
|
|
|
+ discountAmount = coupon.getNominalValue();
|
|
|
|
|
+ if (discountAmount == null) {
|
|
|
|
|
+ discountAmount = BigDecimal.ZERO;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 优惠金额不能超过订单总金额
|
|
|
|
|
+ if (discountAmount.compareTo(totalWithTableware) > 0) {
|
|
|
|
|
+ discountAmount = totalWithTableware;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return discountAmount;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|