Explorar el Código

开发选择餐具 以及餐具增减

lutong hace 2 meses
padre
commit
8f80b62f7e

+ 50 - 0
alien-dining/src/main/java/shop/alien/dining/controller/StoreOrderController.java

@@ -131,6 +131,56 @@ public class StoreOrderController {
         }
     }
 
+    @ApiOperation(value = "设置用餐人数", notes = "设置用餐人数,自动添加或更新餐具到购物车")
+    @PostMapping("/cart/set-diner-count")
+    public R<CartDTO> setDinerCount(
+            @ApiParam(value = "桌号ID", required = true) @RequestParam Integer tableId,
+            @ApiParam(value = "用餐人数", required = true) @RequestParam Integer dinerCount) {
+        try {
+            // 验证 token
+            if (!TokenUtil.hasValidToken()) {
+                return R.fail("用户未登录");
+            }
+            if (dinerCount == null || dinerCount <= 0) {
+                return R.fail("用餐人数必须大于0");
+            }
+            CartDTO cart = cartService.setDinerCount(tableId, dinerCount);
+            // 推送购物车更新消息(SSE)
+            sseService.pushCartUpdate(tableId, cart);
+            // 推送购物车更新消息(WebSocket)
+            CartWebSocketProcess.pushCartUpdate(tableId, cart);
+            return R.data(cart);
+        } catch (Exception e) {
+            log.error("设置用餐人数失败: {}", e.getMessage(), e);
+            return R.fail("设置用餐人数失败: " + e.getMessage());
+        }
+    }
+
+    @ApiOperation(value = "更新餐具数量", notes = "更新购物车中餐具的数量,并推送SSE和WebSocket消息")
+    @PutMapping("/cart/update-tableware")
+    public R<CartDTO> updateTablewareQuantity(
+            @ApiParam(value = "桌号ID", required = true) @RequestParam Integer tableId,
+            @ApiParam(value = "餐具数量", required = true) @RequestParam Integer quantity) {
+        try {
+            // 验证 token
+            if (!TokenUtil.hasValidToken()) {
+                return R.fail("用户未登录");
+            }
+            if (quantity == null || quantity < 0) {
+                return R.fail("餐具数量不能小于0");
+            }
+            CartDTO cart = cartService.updateTablewareQuantity(tableId, quantity);
+            // 推送购物车更新消息(SSE)
+            sseService.pushCartUpdate(tableId, cart);
+            // 推送购物车更新消息(WebSocket)
+            CartWebSocketProcess.pushCartUpdate(tableId, cart);
+            return R.data(cart);
+        } catch (Exception e) {
+            log.error("更新餐具数量失败: {}", e.getMessage(), e);
+            return R.fail("更新餐具数量失败: " + e.getMessage());
+        }
+    }
+
     @ApiOperation(value = "创建订单(下单)", notes = "从购物车创建订单,不立即支付")
     @PostMapping("/create")
     public R<shop.alien.entity.store.vo.OrderSuccessVO> createOrder(@Valid @RequestBody CreateOrderDTO dto) {

+ 18 - 0
alien-dining/src/main/java/shop/alien/dining/service/CartService.java

@@ -84,4 +84,22 @@ public interface CartService {
      * @param tableId 桌号ID
      */
     void clearCouponUsed(Integer tableId);
+
+    /**
+     * 设置用餐人数(自动添加或更新餐具)
+     *
+     * @param tableId   桌号ID
+     * @param dinerCount 用餐人数
+     * @return 购物车信息
+     */
+    CartDTO setDinerCount(Integer tableId, Integer dinerCount);
+
+    /**
+     * 更新餐具数量
+     *
+     * @param tableId 桌号ID
+     * @param quantity 餐具数量
+     * @return 购物车信息
+     */
+    CartDTO updateTablewareQuantity(Integer tableId, Integer quantity);
 }

+ 175 - 0
alien-dining/src/main/java/shop/alien/dining/service/impl/CartServiceImpl.java

@@ -12,6 +12,7 @@ import shop.alien.dining.service.CartService;
 import shop.alien.entity.store.StoreCart;
 import shop.alien.entity.store.StoreCouponUsage;
 import shop.alien.entity.store.StoreCuisine;
+import shop.alien.entity.store.StoreInfo;
 import shop.alien.entity.store.StoreTable;
 import shop.alien.entity.store.dto.AddCartItemDTO;
 import shop.alien.entity.store.dto.CartDTO;
@@ -19,6 +20,7 @@ import shop.alien.entity.store.dto.CartItemDTO;
 import shop.alien.mapper.StoreCartMapper;
 import shop.alien.mapper.StoreCouponUsageMapper;
 import shop.alien.mapper.StoreCuisineMapper;
+import shop.alien.mapper.StoreInfoMapper;
 import shop.alien.mapper.StoreTableMapper;
 import shop.alien.dining.util.TokenUtil;
 
@@ -48,6 +50,7 @@ public class CartServiceImpl implements CartService {
     private final StoreCuisineMapper storeCuisineMapper;
     private final StoreCartMapper storeCartMapper;
     private final StoreCouponUsageMapper storeCouponUsageMapper;
+    private final StoreInfoMapper storeInfoMapper;
 
     @Override
     public CartDTO getCart(Integer tableId) {
@@ -468,6 +471,178 @@ public class CartServiceImpl implements CartService {
     }
 
     /**
+     * 餐具的特殊ID(用于标识餐具项)
+     */
+    private static final Integer TABLEWARE_CUISINE_ID = -1;
+    private static final String TABLEWARE_NAME = "餐具";
+
+    /**
+     * 获取餐具单价(从 store_info 表获取)
+     *
+     * @param storeId 门店ID
+     * @return 餐具单价(BigDecimal),如果门店不存在或未设置餐具费,返回 0.00
+     */
+    private BigDecimal getTablewareUnitPrice(Integer storeId) {
+        if (storeId == null) {
+            log.warn("门店ID为空,返回默认餐具单价 0.00");
+            return BigDecimal.ZERO;
+        }
+        StoreInfo storeInfo = storeInfoMapper.selectById(storeId);
+        if (storeInfo == null) {
+            log.warn("门店不存在, storeId={},返回默认餐具单价 0.00", storeId);
+            return BigDecimal.ZERO;
+        }
+        Integer tablewareFee = storeInfo.getTablewareFee();
+        if (tablewareFee == null || tablewareFee < 0) {
+            log.warn("门店餐具费未设置或无效, storeId={}, tablewareFee={},返回默认餐具单价 0.00", storeId, tablewareFee);
+            return BigDecimal.ZERO;
+        }
+        return BigDecimal.valueOf(tablewareFee);
+    }
+
+    @Override
+    public CartDTO setDinerCount(Integer tableId, Integer dinerCount) {
+        log.info("设置用餐人数, tableId={}, dinerCount={}", tableId, dinerCount);
+        
+        if (dinerCount == null || dinerCount <= 0) {
+            throw new RuntimeException("用餐人数必须大于0");
+        }
+
+        // 获取购物车
+        CartDTO cart = getCart(tableId);
+        List<CartItemDTO> items = cart.getItems();
+
+        // 获取门店ID和餐具单价
+        Integer storeId = cart.getStoreId();
+        if (storeId == null) {
+            // 如果购物车中没有门店ID,从桌号获取
+            StoreTable table = storeTableMapper.selectById(tableId);
+            if (table != null) {
+                storeId = table.getStoreId();
+            }
+        }
+        BigDecimal tablewareUnitPrice = getTablewareUnitPrice(storeId);
+
+        // 查找是否已存在餐具项
+        CartItemDTO tablewareItem = items.stream()
+                .filter(item -> TABLEWARE_CUISINE_ID.equals(item.getCuisineId()))
+                .findFirst()
+                .orElse(null);
+
+        // 获取当前用户信息
+        Integer userId = TokenUtil.getCurrentUserId();
+        String userPhone = TokenUtil.getCurrentUserPhone();
+
+        if (tablewareItem != null) {
+            // 更新餐具数量和单价
+            tablewareItem.setQuantity(dinerCount);
+            tablewareItem.setUnitPrice(tablewareUnitPrice);
+            tablewareItem.setSubtotalAmount(tablewareUnitPrice.multiply(BigDecimal.valueOf(dinerCount)));
+        } else {
+            // 添加餐具项
+            CartItemDTO newTablewareItem = new CartItemDTO();
+            newTablewareItem.setCuisineId(TABLEWARE_CUISINE_ID);
+            newTablewareItem.setCuisineName(TABLEWARE_NAME);
+            newTablewareItem.setCuisineType(0); // 0表示餐具
+            newTablewareItem.setCuisineImage("");
+            newTablewareItem.setUnitPrice(tablewareUnitPrice);
+            newTablewareItem.setQuantity(dinerCount);
+            newTablewareItem.setSubtotalAmount(tablewareUnitPrice.multiply(BigDecimal.valueOf(dinerCount)));
+            newTablewareItem.setAddUserId(userId);
+            newTablewareItem.setAddUserPhone(userPhone);
+            items.add(newTablewareItem);
+        }
+
+        // 重新计算总金额和总数量
+        BigDecimal totalAmount = items.stream()
+                .map(CartItemDTO::getSubtotalAmount)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        Integer totalQuantity = items.stream()
+                .mapToInt(CartItemDTO::getQuantity)
+                .sum();
+        cart.setTotalAmount(totalAmount);
+        cart.setTotalQuantity(totalQuantity);
+
+        // 保存到Redis和数据库(双写策略)
+        saveCart(cart);
+
+        return cart;
+    }
+
+    @Override
+    public CartDTO updateTablewareQuantity(Integer tableId, Integer quantity) {
+        log.info("更新餐具数量, tableId={}, quantity={}", tableId, quantity);
+        
+        if (quantity == null || quantity < 0) {
+            throw new RuntimeException("餐具数量不能小于0");
+        }
+
+        if (quantity == 0) {
+            // 数量为0时,删除餐具项
+            return removeItem(tableId, TABLEWARE_CUISINE_ID);
+        }
+
+        // 获取购物车
+        CartDTO cart = getCart(tableId);
+        List<CartItemDTO> items = cart.getItems();
+
+        // 获取门店ID和餐具单价
+        Integer storeId = cart.getStoreId();
+        if (storeId == null) {
+            // 如果购物车中没有门店ID,从桌号获取
+            StoreTable table = storeTableMapper.selectById(tableId);
+            if (table != null) {
+                storeId = table.getStoreId();
+            }
+        }
+        BigDecimal tablewareUnitPrice = getTablewareUnitPrice(storeId);
+
+        // 查找餐具项
+        CartItemDTO tablewareItem = items.stream()
+                .filter(item -> TABLEWARE_CUISINE_ID.equals(item.getCuisineId()))
+                .findFirst()
+                .orElse(null);
+
+        if (tablewareItem == null) {
+            // 如果不存在餐具项,创建一个
+            Integer userId = TokenUtil.getCurrentUserId();
+            String userPhone = TokenUtil.getCurrentUserPhone();
+            
+            tablewareItem = new CartItemDTO();
+            tablewareItem.setCuisineId(TABLEWARE_CUISINE_ID);
+            tablewareItem.setCuisineName(TABLEWARE_NAME);
+            tablewareItem.setCuisineType(0); // 0表示餐具
+            tablewareItem.setCuisineImage("");
+            tablewareItem.setUnitPrice(tablewareUnitPrice);
+            tablewareItem.setAddUserId(userId);
+            tablewareItem.setAddUserPhone(userPhone);
+            items.add(tablewareItem);
+        } else {
+            // 如果已存在,更新单价(可能门店修改了餐具费)
+            tablewareItem.setUnitPrice(tablewareUnitPrice);
+        }
+
+        // 更新数量
+        tablewareItem.setQuantity(quantity);
+        tablewareItem.setSubtotalAmount(tablewareUnitPrice.multiply(BigDecimal.valueOf(quantity)));
+
+        // 重新计算总金额和总数量
+        BigDecimal totalAmount = items.stream()
+                .map(CartItemDTO::getSubtotalAmount)
+                .reduce(BigDecimal.ZERO, BigDecimal::add);
+        Integer totalQuantity = items.stream()
+                .mapToInt(CartItemDTO::getQuantity)
+                .sum();
+        cart.setTotalAmount(totalAmount);
+        cart.setTotalQuantity(totalQuantity);
+
+        // 保存到Redis和数据库(双写策略)
+        saveCart(cart);
+
+        return cart;
+    }
+
+    /**
      * 保存购物车到Redis和数据库(双写策略)
      */
     private void saveCart(CartDTO cart) {