diff --git a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java index 3316b38fa..7e54c8ed9 100644 --- a/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java +++ b/yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/app/favorite/AppFavoriteController.java @@ -42,6 +42,14 @@ public class AppFavoriteController { return success(productFavoriteService.createFavorite(getLoginUserId(), reqVO.getSpuId())); } + @PostMapping(value = "/create-list") + @Operation(summary = "添加多个商品收藏") + @PreAuthenticated + public CommonResult createFavoriteList(@RequestBody @Valid AppFavoriteBatchReqVO reqVO) { + // todo @jason:待实现;如果有已经收藏的,不用报错,忽略即可; + return success(true); + } + @DeleteMapping(value = "/delete") @Operation(summary = "取消单个商品收藏") @PreAuthenticated diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.java index c442cd7d0..2c9d77b52 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/cart/AppCartController.java @@ -15,7 +15,6 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.validation.Valid; import java.util.List; -import java.util.Map; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @@ -78,13 +77,6 @@ public class AppCartController { return success(cartService.getCartCount(getLoginUserId())); } - @GetMapping("get-count-map") - @Operation(summary = "查询用户在购物车中的商品 SPU 数量 Map") - @PreAuthenticated - public CommonResult> getCartCountMap() { - return success(cartService.getCartCountMap(getLoginUserId())); - } - @GetMapping("/list") @Operation(summary = "查询用户的购物车列表") @PreAuthenticated diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java index 8a34f1180..e3205fcaf 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; @@ -91,15 +90,11 @@ public class AppTradeOrderController { // 查询订单项 List orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); - // 查询商品属性 - List propertyValueDetails = productPropertyValueApi - .getPropertyValueDetailList(TradeOrderConvert.INSTANCE.convertPropertyValueIds(orderItems)); // 查询物流公司 DeliveryExpressDO express = order.getLogisticsId() != null && order.getLogisticsId() > 0 ? deliveryExpressService.getDeliveryExpress(order.getLogisticsId()) : null; // 最终组合 - return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, - propertyValueDetails, tradeOrderProperties, express)); + return success(TradeOrderConvert.INSTANCE.convert02(order, orderItems, tradeOrderProperties, express)); } @GetMapping("/get-express-track-list") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 5876e265b..0285a6354 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.framework.common.util.string.StrUtils; import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; @@ -82,14 +83,16 @@ public interface TradeOrderConvert { TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); + default ProductSkuUpdateStockReqDTO convert(List list) { + return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); + } + List convertList(List list); @Mappings({ @Mapping(source = "skuId", target = "id"), @Mapping(source = "count", target = "incrCount"), }) ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); - List convertList(List list); - default PayOrderCreateReqDTO convert(TradeOrderDO order, List orderItems, TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() @@ -97,9 +100,7 @@ public interface TradeOrderConvert { // 商户相关字段 createReqDTO.setMerchantOrderId(String.valueOf(order.getId())); String subject = calculateRespBO.getItems().get(0).getSpuName(); - if (calculateRespBO.getItems().size() > 1) { - subject += " 等多件"; - } + subject = StrUtils.maxLength(subject, PayOrderCreateReqDTO.SUBJECT_MAX_LENGTH); // 避免超过 32 位 createReqDTO.setSubject(subject); createReqDTO.setBody(subject); // TODO 芋艿:临时写死 // 订单相关字段 @@ -107,16 +108,6 @@ public interface TradeOrderConvert { return createReqDTO; } - default Set convertPropertyValueIds(List list) { - if (CollUtil.isEmpty(list)) { - return new HashSet<>(); - } - return list.stream().filter(item -> item.getProperties() != null) - .flatMap(p -> p.getProperties().stream()) // 遍历多个 Property 属性 - .map(TradeOrderItemDO.Property::getValueId) // 将每个 Property 转换成对应的 propertyId,最后形成集合 - .collect(Collectors.toSet()); - } - // TODO 芋艿:可简化 default PageResult convertPage(PageResult pageResult, List orderItems, @@ -170,31 +161,13 @@ public interface TradeOrderConvert { // TODO 芋艿:可简化 default AppTradeOrderDetailRespVO convert02(TradeOrderDO order, List orderItems, - List propertyValueDetails, TradeOrderProperties tradeOrderProperties, + TradeOrderProperties tradeOrderProperties, DeliveryExpressDO express) { AppTradeOrderDetailRespVO orderVO = convert3(order, orderItems); orderVO.setPayExpireTime(addTime(tradeOrderProperties.getExpireTime())); if (StrUtil.isNotEmpty(order.getPayChannelCode())) { orderVO.setPayChannelName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHANNEL_CODE, order.getPayChannelCode())); } - // 处理商品属性 - Map propertyValueDetailMap = convertMap(propertyValueDetails, ProductPropertyValueDetailRespDTO::getValueId); - for (int i = 0; i < orderItems.size(); i++) { - List properties = orderItems.get(i).getProperties(); - if (CollUtil.isEmpty(properties)) { - continue; - } - AppTradeOrderItemRespVO item = orderVO.getItems().get(i); - item.setProperties(new ArrayList<>(properties.size())); - // 遍历每个 properties,设置到 TradeOrderPageItemRespVO.Item 中 - properties.forEach(property -> { - ProductPropertyValueDetailRespDTO propertyValueDetail = propertyValueDetailMap.get(property.getValueId()); - if (propertyValueDetail == null) { - return; - } - item.getProperties().add(convert02(propertyValueDetail)); - }); - } // 处理收货地址 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); if (express != null) { diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/CartMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/CartMapper.java index 121752c85..b67265156 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/CartMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/cart/CartMapper.java @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.dal.mysql.cart; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -27,25 +26,11 @@ public interface CartMapper extends BaseMapperX { List> result = selectMaps(new QueryWrapper() .select("SUM(count) AS sumCount") .eq("user_id", userId) - .eq("add_status", true) // 只计算添加到购物车中的 - .eq("order_status", false)); // 必须未下单 + .eq("selected", true)); // 只计算选中的 // 获得数量 return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0; } - default Map selectSumMapByUserId(Long userId) { - // SQL sum 查询 - List> result = selectMaps(new QueryWrapper() - .select("spu_id, SUM(count) AS sumCount") - .eq("user_id", userId) - .eq("add_status", true) // 只计算添加到购物车中的 - .eq("order_status", false) // 必须未下单 - .groupBy("spu_id")); - // 获得数量 - return CollectionUtils.convertMap(result, item -> MapUtil.getLong(item, "spu_id"), - item -> MapUtil.getInt(item, "sumCount")); - } - default CartDO selectById(Long id, Long userId) { return selectOne(CartDO::getId, id, CartDO::getUserId, userId); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartService.java index 84e697a6a..6130614e0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartService.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartService.java @@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; import javax.validation.Valid; import java.util.Collection; import java.util.List; -import java.util.Map; import java.util.Set; /** @@ -84,12 +83,4 @@ public interface CartService { */ List getCartList(Long userId, Set ids); - /** - * 获得用户的购物车商品 SPU 数量的 Map - * - * @param userId 用户编号 - * @return 购物车商品 SPU 数量的 Map - */ - Map getCartCountMap(Long userId); - } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartServiceImpl.java index 217cf1f6b..b936f6f8e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/CartServiceImpl.java @@ -50,19 +50,14 @@ public class CartServiceImpl implements CartService { Integer count = addReqVO.getCount(); ProductSkuRespDTO sku = checkProductSku(addReqVO.getSkuId(), count); - // 情况零:特殊,count 小于等于 0,说明前端项目删除 // 情况一:存在,则进行数量更新 if (cart != null) { - // 特殊情况,如果 count 小于等于 0,说明前端想要删除 - if (count <= 0) { - cartMapper.deleteById(cart.getId()); - } else { - cartMapper.updateById(new CartDO().setId(cart.getId()).setCount(count)); - } + cartMapper.updateById(new CartDO().setId(cart.getId()).setSelected(true) + .setCount(cart.getCount() + count)); return cart.getId(); // 情况二:不存在,则进行插入 } else { - cart = new CartDO().setUserId(userId) + cart = new CartDO().setUserId(userId).setSelected(true) .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count); cartMapper.insert(cart); } @@ -101,7 +96,6 @@ public class CartServiceImpl implements CartService { cartMapper.deleteById(oldCart.getId()); // 第二步:添加新的购物项 - // TODO 芋艿:直接改成 addCart 貌似就行 CartDO newCart = cartMapper.selectByUserIdAndSkuId(userId, resetReqVO.getSkuId()); if (newCart != null) { updateCartCount(userId, new AppCartUpdateCountReqVO() @@ -136,12 +130,6 @@ public class CartServiceImpl implements CartService { return cartMapper.selectSumByUserId(userId); } - @Override - public Map getCartCountMap(Long userId) { - // TODO 芋艿:需要算上 selected - return cartMapper.selectSumMapByUserId(userId); - } - @Override public AppCartListRespVO getCartList(Long userId) { // 获得购物车的商品 diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java index b743d3761..3b6d160f1 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java @@ -26,7 +26,6 @@ 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.comment.dto.ProductCommentCreateReqDTO; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; @@ -70,6 +69,7 @@ import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; import java.util.Objects; +import java.util.Set; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; @@ -93,7 +93,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { private TradeOrderItemMapper tradeOrderItemMapper; @Resource - private CartService tradeCartService; + private CartService cartService; @Resource private TradePriceService tradePriceService; @Resource @@ -168,7 +168,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { */ private TradePriceCalculateRespBO calculatePrice(Long userId, AppTradeOrderSettlementReqVO settlementReqVO) { // 1. 如果来自购物车,则获得购物车的商品 - List cartList = tradeCartService.getCartList(userId, + List cartList = cartService.getCartList(userId, convertSet(settlementReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId)); // 2. 计算价格 @@ -190,6 +190,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { // 订单创建完后的逻辑 afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); // 3.3 校验订单类型 + // TODO @puhui999:这个逻辑,先抽个小方法;未来要通过设计模式,把这些拼团之类的逻辑,抽象出去 // 拼团 if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { MemberUserRespDTO user = memberUserApi.getUser(userId); @@ -292,11 +293,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { TradeOrderDO tradeOrderDO, List orderItems, TradePriceCalculateRespBO calculateRespBO) { // 下单时扣减商品库存 - productSkuApi.updateSkuStock(new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(orderItems))); + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convert(orderItems)); - // 删除购物车商品 TODO 芋艿:待实现 + // 删除购物车商品 + Set cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); + if (CollUtil.isNotEmpty(cartIds)) { + cartService.deleteCart(userId, cartIds); + } - // 扣减积分,抵扣金额 TODO 芋艿:待实现 + // 扣减积分 TODO 芋艿:待实现 // 有使用优惠券时更新 if (createReqVO.getCouponId() != null) { diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java index 821548323..383e18aca 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java +++ b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/order/dto/PayOrderCreateReqDTO.java @@ -15,6 +15,8 @@ import java.time.LocalDateTime; @Data public class PayOrderCreateReqDTO implements Serializable { + public static final int SUBJECT_MAX_LENGTH = 32; + /** * 应用编号 */ @@ -37,7 +39,7 @@ public class PayOrderCreateReqDTO implements Serializable { * 商品标题 */ @NotEmpty(message = "商品标题不能为空") - @Length(max = 32, message = "商品标题不能超过 32") + @Length(max = SUBJECT_MAX_LENGTH, message = "商品标题不能超过 32") private String subject; /** * 商品描述