Jelajahi Sumber

抽取公共校验类

lutong 2 minggu lalu
induk
melakukan
1a92459cab

+ 11 - 14
alien-dining/src/main/java/shop/alien/dining/service/impl/CartServiceImpl.java

@@ -24,7 +24,7 @@ import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.StoreProductDiscountRuleMapper;
 import shop.alien.mapper.StoreTableMapper;
 import shop.alien.dining.support.DiningMenuPricing;
-import shop.alien.dining.support.StoreBusinessSectionOrdering;
+import shop.alien.dining.support.DiningOrderingTableGuard;
 import shop.alien.dining.support.StoreCartMenuFilters;
 import shop.alien.dining.constants.OrderMenuConstants;
 import shop.alien.dining.util.TokenUtil;
@@ -71,16 +71,7 @@ public class CartServiceImpl implements CartService {
     private final StoreCouponUsageMapper storeCouponUsageMapper;
     private final StoreInfoMapper storeInfoMapper;
     private final StoreProductDiscountRuleMapper storeProductDiscountRuleMapper;
-
-    private void assertCuisineTableForCart(StoreTable table) {
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        StoreInfo info = storeInfoMapper.selectById(table.getStoreId());
-        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(info, table)) {
-            throw new RuntimeException("当前桌台不适用美食购物车,请使用通用价目入口");
-        }
-    }
+    private final DiningOrderingTableGuard diningOrderingTableGuard;
 
     @Override
     public CartDTO getCart(Integer tableId) {
@@ -261,7 +252,10 @@ public class CartServiceImpl implements CartService {
         log.info("添加商品到购物车, dto={}", dto);
         // 验证桌号
         StoreTable table = storeTableMapper.selectById(dto.getTableId());
-        assertCuisineTableForCart(table);
+        if (table == null) {
+            throw new RuntimeException("桌号不存在");
+        }
+        diningOrderingTableGuard.assertCuisineMenuAllowed(table);
 
         // 验证菜品
         StoreCuisine cuisine = storeCuisineMapper.selectById(dto.getCuisineId());
@@ -367,7 +361,10 @@ public class CartServiceImpl implements CartService {
             log.info("商品不在购物车中,自动添加, tableId={}, cuisineId={}, quantity={}", tableId, cuisineId, quantity);
 
             StoreTable table = storeTableMapper.selectById(tableId);
-            assertCuisineTableForCart(table);
+            if (table == null) {
+                throw new RuntimeException("桌号不存在");
+            }
+            diningOrderingTableGuard.assertCuisineMenuAllowed(table);
 
             // 验证菜品
             StoreCuisine cuisine = storeCuisineMapper.selectById(cuisineId);
@@ -581,7 +578,7 @@ public class CartServiceImpl implements CartService {
         if (toTable == null) {
             throw new RuntimeException("目标桌号不存在");
         }
-        assertCuisineTableForCart(toTable);
+        diningOrderingTableGuard.assertCuisineMenuAllowed(toTable);
 
         // 获取目标购物车
         CartDTO toCart = getCart(toTableId);

+ 24 - 69
alien-dining/src/main/java/shop/alien/dining/service/impl/DiningServiceImpl.java

@@ -11,11 +11,12 @@ import shop.alien.entity.store.dto.CartDTO;
 import shop.alien.entity.store.dto.CartItemDTO;
 import shop.alien.entity.store.vo.*;
 import shop.alien.mapper.*;
-import shop.alien.dining.config.BaseRedisService;
 import shop.alien.dining.service.CartService;
 import shop.alien.dining.service.DiningService;
 import shop.alien.dining.support.DiningOrderServiceFeeCalculator;
-import shop.alien.dining.support.StoreBusinessSectionOrdering;
+import shop.alien.dining.support.DiningFirstVisitDinerCount;
+import shop.alien.dining.support.DiningOrderingTableGuard;
+import shop.alien.dining.support.DiningSearchText;
 
 import java.math.BigDecimal;
 import java.time.LocalDate;
@@ -36,30 +37,23 @@ public class DiningServiceImpl implements DiningService {
     private final StoreTableMapper storeTableMapper;
     private final StoreInfoMapper storeInfoMapper;
     private final StoreCuisineMapper storeCuisineMapper;
-    private final StoreCuisineCategoryMapper storeCuisineCategoryMapper;
     private final StoreCuisineComboMapper storeCuisineComboMapper;
     private final StoreOrderDetailMapper storeOrderDetailMapper;
     private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
     private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
     private final CartService cartService;
-    private final BaseRedisService baseRedisService;
     private final shop.alien.dining.service.StoreOrderService storeOrderService;
-    private final shop.alien.mapper.StoreOrderMapper storeOrderMapper;
     private final shop.alien.dining.service.OrderLockService orderLockService;
     private final DiningOrderServiceFeeCalculator diningOrderServiceFeeCalculator;
+    private final DiningOrderingTableGuard diningOrderingTableGuard;
 
     @Override
     public DiningServiceFeeEstimateVO estimateServiceFee(Integer storeId, Integer tableId, Integer dinerCount, BigDecimal goodsSubtotal) {
         if (storeId == null || tableId == null) {
             throw new RuntimeException("门店ID与桌号ID不能为空");
         }
-        StoreTable table = storeTableMapper.selectById(tableId);
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        if (table.getStoreId() == null || !table.getStoreId().equals(storeId)) {
-            throw new RuntimeException("桌号与门店不匹配");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertTableBelongsToStore(table, storeId);
         return diningOrderServiceFeeCalculator.estimate(storeId, tableId, new Date(), dinerCount, goodsSubtotal);
     }
 
@@ -87,37 +81,23 @@ public class DiningServiceImpl implements DiningService {
     @Override
     public DiningPageInfoVO getDiningPageInfo(Integer tableId, Integer dinerCount) {
         log.info("获取点餐页面信息, tableId={}, dinerCount={}", tableId, dinerCount);
-        StoreTable table = storeTableMapper.selectById(tableId);
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        StoreInfo storeInfo = diningOrderingTableGuard.requireStore(table);
+        diningOrderingTableGuard.assertCuisineMenuAllowed(storeInfo, table);
 
-        StoreInfo storeInfo = storeInfoMapper.selectById(table.getStoreId());
-        if (storeInfo == null) {
-            throw new RuntimeException("门店不存在");
-        }
-        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(storeInfo, table)) {
-            throw new RuntimeException("当前门店适用通用价目点餐,请使用通用价目入口");
-        }
-
-        // 选择人数:只落库就餐人数,不把餐桌置为就餐中;开台在提交到店/用餐信息(walk-in)时处理
-        if (dinerCount != null && dinerCount > 0) {
-            table.setDinerCount(dinerCount);
+        int resolvedDinerCount = DiningFirstVisitDinerCount.resolveOrThrow(table, dinerCount);
+        if (DiningFirstVisitDinerCount.shouldPersistToDatabase(dinerCount)) {
             storeTableMapper.updateById(table);
-            log.info("首客填写用餐人数(餐桌状态不变,未开台), tableId={}, dinerCount={}", tableId, dinerCount);
+            log.info("首客填写用餐人数(餐桌状态不变,未开台), tableId={}, dinerCount={}", tableId, resolvedDinerCount);
         } else {
-            if (table.getDinerCount() != null && table.getDinerCount() > 0) {
-                dinerCount = table.getDinerCount();
-                log.info("使用已保存的就餐人数, tableId={}, dinerCount={}, tableStatus={}", tableId, dinerCount, table.getStatus());
-            } else {
-                throw new RuntimeException("请选择用餐人数");
-            }
+            log.info("使用已保存的就餐人数, tableId={}, dinerCount={}, tableStatus={}",
+                    tableId, resolvedDinerCount, table.getStatus());
         }
 
         DiningPageInfoVO vo = new DiningPageInfoVO();
         vo.setStoreName(storeInfo.getStoreName());
         vo.setTableNumber(table.getTableNumber());
-        vo.setDinerCount(dinerCount);
+        vo.setDinerCount(resolvedDinerCount);
         vo.setStoreId(table.getStoreId());
         vo.setTableId(tableId);
 
@@ -128,22 +108,11 @@ public class DiningServiceImpl implements DiningService {
     public List<CuisineListVO> searchCuisines(Integer storeId, String keyword, Integer tableId) {
         log.info("搜索菜品, storeId={}, keyword={}, tableId={}", storeId, keyword, tableId);
 
-        StoreTable table = storeTableMapper.selectById(tableId);
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        if (!Objects.equals(table.getStoreId(), storeId)) {
-            throw new RuntimeException("门店与桌台不匹配");
-        }
-        StoreInfo storeInfoForTable = storeInfoMapper.selectById(storeId);
-        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(storeInfoForTable, table)) {
-            throw new RuntimeException("当前门店适用通用价目点餐,请使用通用价目入口");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertTableBelongsToStore(table, storeId);
+        diningOrderingTableGuard.assertCuisineMenuAllowed(table);
 
-        // 限制搜索关键词长度
-        if (StringUtils.hasText(keyword) && keyword.length() > 10) {
-            keyword = keyword.substring(0, 10);
-        }
+        keyword = DiningSearchText.clampKeyword(keyword);
 
         LambdaQueryWrapper<StoreCuisine> wrapper = new LambdaQueryWrapper<>();
         wrapper.eq(StoreCuisine::getStoreId, storeId);
@@ -162,17 +131,9 @@ public class DiningServiceImpl implements DiningService {
     public List<CuisineListVO> getCuisinesByCategory(Integer storeId, Integer categoryId, Integer tableId, Integer page, Integer size) {
         log.info("根据分类获取菜品列表, storeId={}, categoryId={}, tableId={}, page={}, size={}", storeId, categoryId, tableId, page, size);
 
-        StoreTable table = storeTableMapper.selectById(tableId);
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        if (!Objects.equals(table.getStoreId(), storeId)) {
-            throw new RuntimeException("门店与桌台不匹配");
-        }
-        StoreInfo storeInfoForTable = storeInfoMapper.selectById(storeId);
-        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(storeInfoForTable, table)) {
-            throw new RuntimeException("当前门店适用通用价目点餐,请使用通用价目入口");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertTableBelongsToStore(table, storeId);
+        diningOrderingTableGuard.assertCuisineMenuAllowed(table);
 
         if (page == null || page < 1) {
             page = 1;
@@ -208,17 +169,11 @@ public class DiningServiceImpl implements DiningService {
             throw new RuntimeException("菜品不存在");
         }
 
-        StoreTable table = storeTableMapper.selectById(tableId);
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
         if (!Objects.equals(cuisine.getStoreId(), table.getStoreId())) {
             throw new RuntimeException("菜品与桌台门店不匹配");
         }
-        StoreInfo storeInfoForTable = storeInfoMapper.selectById(table.getStoreId());
-        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(storeInfoForTable, table)) {
-            throw new RuntimeException("当前门店适用通用价目点餐,请使用通用价目入口");
-        }
+        diningOrderingTableGuard.assertCuisineMenuAllowed(table);
 
         CuisineDetailVO vo = new CuisineDetailVO();
         // 手动映射所有字段,确保所有属性都被正确复制

+ 10 - 13
alien-dining/src/main/java/shop/alien/dining/service/impl/GenericCartServiceImpl.java

@@ -25,7 +25,7 @@ import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.StoreProductDiscountRuleMapper;
 import shop.alien.mapper.StoreTableMapper;
 import shop.alien.dining.support.DiningMenuPricing;
-import shop.alien.dining.support.StoreBusinessSectionOrdering;
+import shop.alien.dining.support.DiningOrderingTableGuard;
 import shop.alien.dining.support.StoreCartMenuFilters;
 import shop.alien.dining.util.TokenUtil;
 
@@ -68,16 +68,7 @@ public class GenericCartServiceImpl implements GenericCartService {
     private final StoreCouponUsageMapper storeCouponUsageMapper;
     private final StoreInfoMapper storeInfoMapper;
     private final StoreProductDiscountRuleMapper storeProductDiscountRuleMapper;
-
-    private void assertGenericTableForCart(StoreTable table) {
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        StoreInfo info = storeInfoMapper.selectById(table.getStoreId());
-        if (!StoreBusinessSectionOrdering.allowsGenericPricing(info, table)) {
-            throw new RuntimeException("当前桌台不适用通用价目购物车,请使用美食点餐入口");
-        }
-    }
+    private final DiningOrderingTableGuard diningOrderingTableGuard;
 
     @Override
     public CartDTO getCart(Integer tableId) {
@@ -257,7 +248,10 @@ public class GenericCartServiceImpl implements GenericCartService {
     public CartDTO addItem(AddCartItemDTO dto) {
         log.info("添加商品到购物车, dto={}", dto);
         StoreTable table = storeTableMapper.selectById(dto.getTableId());
-        assertGenericTableForCart(table);
+        if (table == null) {
+            throw new RuntimeException("桌号不存在");
+        }
+        diningOrderingTableGuard.assertGenericMenuAllowed(table);
 
         // dto.cuisineId 此处表示 store_price.id
         StorePrice price = storePriceMapper.selectById(dto.getCuisineId());
@@ -361,7 +355,10 @@ public class GenericCartServiceImpl implements GenericCartService {
         } else {
             log.info("商品不在购物车中,自动添加, tableId={}, priceId={}, quantity={}", tableId, cuisineId, quantity);
             StoreTable t = storeTableMapper.selectById(tableId);
-            assertGenericTableForCart(t);
+            if (t == null) {
+                throw new RuntimeException("桌号不存在");
+            }
+            diningOrderingTableGuard.assertGenericMenuAllowed(t);
             StorePrice price = storePriceMapper.selectById(cuisineId);
             if (price == null) {
                 throw new RuntimeException("价目项不存在");

+ 23 - 45
alien-dining/src/main/java/shop/alien/dining/service/impl/GenericDiningServiceImpl.java

@@ -11,7 +11,9 @@ import shop.alien.dining.service.DiningService;
 import shop.alien.dining.service.GenericCartService;
 import shop.alien.dining.service.GenericDiningService;
 import shop.alien.dining.service.OrderLockService;
-import shop.alien.dining.support.StoreBusinessSectionOrdering;
+import shop.alien.dining.support.DiningFirstVisitDinerCount;
+import shop.alien.dining.support.DiningOrderingTableGuard;
+import shop.alien.dining.support.DiningSearchText;
 import shop.alien.entity.store.LifeDiscountCoupon;
 import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.store.StoreOrderDetail;
@@ -25,7 +27,6 @@ import shop.alien.entity.store.vo.CuisineListVO;
 import shop.alien.entity.store.vo.DiningPageInfoVO;
 import shop.alien.entity.store.vo.OrderConfirmVO;
 import shop.alien.mapper.LifeDiscountCouponMapper;
-import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.StoreOrderDetailMapper;
 import shop.alien.mapper.StorePriceMapper;
 import shop.alien.mapper.StoreTableMapper;
@@ -47,52 +48,35 @@ import java.util.stream.Collectors;
 public class GenericDiningServiceImpl implements GenericDiningService {
 
     private final StoreTableMapper storeTableMapper;
-    private final StoreInfoMapper storeInfoMapper;
     private final StorePriceMapper storePriceMapper;
     private final GenericCartService genericCartService;
     private final OrderLockService orderLockService;
     private final LifeDiscountCouponMapper lifeDiscountCouponMapper;
     private final StoreOrderDetailMapper storeOrderDetailMapper;
     private final DiningService diningService;
-
-    private void assertGenericTable(StoreTable table) {
-        if (table == null) {
-            throw new RuntimeException("桌号不存在");
-        }
-        StoreInfo storeInfo = storeInfoMapper.selectById(table.getStoreId());
-        if (!StoreBusinessSectionOrdering.allowsGenericPricing(storeInfo, table)) {
-            throw new RuntimeException("当前门店/桌台不适用通用价目点餐,请使用美食点餐入口");
-        }
-    }
+    private final DiningOrderingTableGuard diningOrderingTableGuard;
 
     @Override
     public DiningPageInfoVO getDiningPageInfo(Integer tableId, Integer dinerCount) {
         log.info("通用价目-获取点餐页面信息, tableId={}, dinerCount={}", tableId, dinerCount);
-        StoreTable table = storeTableMapper.selectById(tableId);
-        assertGenericTable(table);
-
-        StoreInfo storeInfo = storeInfoMapper.selectById(table.getStoreId());
-        if (storeInfo == null) {
-            throw new RuntimeException("门店不存在");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        StoreInfo storeInfo = diningOrderingTableGuard.requireStore(table);
+        diningOrderingTableGuard.assertGenericMenuAllowed(storeInfo, table);
 
-        if (dinerCount != null && dinerCount > 0) {
-            table.setDinerCount(dinerCount);
+        int resolvedDinerCount = DiningFirstVisitDinerCount.resolveOrThrow(table, dinerCount);
+        if (DiningFirstVisitDinerCount.shouldPersistToDatabase(dinerCount)) {
             storeTableMapper.updateById(table);
-            log.info("通用价目-首客填写用餐人数(餐桌状态不变,未开台), tableId={}, dinerCount={}", tableId, dinerCount);
+            log.info("通用价目-首客填写用餐人数(餐桌状态不变,未开台), tableId={}, dinerCount={}",
+                    tableId, resolvedDinerCount);
         } else {
-            if (table.getDinerCount() != null && table.getDinerCount() > 0) {
-                dinerCount = table.getDinerCount();
-                log.info("通用价目-使用已保存人数, tableId={}, dinerCount={}, tableStatus={}", tableId, dinerCount, table.getStatus());
-            } else {
-                throw new RuntimeException("请选择用餐人数");
-            }
+            log.info("通用价目-使用已保存人数, tableId={}, dinerCount={}, tableStatus={}",
+                    tableId, resolvedDinerCount, table.getStatus());
         }
 
         DiningPageInfoVO vo = new DiningPageInfoVO();
         vo.setStoreName(storeInfo.getStoreName());
         vo.setTableNumber(table.getTableNumber());
-        vo.setDinerCount(dinerCount);
+        vo.setDinerCount(resolvedDinerCount);
         vo.setStoreId(table.getStoreId());
         vo.setTableId(tableId);
         return vo;
@@ -110,15 +94,11 @@ public class GenericDiningServiceImpl implements GenericDiningService {
     @Override
     public List<CuisineListVO> searchCuisines(Integer storeId, String keyword, Integer tableId) {
         log.info("通用价目-搜索, storeId={}, keyword={}, tableId={}", storeId, keyword, tableId);
-        StoreTable table = storeTableMapper.selectById(tableId);
-        assertGenericTable(table);
-        if (!Objects.equals(table.getStoreId(), storeId)) {
-            throw new RuntimeException("门店与桌台不匹配");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertTableBelongsToStore(table, storeId);
+        diningOrderingTableGuard.assertGenericMenuAllowed(table);
 
-        if (StringUtils.hasText(keyword) && keyword.length() > 10) {
-            keyword = keyword.substring(0, 10);
-        }
+        keyword = DiningSearchText.clampKeyword(keyword);
 
         LambdaQueryWrapper<StorePrice> wrapper = baseOnShelfApproved(storeId);
         if (StringUtils.hasText(keyword)) {
@@ -131,11 +111,9 @@ public class GenericDiningServiceImpl implements GenericDiningService {
     @Override
     public List<CuisineListVO> getCuisinesByCategory(Integer storeId, Integer categoryId, Integer tableId, Integer page, Integer size) {
         log.info("通用价目-分类列表, storeId={}, categoryId={}, tableId={}, page={}, size={}", storeId, categoryId, tableId, page, size);
-        StoreTable table = storeTableMapper.selectById(tableId);
-        assertGenericTable(table);
-        if (!Objects.equals(table.getStoreId(), storeId)) {
-            throw new RuntimeException("门店与桌台不匹配");
-        }
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertTableBelongsToStore(table, storeId);
+        diningOrderingTableGuard.assertGenericMenuAllowed(table);
 
         if (page == null || page < 1) {
             page = 1;
@@ -157,8 +135,8 @@ public class GenericDiningServiceImpl implements GenericDiningService {
     @Override
     public CuisineDetailVO getCuisineDetail(Integer priceItemId, Integer tableId) {
         log.info("通用价目-详情, priceItemId={}, tableId={}", priceItemId, tableId);
-        StoreTable table = storeTableMapper.selectById(tableId);
-        assertGenericTable(table);
+        StoreTable table = diningOrderingTableGuard.requireTable(tableId);
+        diningOrderingTableGuard.assertGenericMenuAllowed(table);
 
         StorePrice price = storePriceMapper.selectById(priceItemId);
         if (price == null || !Objects.equals(price.getStoreId(), table.getStoreId())) {

+ 3 - 11
alien-dining/src/main/java/shop/alien/dining/service/impl/StoreOrderServiceImpl.java

@@ -14,7 +14,7 @@ import shop.alien.dining.config.BaseRedisService;
 import shop.alien.dining.service.CartService;
 import shop.alien.dining.service.StoreOrderService;
 import shop.alien.dining.support.DiningMenuPricing;
-import shop.alien.dining.support.StoreBusinessSectionOrdering;
+import shop.alien.dining.support.DiningOrderingTableGuard;
 import shop.alien.dining.util.TokenUtil;
 import shop.alien.dining.constants.OrderMenuConstants;
 import shop.alien.dining.service.GenericCartService;
@@ -79,6 +79,7 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
     private final LifeDiscountCouponUserMapper lifeDiscountCouponUserMapper;
     private final GenericCartService genericCartService;
     private final StorePriceMapper storePriceMapper;
+    private final DiningOrderingTableGuard diningOrderingTableGuard;
 
     @Override
     public StoreOrder createOrder(CreateOrderDTO dto) {
@@ -116,16 +117,7 @@ public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOr
             throw new RuntimeException("门店不存在");
         }
 
-        int effectiveMenuType = StoreBusinessSectionOrdering.resolveEffectiveMenuType(storeInfo, table);
-        if (menuType == OrderMenuConstants.MENU_TYPE_GENERIC_PRICE) {
-            if (effectiveMenuType != OrderMenuConstants.MENU_TYPE_GENERIC_PRICE) {
-                throw new RuntimeException("当前门店/桌台不适用通用价目点餐,请使用美食点餐入口");
-            }
-        } else {
-            if (effectiveMenuType != OrderMenuConstants.MENU_TYPE_CUISINE) {
-                throw new RuntimeException("当前门店/桌台请使用通用价目点餐接口下单");
-            }
-        }
+        diningOrderingTableGuard.assertOrderMenuTypeAllowed(storeInfo, table, menuType);
 
         // 获取购物车
         CartDTO cart = menuType == OrderMenuConstants.MENU_TYPE_GENERIC_PRICE

+ 35 - 0
alien-dining/src/main/java/shop/alien/dining/support/DiningFirstVisitDinerCount.java

@@ -0,0 +1,35 @@
+package shop.alien.dining.support;
+
+import shop.alien.entity.store.StoreTable;
+
+/**
+ * 点餐页首访:填写或沿用桌台已保存的「就餐人数」(不落开台状态,仅更新 {@link StoreTable#getDinerCount} 可能待持久化字段)。
+ */
+public final class DiningFirstVisitDinerCount {
+
+    private DiningFirstVisitDinerCount() {
+    }
+
+    /**
+     * 本次请求是否带了有效人数并需要写回库(调用方在 true 时应对 table 执行 update)。
+     */
+    public static boolean shouldPersistToDatabase(Integer dinerCountFromRequest) {
+        return dinerCountFromRequest != null && dinerCountFromRequest > 0;
+    }
+
+    /**
+     * 解析最终就餐人数:请求有效则写入 table 暂存字段;否则沿用桌台已有正数人数;皆无则抛错。
+     *
+     * @return 用于展示与后续业务的正整数人数
+     */
+    public static int resolveOrThrow(StoreTable table, Integer dinerCountFromRequest) {
+        if (shouldPersistToDatabase(dinerCountFromRequest)) {
+            table.setDinerCount(dinerCountFromRequest);
+            return dinerCountFromRequest;
+        }
+        if (table.getDinerCount() != null && table.getDinerCount() > 0) {
+            return table.getDinerCount();
+        }
+        throw new RuntimeException("请选择用餐人数");
+    }
+}

+ 83 - 0
alien-dining/src/main/java/shop/alien/dining/support/DiningOrderingTableGuard.java

@@ -0,0 +1,83 @@
+package shop.alien.dining.support;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+import shop.alien.dining.constants.OrderMenuConstants;
+import shop.alien.entity.store.StoreInfo;
+import shop.alien.entity.store.StoreTable;
+import shop.alien.mapper.StoreInfoMapper;
+import shop.alien.mapper.StoreTableMapper;
+
+import java.util.Objects;
+/**
+ * 点餐侧桌台与门店校验:桌是否存在、门店是否匹配、经营板块+桌类型是否允许美食或通用价目入口。
+ * <p>
+ * 集中异常文案与 {@link StoreBusinessSectionOrdering} 的调用,避免在多个 Service 中复制相同逻辑。
+ */
+@Component
+@RequiredArgsConstructor
+public class DiningOrderingTableGuard {
+
+    private final StoreTableMapper storeTableMapper;
+    private final StoreInfoMapper storeInfoMapper;
+
+    public StoreTable requireTable(Integer tableId) {
+        StoreTable table = storeTableMapper.selectById(tableId);
+        if (table == null) {
+            throw new RuntimeException("桌号不存在");
+        }
+        return table;
+    }
+
+    public StoreInfo requireStore(StoreTable table) {
+        StoreInfo storeInfo = storeInfoMapper.selectById(table.getStoreId());
+        if (storeInfo == null) {
+            throw new RuntimeException("门店不存在");
+        }
+        return storeInfo;
+    }
+
+    public void assertTableBelongsToStore(StoreTable table, Integer storeId) {
+        if (!Objects.equals(table.getStoreId(), storeId)) {
+            throw new RuntimeException("门店与桌台不匹配");
+        }
+    }
+
+    /** 美食 browsing / 购物车 / 下单:当前桌台须按规则走美食价目 */
+    public void assertCuisineMenuAllowed(StoreTable table) {
+        assertCuisineMenuAllowed(storeInfoForTable(table), table);
+    }
+
+    public void assertCuisineMenuAllowed(StoreInfo storeInfo, StoreTable table) {
+        if (!StoreBusinessSectionOrdering.allowsCuisinePricing(storeInfo, table)) {
+            throw new RuntimeException("当前门店适用通用价目点餐,请使用通用价目入口");
+        }
+    }
+
+    /** 通用价目 browsing / 购物车:当前桌台须按规则走 store_price */
+    public void assertGenericMenuAllowed(StoreTable table) {
+        assertGenericMenuAllowed(storeInfoForTable(table), table);
+    }
+
+    public void assertGenericMenuAllowed(StoreInfo storeInfo, StoreTable table) {
+        if (!StoreBusinessSectionOrdering.allowsGenericPricing(storeInfo, table)) {
+            throw new RuntimeException("当前门店/桌台不适用通用价目点餐,请使用美食点餐入口");
+        }
+    }
+
+    /** 创建订单前:请求的美食/通用类型须与门店+桌台解析出的有效类型一致 */
+    public void assertOrderMenuTypeAllowed(StoreInfo storeInfo, StoreTable table, int requestedMenuType) {
+        int effective = StoreBusinessSectionOrdering.resolveEffectiveMenuType(storeInfo, table);
+        if (requestedMenuType == OrderMenuConstants.MENU_TYPE_GENERIC_PRICE) {
+            if (effective != OrderMenuConstants.MENU_TYPE_GENERIC_PRICE) {
+                throw new RuntimeException("当前门店/桌台不适用通用价目点餐,请使用美食点餐入口");
+            }
+        } else if (effective != OrderMenuConstants.MENU_TYPE_CUISINE) {
+            throw new RuntimeException("当前门店/桌台请使用通用价目点餐接口下单");
+        }
+    }
+
+    private StoreInfo storeInfoForTable(StoreTable table) {
+        return storeInfoMapper.selectById(table.getStoreId());
+    }
+}

+ 27 - 0
alien-dining/src/main/java/shop/alien/dining/support/DiningSearchText.java

@@ -0,0 +1,27 @@
+package shop.alien.dining.support;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * 点餐检索相关字符串处理(与具体 Service 解耦)。
+ */
+public final class DiningSearchText {
+
+    /** 与历史接口一致:模糊搜索关键词最多保留的字数 */
+    public static final int MAX_KEYWORD_LENGTH = 10;
+
+    private DiningSearchText() {
+    }
+
+    public static String clampKeyword(String keyword) {
+        return clampKeyword(keyword, MAX_KEYWORD_LENGTH);
+    }
+
+    public static String clampKeyword(String keyword, int maxLen) {
+        if (!StringUtils.hasText(keyword) || maxLen <= 0) {
+            return keyword;
+        }
+        // 与历史实现一致:仅截断长度,不对入参 trim(避免前后空格参与 like 条件的行为发生漂移)
+        return keyword.length() > maxLen ? keyword.substring(0, maxLen) : keyword;
+    }
+}