diff --git a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java index bb87a4933..6dbf2321a 100644 --- a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java +++ b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/dal/mysql/mapper/cart/CartItemMapper.java @@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; +import java.math.BigDecimal; import java.util.Collection; import java.util.List; import java.util.Map; @@ -37,7 +38,7 @@ public interface CartItemMapper extends BaseMapper { .select("SUM(quantity) AS sumQuantity") .eq("user_id", userId)); // 获得数量 - return (Integer) result.get(0).get("sumQuantity"); + return ((BigDecimal) result.get(0).get("sumQuantity")).intValue(); } default List selectList(CartItemListQueryBO queryBO) { diff --git a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/manager/cart/CartManager.java b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/manager/cart/CartManager.java index 17ca53189..1c4f3bbfd 100644 --- a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/manager/cart/CartManager.java +++ b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/manager/cart/CartManager.java @@ -38,7 +38,7 @@ public class CartManager { // 校验商品 SKU 是否合法 ProductSkuRespDTO skuDTO = this.checkProductSku(addReqDTO.getSkuId()); // 添加购物车项 - cartService.addCartItem(CartConvert.INSTANCE.convert(addReqDTO), skuDTO.getQuantity()); + cartService.addCartItem(CartConvert.INSTANCE.convert(addReqDTO).setSpuId(skuDTO.getSpuId()), skuDTO.getQuantity()); } /** diff --git a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/bo/CartItemAddBO.java b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/bo/CartItemAddBO.java index 596054a31..ce0642c29 100644 --- a/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/bo/CartItemAddBO.java +++ b/order-service-project/order-service-app/src/main/java/cn/iocoder/mall/orderservice/service/cart/bo/CartItemAddBO.java @@ -10,7 +10,7 @@ import javax.validation.constraints.NotNull; * 购物车添加购物项 Request DTO */ @Data -@Accessors +@Accessors(chain = true) public class CartItemAddBO { /** diff --git a/order-service-project/order-service-app/src/main/resources/application.yaml b/order-service-project/order-service-app/src/main/resources/application.yaml index e3f1adf9b..01b683423 100644 --- a/order-service-project/order-service-app/src/main/resources/application.yaml +++ b/order-service-project/order-service-app/src/main/resources/application.yaml @@ -39,6 +39,8 @@ dubbo: consumer: ErrorCodeRpc: version: 1.0.0 + ProductSkuRpc: + version: 1.0.0 # RocketMQ 配置项 rocketmq: diff --git a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java index 3f4adc508..863915417 100644 --- a/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java +++ b/order/order-rest/src/main/java/cn/iocoder/mall/order/rest/controller/cart/UsersCartController.java @@ -16,14 +16,7 @@ public class UsersCartController { // @Reference(validation = "true", version = "${dubbo.consumer.CouponService.version}") // private CouponService couponService; // -// @PostMapping("add") -// public CommonResult add(@RequestParam("skuId") Integer skuId, -// @RequestParam("quantity") Integer quantity) { -// // 添加到购物车 -// cartService.add(UserSecurityContextHolder.getContext().getUserId(), skuId, quantity); -// // 获得目前购物车商品总数量 -// return success(cartService.count(UserSecurityContextHolder.getContext().getUserId())); -// } + // // @PostMapping("update_quantity") // public CommonResult updateQuantity(@RequestParam("skuId") Integer skuId, // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整 @@ -43,11 +36,7 @@ public class UsersCartController { // // 获得目前购物车明细 // return getCartDetail(); // } -// -// @GetMapping("count") -// public CommonResult count() { -// return success(cartService.count(UserSecurityContextHolder.getContext().getUserId())); -// } + // // @GetMapping("/list") // public CommonResult list() { // TODO 芋艿,先暂用这个 VO 。等促销活动出来后,做调整 diff --git a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java index d61a87004..4dba7aa9a 100644 --- a/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java +++ b/order/order-service-impl/src/main/java/cn/iocoder/mall/order/biz/service/CartServiceImpl.java @@ -239,7 +239,7 @@ public class CartServiceImpl implements CartService { // 判断是否符合条件 int originalTotal = items.stream().mapToInt(CalcOrderPriceBO.Item::getPresentTotal).sum(); // 此处,指的是以优惠劵视角的原价 if (originalTotal == 0 || originalTotal < couponCard.getPriceAvailable()) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_MATCH.getCode()); // TODO 芋艿,这种情况,会出现错误码的提示,无法格式化出来。另外,这块的最佳实践,找人讨论下。 + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_NOT_MATCH.getCode()); // TODO 芋艿,这种情况,会出现错误码的提示,无法格式化出来。另外,这块的最佳实践,找人讨论下。 } // 计算价格 // 获得到优惠信息,进行价格计算 diff --git a/pom.xml b/pom.xml index f484a1162..7427299c3 100644 --- a/pom.xml +++ b/pom.xml @@ -16,10 +16,8 @@ order common - - mall-dependencies user-service-project user-web-app @@ -28,7 +26,7 @@ management-web-app shop-web-app product-service-project - + promotion-service-project search-service-project order-service-project diff --git a/promotion-service-project/promotion-service-api/pom.xml b/promotion-service-project/promotion-service-api/pom.xml index caaeda443..a5a773359 100644 --- a/promotion-service-project/promotion-service-api/pom.xml +++ b/promotion-service-project/promotion-service-api/pom.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - promotion + promotion-service-project cn.iocoder.mall 1.0-SNAPSHOT diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeConstants.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeConstants.java new file mode 100644 index 000000000..162cc0d07 --- /dev/null +++ b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeConstants.java @@ -0,0 +1,37 @@ +package cn.iocoder.mall.promotion.api.enums; + +import cn.iocoder.common.framework.exception.ErrorCode; + +/** + * 错误码枚举类 + * + * 营销系统,使用 1-006-000-000 段 + */ +public interface PromotionErrorCodeConstants { + + // ========== Banner 模块 ========== + ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1006000000, "账号不存在"); + + // ========== PRODUCT RECOMMEND 模块 ========== + ErrorCode PRODUCT_RECOMMEND_NOT_EXISTS = new ErrorCode(1006001000, "商品推荐不存在"); + ErrorCode PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS = new ErrorCode(1006001001, "商品不存在"); + ErrorCode PRODUCT_RECOMMEND_EXISTS = new ErrorCode(1006001002, "该商品推荐已经存在"); + + + // ========== COUPON TEMPLATE 模块 ========== + ErrorCode COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1006002000, "优惠劵模板(码)不存在"); + ErrorCode COUPON_TEMPLATE_NOT_CARD = new ErrorCode(1006002001, "不是优惠劵模板"); + ErrorCode COUPON_TEMPLATE_NOT_CODE = new ErrorCode(1006002002, "不是优惠码模板"); + ErrorCode COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE = new ErrorCode(1006002003, "优惠劵(码)模板的发放数量不能减小"); + ErrorCode COUPON_TEMPLATE_STATUS_NOT_ENABLE = new ErrorCode(1006002004, "优惠劵模板(码)未开启"); + ErrorCode COUPON_TEMPLATE_TOTAL_NOT_ENOUGH = new ErrorCode(1006002005, "优惠劵(码)模板的发放量不足"); + ErrorCode COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA = new ErrorCode(1006002006, "优惠劵领取到达上限"); + + // ========== COUPON CARD 模块 ========== + ErrorCode COUPON_CARD_NOT_EXISTS = new ErrorCode(1006003000, "优惠劵不存在"); + ErrorCode COUPON_CARD_ERROR_USER = new ErrorCode(1006003001, "优惠劵不属于当前用户"); + ErrorCode COUPON_CARD_NOT_MATCH = new ErrorCode(1006003002, "优惠劵不匹配,无法使用"); + ErrorCode COUPON_CARD_STATUS_NOT_UNUSED = new ErrorCode(1006003003, "优惠劵不处于待使用状态"); + ErrorCode COUPON_CARD_STATUS_NOT_USED = new ErrorCode( 1006003004, "优惠劵不处于已使用状态"); + +} diff --git a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeEnum.java b/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeEnum.java deleted file mode 100644 index 7e08132ff..000000000 --- a/promotion-service-project/promotion-service-api/src/main/java/cn/iocoder/mall/promotion/api/enums/PromotionErrorCodeEnum.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.mall.promotion.api.enums; - -/** - * 错误码枚举类 - * - * 营销系统,使用 1-006-000-000 段 - */ -public enum PromotionErrorCodeEnum { - - // ========== Banner 模块 ========== - BANNER_NOT_EXISTS(1006000000, "账号不存在"), - - // ========== PRODUCT RECOMMEND 模块 ========== - PRODUCT_RECOMMEND_NOT_EXISTS(1006001000, "商品推荐不存在"), - PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS(1006001001, "商品不存在"), - PRODUCT_RECOMMEND_EXISTS(1006001002, "该商品推荐已经存在"), - - - // ========== COUPON TEMPLATE 模块 ========== - COUPON_TEMPLATE_NOT_EXISTS(1006002000, "优惠劵模板(码)不存在"), - COUPON_TEMPLATE_NOT_CARD(1006002001, "不是优惠劵模板"), - COUPON_TEMPLATE_NOT_CODE(1006002002, "不是优惠码模板"), - COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE(1006002003, "优惠劵(码)模板的发放数量不能减小"), - COUPON_TEMPLATE_STATUS_NOT_ENABLE(1006002004, "优惠劵模板(码)未开启"), - COUPON_TEMPLATE_TOTAL_NOT_ENOUGH(1006002005, "优惠劵(码)模板的发放量不足"), - COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA(1006002006, "优惠劵领取到达上限"), - - // ========== COUPON CARD 模块 ========== - COUPON_CARD_NOT_EXISTS(1006003000, "优惠劵不存在"), - COUPON_CARD_ERROR_USER(1006003001, "优惠劵不属于当前用户"), - COUPON_CARD_NOT_MATCH(1006003002, "优惠劵不匹配,无法使用"), - COUPON_CARD_STATUS_NOT_UNUSED(1006003003, "优惠劵不处于待使用状态"), - COUPON_CARD_STATUS_NOT_USED(1006003004, "优惠劵不处于已使用状态"), - ; - - - private final int code; - private final String message; - - PromotionErrorCodeEnum(int code, String message) { - this.code = code; - this.message = message; - } - - public int getCode() { - return code; - } - - public String getMessage() { - return message; - } - -} diff --git a/promotion-service-project/promotion-service-app/pom.xml b/promotion-service-project/promotion-service-app/pom.xml index 7717f549d..3866bfaa3 100644 --- a/promotion-service-project/promotion-service-app/pom.xml +++ b/promotion-service-project/promotion-service-app/pom.xml @@ -12,26 +12,45 @@ promotion-service-app - + cn.iocoder.mall mall-spring-boot-starter-dubbo + + cn.iocoder.mall + system-service-api + ${project.version} + + + + + cn.iocoder.mall + product-service-api + 1.0-SNAPSHOT + + + + cn.iocoder.mall promotion-service-api + org.springframework.boot - spring-boot - - - org.springframework.boot - spring-boot-autoconfigure + spring-boot-starter-web + + + com.alibaba.cloud + spring-cloud-starter-alibaba-nacos-discovery + + + mysql mysql-connector-java @@ -46,12 +65,44 @@ cn.iocoder.mall mall-spring-boot-starter-mybatis + + - cn.iocoder.mall - product-service-api - 1.0-SNAPSHOT - compile + org.springframework.boot + spring-boot-starter-validation + + + + org.projectlombok + lombok + + + + org.mapstruct + mapstruct + + + org.mapstruct + mapstruct-jdk8 + + + + org.aspectj + aspectjweaver + 1.9.6 - \ No newline at end of file + + + ${project.artifactId} + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/banner/BannerService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/banner/BannerService.java index f02e28f8f..74934dc38 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/banner/BannerService.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/banner/BannerService.java @@ -3,24 +3,17 @@ package cn.iocoder.mall.promotionservice.service.banner; import cn.iocoder.common.framework.enums.CommonStatusEnum; import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil; import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum; -import cn.iocoder.mall.promotion.api.enums.PromotionActivityTypeEnum; -import cn.iocoder.mall.promotion.api.enums.PromotionErrorCodeEnum; -import cn.iocoder.mall.promotion.api.enums.RangeTypeEnum; +import cn.iocoder.mall.promotion.api.enums.PromotionErrorCodeConstants; import cn.iocoder.mall.promotion.api.rpc.banner.dto.BannerPageDTO; -import cn.iocoder.mall.promotionservice.convert.activity.PromotionActivityConvert; import cn.iocoder.mall.promotionservice.convert.banner.BannerConvert; -import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.activity.PromotionActivityDO; import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.banner.BannerDO; -import cn.iocoder.mall.promotionservice.dal.mysql.mapper.activity.PromotionActivityMapper; import cn.iocoder.mall.promotionservice.dal.mysql.mapper.banner.BannerMapper; -import cn.iocoder.mall.promotionservice.service.activity.bo.PromotionActivityPageBO; import cn.iocoder.mall.promotionservice.service.banner.bo.BannerAddBO; import cn.iocoder.mall.promotionservice.service.banner.bo.BannerBO; import cn.iocoder.mall.promotionservice.service.banner.bo.BannerPageBO; import cn.iocoder.mall.promotionservice.service.banner.bo.BannerUpdateBO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; import java.util.*; @@ -61,7 +54,7 @@ public class BannerService { public Boolean updateBanner(Integer adminId, BannerUpdateBO bannerUpdateDTO) { // 校验 Banner 存在 if (bannerMapper.selectById(bannerUpdateDTO.getId()) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.BANNER_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.BANNER_NOT_EXISTS.getCode()); } // 更新到数据库 BannerDO updateBanner = BannerConvert.INSTANCE.convert(bannerUpdateDTO); @@ -73,7 +66,7 @@ public class BannerService { public Boolean updateBannerStatus(Integer adminId, Integer bannerId, Integer status) { // 校验 Banner 存在 if (bannerMapper.selectById(bannerId) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.BANNER_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.BANNER_NOT_EXISTS.getCode()); } // 更新到数据库 BannerDO updateBanner = new BannerDO().setId(bannerId).setStatus(status); @@ -85,7 +78,7 @@ public class BannerService { public Boolean deleteBanner(Integer adminId, Integer bannerId) { // 校验 Banner 存在 if (bannerMapper.selectById(bannerId) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.BANNER_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.BANNER_NOT_EXISTS.getCode()); } // 更新到数据库 BannerDO updateBanner = new BannerDO().setId(bannerId); diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/coupon/CouponService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/coupon/CouponService.java index da75b159e..9754e19b4 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/coupon/CouponService.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/coupon/CouponService.java @@ -12,7 +12,6 @@ import cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon.CouponCardMapper import cn.iocoder.mall.promotionservice.dal.mysql.mapper.coupon.CouponTemplateMapper; import cn.iocoder.mall.promotionservice.service.coupon.bo.*; import cn.iocoder.common.framework.util.*; -import io.netty.util.internal.StringUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -80,15 +79,15 @@ public class CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponCardTemplateUpdateDTO.getId()); if (template == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 校验 CouponCardTemplate 是 CARD if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_CARD.getCode()); } // 校验发放数量不能减少 if (couponCardTemplateUpdateDTO.getTotal() < template.getTotal()) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_TOTAL_CAN_NOT_REDUCE.getCode()); } // 更新优惠劵模板到数据库 CouponTemplateDO updateTemplateDO = CouponTemplateConvert.INSTANCE.convert(couponCardTemplateUpdateDTO); @@ -101,7 +100,7 @@ public class CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); if (template == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 更新到数据库 CouponTemplateDO updateTemplateDO = new CouponTemplateDO().setId(couponTemplateId).setStatus(status); @@ -173,28 +172,28 @@ public class CouponService { // 校验 CouponCardTemplate 存在 CouponTemplateDO template = couponTemplateMapper.selectById(couponTemplateId); if (template == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 校验 CouponCardTemplate 是 CARD if (!CouponTemplateTypeEnum.CARD.getValue().equals(template.getType())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_CARD.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_CARD.getCode()); } // 校验 CouponCardTemplate 状态是否开启 if (!CouponTemplateStatusEnum.ENABLE.getValue().equals(template.getStatus())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_STATUS_NOT_ENABLE.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_STATUS_NOT_ENABLE.getCode()); } // 校验 CouponCardTemplate 是否到达可领取的上限 if (template.getStatFetchNum() > template.getTotal()) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_TOTAL_NOT_ENOUGH.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_TOTAL_NOT_ENOUGH.getCode()); } // 校验单人可领取优惠劵是否到达上限 if (couponCardMapper.selectCountByUserIdAndTemplateId(userId, couponTemplateId) > template.getQuota()) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); } // 增加优惠劵已领取量 int updateTemplateCount = couponTemplateMapper.updateStatFetchNumIncr(couponTemplateId); if (updateTemplateCount == 0) { // 超过 CouponCardTemplate 发放量 - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_CARD_ADD_EXCEED_QUOTA.getCode()); } // 创建优惠劵 // 1. 基本信息 + 领取情况 @@ -222,22 +221,22 @@ public class CouponService { // 查询优惠劵 CouponCardDO card = couponCardMapper.selectById(couponCardId); if (card == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_NOT_EXISTS.getCode()); } if (!userId.equals(card.getUserId())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_ERROR_USER.getCode()); } if (!CouponCardStatusEnum.UNUSED.getValue().equals(card.getStatus())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); } if (DateUtil.isBetween(card.getValidStartTime(), card.getValidEndTime())) { // 为避免定时器没跑,实际优惠劵已经过期 - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); } // 更新优惠劵已使用 int updateCount = couponCardMapper.updateByIdAndStatus(card.getId(), CouponCardStatusEnum.UNUSED.getValue(), new CouponCardDO().setStatus(CouponCardStatusEnum.USED.getValue()).setUsedTime(new Date())); if (updateCount == 0) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_STATUS_NOT_UNUSED.getCode()); } return true; } @@ -246,19 +245,19 @@ public class CouponService { // 查询优惠劵 CouponCardDO card = couponCardMapper.selectById(couponCardId); if (card == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_NOT_EXISTS.getCode()); } if (!userId.equals(card.getUserId())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_ERROR_USER.getCode()); } if (!CouponCardStatusEnum.USED.getValue().equals(card.getStatus())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_USED.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_STATUS_NOT_USED.getCode()); } // 更新优惠劵已使用 int updateCount = couponCardMapper.updateByIdAndStatus(card.getId(), CouponCardStatusEnum.USED.getValue(), new CouponCardDO().setStatus(CouponCardStatusEnum.UNUSED.getValue())); // TODO 芋艿,usedTime 未设置空,后面处理。 if (updateCount == 0) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_STATUS_NOT_USED.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_STATUS_NOT_USED.getCode()); } // 有一点要注意,更新会未使用时,优惠劵可能已经过期了,直接让定时器跑过期,这里不做处理。 return true; @@ -268,15 +267,15 @@ public class CouponService { // 查询优惠劵 CouponCardDO card = couponCardMapper.selectById(couponCardId); if (card == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_NOT_EXISTS.getCode()); } if (!userId.equals(card.getUserId())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_CARD_ERROR_USER.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_CARD_ERROR_USER.getCode()); } // 查询优惠劵模板 CouponTemplateDO template = couponTemplateMapper.selectById(card.getTemplateId()); if (template == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.COUPON_TEMPLATE_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.COUPON_TEMPLATE_NOT_EXISTS.getCode()); } // 拼接结果 CouponCardDetailRespDTO detail = CouponCardConvert.INSTANCE.convert2(card); diff --git a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java index e8770317e..b8bb37102 100644 --- a/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java +++ b/promotion-service-project/promotion-service-app/src/main/java/cn/iocoder/mall/promotionservice/service/recommend/ProductRecommendService.java @@ -4,7 +4,7 @@ import cn.iocoder.common.framework.enums.CommonStatusEnum; import cn.iocoder.common.framework.exception.util.ServiceExceptionUtil; import cn.iocoder.mall.mybatis.core.enums.DeletedStatusEnum; import cn.iocoder.mall.productservice.rpc.spu.ProductSpuRpc; -import cn.iocoder.mall.promotion.api.enums.PromotionErrorCodeEnum; +import cn.iocoder.mall.promotion.api.enums.PromotionErrorCodeConstants; import cn.iocoder.mall.promotion.api.rpc.recommend.dto.ProductRecommendPageReqDTO; import cn.iocoder.mall.promotion.api.rpc.recommend.dto.ProductRecommendPageRespDTO; import cn.iocoder.mall.promotionservice.convert.recommend.ProductRecommendConvert; @@ -12,7 +12,6 @@ import cn.iocoder.mall.promotionservice.dal.mysql.dataobject.recommend.ProductRe import cn.iocoder.mall.promotionservice.dal.mysql.mapper.recommend.ProductRecommendMapper; import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendAddBO; import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendBO; -import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendPageBO; import cn.iocoder.mall.promotionservice.service.recommend.bo.ProductRecommendUpdateBO; import org.apache.dubbo.config.annotation.Reference; import org.springframework.beans.factory.annotation.Autowired; @@ -51,11 +50,11 @@ public class ProductRecommendService { public ProductRecommendBO addProductRecommend(Integer adminId, ProductRecommendAddBO productRecommendAddDTO) { // 校验商品不存在 if (productSpuRpc.getProductSpu(productRecommendAddDTO.getProductSpuId()) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode()); } // 校验商品是否已经推荐 if (productRecommendMapper.selectByProductSpuIdAndType(productRecommendAddDTO.getProductSpuId(), productRecommendAddDTO.getType()) != null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_EXISTS.getCode()); } // 保存到数据库 ProductRecommendDO productRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendAddDTO).setStatus(CommonStatusEnum.ENABLE.getValue()); @@ -68,16 +67,16 @@ public class ProductRecommendService { public Boolean updateProductRecommend(Integer adminId, ProductRecommendUpdateBO productRecommendUpdateDTO) { // 校验更新的商品推荐存在 if (productRecommendMapper.selectById(productRecommendUpdateDTO.getId()) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); } // 校验商品不存在 if (productSpuRpc.getProductSpu(productRecommendUpdateDTO.getProductSpuId()) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode()); } // 校验商品是否已经推荐 ProductRecommendDO existProductRecommend = productRecommendMapper.selectByProductSpuIdAndType(productRecommendUpdateDTO.getProductSpuId(), productRecommendUpdateDTO.getType()); if (existProductRecommend != null && !existProductRecommend.getId().equals(productRecommendUpdateDTO.getId())) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_EXISTS.getCode()); } // 更新到数据库 ProductRecommendDO updateProductRecommend = ProductRecommendConvert.INSTANCE.convert(productRecommendUpdateDTO); @@ -89,7 +88,7 @@ public class ProductRecommendService { public Boolean updateProductRecommendStatus(Integer adminId, Integer productRecommendId, Integer status) { // 校验更新的商品推荐存在 if (productRecommendMapper.selectById(productRecommendId) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); } // 更新到数据库 ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId).setStatus(status); @@ -101,7 +100,7 @@ public class ProductRecommendService { public Boolean deleteProductRecommend(Integer adminId, Integer productRecommendId) { // 校验更新的商品推荐存在 if (productRecommendMapper.selectById(productRecommendId) == null) { - throw ServiceExceptionUtil.exception(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); + throw ServiceExceptionUtil.exception(PromotionErrorCodeConstants.PRODUCT_RECOMMEND_NOT_EXISTS.getCode()); } // 更新到数据库 ProductRecommendDO updateProductRecommend = new ProductRecommendDO().setId(productRecommendId); diff --git a/promotion-service-project/promotion-service-app/src/main/resources/application-dev.yaml b/promotion-service-project/promotion-service-app/src/main/resources/application-dev.yaml new file mode 100644 index 000000000..332f6ce8f --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/resources/application-dev.yaml @@ -0,0 +1,21 @@ +spring: + # 数据源配置项 + datasource: + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/mall_promotionr?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: 3WLiVUBEwTbvAfsh + # Spring Cloud 配置项 + cloud: + nacos: + # Spring Cloud Nacos Discovery 配置项 + discovery: + server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址 + namespace: dev # Nacos 命名空间 + +# Dubbo 配置项 +dubbo: + # Dubbo 注册中心 + registry: + # address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址 + address: nacos://400-infra.server.iocoder.cn:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址 diff --git a/promotion-service-project/promotion-service-app/src/main/resources/application-local.yaml b/promotion-service-project/promotion-service-app/src/main/resources/application-local.yaml new file mode 100644 index 000000000..332deef02 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/resources/application-local.yaml @@ -0,0 +1,24 @@ +spring: + # 数据源配置项 + datasource: + url: jdbc:mysql://400-infra.server.iocoder.cn:3306/mall_promotion?useSSL=false&useUnicode=true&characterEncoding=UTF-8 + driver-class-name: com.mysql.jdbc.Driver + username: root + password: 3WLiVUBEwTbvAfsh + # Spring Cloud 配置项 + cloud: + nacos: + # Spring Cloud Nacos Discovery 配置项 + discovery: + server-addr: 400-infra.server.iocoder.cn:8848 # Nacos 服务器地址 + namespace: dev # Nacos 命名空间 + +# Dubbo 配置项 +dubbo: + # Dubbo 注册中心 + registry: +# address: spring-cloud://400-infra.server.iocoder.cn:8848 # 指定 Dubbo 服务注册中心的地址 + address: nacos://400-infra.server.iocoder.cn:8848?namespace=dev # 指定 Dubbo 服务注册中心的地址 + # Dubbo 服务提供者的配置 + provider: + tag: ${DUBBO_TAG} # Dubbo 路由分组 diff --git a/promotion-service-project/promotion-service-app/src/main/resources/application.yaml b/promotion-service-project/promotion-service-app/src/main/resources/application.yaml new file mode 100644 index 000000000..5fdb1ef92 --- /dev/null +++ b/promotion-service-project/promotion-service-app/src/main/resources/application.yaml @@ -0,0 +1,64 @@ +spring: + # Application 的配置项 + application: + name: promotion-service + # Profile 的配置项 + profiles: + active: local + +# MyBatis Plus 配置项 +mybatis-plus: + configuration: + map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。 + global-config: + db-config: + id-type: auto + logic-delete-value: 1 # 逻辑已删除值(默认为 1) + logic-not-delete-value: 0 # 逻辑未删除值(默认为 0) + mapper-locations: classpath*:mapper/*.xml + type-aliases-package: cn.iocoder.mall.promotionservice.dal.mysql.dataobject + +# Dubbo 配置项 +dubbo: + # Spring Cloud Alibaba Dubbo 专属配置 + cloud: + subscribed-services: '' # 设置订阅的应用列表,默认为 * 订阅所有应用 + # Dubbo 提供者的协议 + protocol: + name: dubbo + port: -1 + # Dubbo 提供服务的扫描基础包 + scan: + base-packages: cn.iocoder.mall.promotionservice.rpc + # Dubbo 服务提供者的配置 + provider: + filter: -exception + validation: true # 开启 Provider 参数校验 + version: 1.0.0 # 服务的版本号 + # Dubbo 服务消费者的配置 + consumer: + ErrorCodeRpc: + version: 1.0.0 + ProductSkuRpc: + version: 1.0.0 + ProductSpuService: + version: 1.0.0 + +# RocketMQ 配置项 +rocketmq: + name-server: 400-infra.server.iocoder.cn:9876 + producer: + group: ${spring.application.name}-producer-group + +# Actuator 监控配置项 +management: + server.port: 38085 # 独立端口,避免被暴露出去 + endpoints.web.exposure.include: '*' # 暴露所有监控端点 +server.port: ${management.server.port} # 设置使用 Actuator 的服务器端口,因为 RPC 服务不需要 Web 端口 + +# Mall 配置项 +mall: + # 错误码配置项对应 ErrorCodeProperties 配置类 + error-code: + group: ${spring.application.name} + constants-class: cn.iocoder.mall.promotionservice.enums.PromotionErrorCodeConstants diff --git a/shop-web-app/pom.xml b/shop-web-app/pom.xml index 162fe4da9..749465e14 100644 --- a/shop-web-app/pom.xml +++ b/shop-web-app/pom.xml @@ -66,6 +66,12 @@ search-service-api 1.0-SNAPSHOT + + + cn.iocoder.mall + order-service-api + 1.0-SNAPSHOT + cn.iocoder.mall diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java new file mode 100644 index 000000000..e511ab0bf --- /dev/null +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/controller/order/CartController.java @@ -0,0 +1,43 @@ +package cn.iocoder.mall.shopweb.controller.order; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.security.user.core.context.UserSecurityContextHolder; +import cn.iocoder.mall.shopweb.manager.order.cart.CartManager; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import static cn.iocoder.common.framework.vo.CommonResult.success; + +@Api(tags = "购物车 API") +@RestController +@RequestMapping("/cart") +@Validated +public class CartController { + + @Autowired + private CartManager cartManager; + + @PostMapping("add") + @ApiOperation("添加商品到购物车") + @ApiImplicitParams({ + @ApiImplicitParam(name = "skuId", value = "商品 SKU 编号", required = true, example = "1"), + @ApiImplicitParam(name = "quantity", value = "增加数量", required = true, example = "1024") + }) + public CommonResult addCartItem(@RequestParam("skuId") Integer skuId, + @RequestParam("quantity") Integer quantity) { + cartManager.addCartItem(UserSecurityContextHolder.getUserId(), skuId, quantity); + return success(true); + } + + @GetMapping("sum-quantity") + @ApiOperation("查询用户在购物车中的商品数量") + public CommonResult sumCartItemQuantity() { + return success(cartManager.sumCartItemQuantity(UserSecurityContextHolder.getUserId())); + } + +} diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java new file mode 100644 index 000000000..2c627dbac --- /dev/null +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/cart/CartManager.java @@ -0,0 +1,43 @@ +package cn.iocoder.mall.shopweb.manager.order.cart; + +import cn.iocoder.common.framework.vo.CommonResult; +import cn.iocoder.mall.orderservice.rpc.cart.CartRpc; +import cn.iocoder.mall.orderservice.rpc.cart.dto.CartItemAddReqDTO; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.stereotype.Service; + +/** + * 购物车 Manager + */ +@Service +public class CartManager { + + @DubboReference(version = "${dubbo.consumer.ProductCategoryRpc.version}") + private CartRpc cartRpc; + + /** + * 添加商品到购物车 + * + * @param userId 用户编号 + * @param skuId 商品 SKU 编号 + * @param quantity 增加数量 + */ + public void addCartItem(Integer userId, Integer skuId, Integer quantity) { + CommonResult addCartItemResult = cartRpc.addCartItem(new CartItemAddReqDTO().setUserId(userId) + .setSkuId(skuId).setQuantity(quantity)); + addCartItemResult.checkError(); + } + + /** + * 查询用户在购物车中的商品数量 + * + * @param userId 用户编号 + * @return 商品数量 + */ + public Integer sumCartItemQuantity(Integer userId) { + CommonResult sumCartItemQuantityResult = cartRpc.sumCartItemQuantity(userId); + sumCartItemQuantityResult.checkError(); + return sumCartItemQuantityResult.getData(); + } + +} diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java new file mode 100644 index 000000000..5ea6db8cb --- /dev/null +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/order/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.mall.shopweb.manager.order; diff --git a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/product/ProductCategoryManager.java b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/product/ProductCategoryManager.java index 67065deb0..8a00fbc80 100644 --- a/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/product/ProductCategoryManager.java +++ b/shop-web-app/src/main/java/cn/iocoder/mall/shopweb/manager/product/ProductCategoryManager.java @@ -7,7 +7,7 @@ import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryListQueryR import cn.iocoder.mall.productservice.rpc.category.dto.ProductCategoryRespDTO; import cn.iocoder.mall.shopweb.controller.product.vo.category.ProductCategoryRespVO; import cn.iocoder.mall.shopweb.convert.product.ProductCategoryConvert; -import org.apache.dubbo.config.annotation.Reference; +import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -20,7 +20,7 @@ import java.util.List; @Validated public class ProductCategoryManager { - @Reference(version = "${dubbo.consumer.ProductCategoryRpc.version}") + @DubboReference(version = "${dubbo.consumer.ProductCategoryRpc.version}") private ProductCategoryRpc productCategoryRpc; public List listProductCategories(Integer pid) {