From e6acdf70980bdc06f36127ebf77bf0b558292113 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sun, 30 Oct 2022 17:37:07 +0800 Subject: [PATCH] 将 market 模块,调整成 promotion 模块 --- yudao-module-mall/pom.xml | 6 +++--- yudao-module-mall/yudao-module-market-api/pom.xml | 33 --------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/package-info.java | 4 ---- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java | 21 --------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java | 56 -------------------------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java | 248 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/ErrorCodeConstants.java | 22 ---------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java | 39 --------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java | 37 ------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java | 40 ---------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java | 38 -------------------------------------- yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java | 40 ---------------------------------------- yudao-module-mall/yudao-module-market-biz/pom.xml | 72 ------------------------------------------------------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/discount/package-info.java | 1 - yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java | 26 -------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/BannerController.java | 71 ----------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerBaseVO.java | 42 ------------------------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerCreateReqVO.java | 22 ---------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerPageReqVO.java | 38 -------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerRespVO.java | 26 -------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerUpdateReqVO.java | 24 ------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java | 4 ---- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/AppMarketTestController.java | 24 ------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/banner/AppBannerController.java | 42 ------------------------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/banner/BannerConvert.java | 34 ---------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java | 4 ---- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/price/PriceConvert.java | 44 -------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/banner/BannerDO.java | 53 ----------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/coupon/CouponDO.java | 139 ------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java | 55 ------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java | 71 ----------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java | 116 -------------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/banner/BannerMapper.java | 26 -------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java | 4 ---- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java | 8 -------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerService.java | 63 --------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerServiceImpl.java | 78 ------------------------------------------------------------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponService.java | 24 ------------------------ yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponServiceImpl.java | 21 --------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountService.java | 25 ------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountServiceImpl.java | 29 ----------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceService.java | 21 --------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java | 487 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardService.java | 23 ----------------------- yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardServiceImpl.java | 26 -------------------------- yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java | 446 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/test/resources/application-unit-test.yaml | 49 ------------------------------------------------- yudao-module-mall/yudao-module-market-biz/src/test/resources/logback.xml | 4 ---- yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/clean.sql | 1 - yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/create_tables.sql | 19 ------------------- yudao-module-mall/yudao-module-promotion-api/pom.xml | 33 +++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java | 4 ++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java | 21 +++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java | 22 ++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java | 39 +++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java | 37 +++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java | 40 ++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/pom.xml | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java | 1 + yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java | 26 ++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java | 42 ++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java | 19 +++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java | 38 ++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java | 26 ++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java | 24 ++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java | 4 ++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java | 24 ++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java | 42 ++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java | 34 ++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java | 4 ++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java | 44 ++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java | 26 ++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java | 4 ++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java | 8 ++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java | 24 ++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java | 21 +++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java | 25 +++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java | 29 +++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java | 21 +++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java | 487 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java | 23 +++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java | 26 ++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java | 446 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml | 4 ++++ yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql | 1 + yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql | 19 +++++++++++++++++++ yudao-module-mall/yudao-module-trade-biz/pom.xml | 2 +- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java | 4 ++-- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java | 2 +- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java | 2 +- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java | 2 +- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java | 6 +++--- yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java | 6 +++--- yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java | 4 ++-- yudao-server/pom.xml | 2 +- 108 files changed, 2855 insertions(+), 2858 deletions(-) delete mode 100644 yudao-module-mall/yudao-module-market-api/pom.xml delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/ErrorCodeConstants.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java delete mode 100644 yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/pom.xml delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/discount/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/BannerController.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerBaseVO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerCreateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerPageReqVO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerRespVO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerUpdateReqVO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/AppMarketTestController.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/banner/AppBannerController.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/banner/BannerConvert.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/price/PriceConvert.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/banner/BannerDO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/coupon/CouponDO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/banner/BannerMapper.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerService.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponService.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountService.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceService.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardService.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardServiceImpl.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/test/resources/application-unit-test.yaml delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/test/resources/logback.xml delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/clean.sql delete mode 100644 yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/create_tables.sql create mode 100644 yudao-module-mall/yudao-module-promotion-api/pom.xml create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/pom.xml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql create mode 100644 yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql diff --git a/yudao-module-mall/pom.xml b/yudao-module-mall/pom.xml index cd761ab..4c362d5 100644 --- a/yudao-module-mall/pom.xml +++ b/yudao-module-mall/pom.xml @@ -15,13 +15,13 @@ ${project.artifactId} - 商城大模块,由 product 商品、market 营销、trade 交易 coupon等组成 + 商城大模块,由 product 商品、promotion 营销、trade 交易 coupon等组成 - yudao-module-market-api - yudao-module-market-biz + yudao-module-promotion-api + yudao-module-promotion-biz yudao-module-product-api yudao-module-product-biz yudao-module-trade-api diff --git a/yudao-module-mall/yudao-module-market-api/pom.xml b/yudao-module-mall/yudao-module-market-api/pom.xml deleted file mode 100644 index 9517c34..0000000 --- a/yudao-module-mall/yudao-module-market-api/pom.xml +++ /dev/null @@ -1,33 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - yudao-module-market-api - jar - - ${project.artifactId} - - market 模块 API,暴露给其它模块调用 - - - - - cn.iocoder.boot - yudao-common - - - - - org.springframework.boot - spring-boot-starter-validation - true - - - - diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/package-info.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/package-info.java deleted file mode 100644 index cb45004..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位 - */ -package cn.iocoder.yudao.module.market.api; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java deleted file mode 100644 index 532a66d..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.market.api.price; - -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; - -/** - * 价格 API 接口 - * - * @author 芋道源码 - */ -public interface PriceApi { - - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格相应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java deleted file mode 100644 index 4cc0196..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java +++ /dev/null @@ -1,56 +0,0 @@ -package cn.iocoder.yudao.module.market.api.price.dto; - -import lombok.Data; - -import javax.validation.constraints.Min; -import javax.validation.constraints.NotNull; -import java.util.List; - -/** - * 价格计算 Request DTO - * - * @author 芋道源码 - */ -@Data -public class PriceCalculateReqDTO { - - /** - * 用户编号 - * - * 对应 MemberUserDO 的 id 编号 - */ - private Long userId; - - /** - * 优惠劵编号 - */ - private Long couponId; - - /** - * 商品 SKU 数组 - */ - @NotNull(message = "商品数组不能为空") - private List items; - - /** - * 商品 SKU - */ - @Data - public static class Item { - - /** - * SKU 编号 - */ - @NotNull(message = "商品 SKU 编号不能为空") - private Long skuId; - - /** - * SKU 数量 - */ - @NotNull(message = "商品 SKU 数量不能为空") - @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况 - private Integer count; - - } - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java deleted file mode 100644 index c9660c4..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java +++ /dev/null @@ -1,248 +0,0 @@ -package cn.iocoder.yudao.module.market.api.price.dto; - -import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum; -import lombok.Data; - -import java.util.List; - -/** - * 价格计算 Response DTO - * - * 整体设计,参考 taobao 的技术文档: - * 1. 订单管理 - * 2. 常用订单金额说明 - * - * 举个例子:订单图 - * 输入: - * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元; - * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元; - * 分摊: - * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元; - * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元; - * - * @author 芋道源码 - */ -@Data -public class PriceCalculateRespDTO { - - /** - * 订单 - */ - private Order order; - - /** - * 营销活动数组 - * - * 只对应 {@link Order#items} 商品匹配的活动 - */ - private List promotions; - - /** - * 订单 - */ - @Data - public static class Order { - - /** - * 商品原价(总),单位:分 - * - * 基于 {@link OrderItem#getOriginalPrice()} 求和 - * 对应 taobao 的 trade.total_fee 字段 - */ - private Integer originalPrice; - /** - * 订单优惠(总),单位:分 - * - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 优惠劵减免金额(总),单位:分 - * - * 对应 taobao 的 trade.coupon_fee 字段 - */ - private Integer couponPrice; - /** - * 积分减免金额(总),单位:分 - * - * 对应 taobao 的 trade.point_fee 字段 - */ - private Integer pointPrice; - /** - * 运费金额,单位:分 - */ - private Integer deliveryPrice; - /** - * 最终购买金额(总),单位:分 - * - * = {@link OrderItem#getPayPrice()} 求和 - * - {@link #couponPrice} - * - {@link #pointPrice} - * + {@link #deliveryPrice} - */ - private Integer payPrice; - /** - * 商品 SKU 数组 - */ - private List items; - - // ========== 营销基本信息 ========== - /** - * 优惠劵编号 - */ - private Long couponId; - - } - - /** - * 订单商品 SKU - */ - @Data - public static class OrderItem { - - /** - * SPU 编号 - */ - private Long spuId; - /** - * SKU 编号 - */ - private Long skuId; - /** - * 购买数量 - */ - private Integer count; - - /** - * 商品原价(总),单位:分 - * - * = {@link #originalUnitPrice} * {@link #getCount()} - */ - private Integer originalPrice; - /** - * 商品原价(单),单位:分 - * - * 对应 ProductSkuDO 的 price 字段 - * 对应 taobao 的 order.price 字段 - */ - private Integer originalUnitPrice; - /** - * 商品优惠(总),单位:分 - * - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 - * - * 对应 taobao 的 order.discount_fee 字段 - */ - private Integer discountPrice; - /** - * 子订单实付金额,不算主订单分摊金额,单位:分 - * - * = {@link #originalPrice} - * - {@link #discountPrice} - * - * 对应 taobao 的 order.payment 字段 - */ - private Integer payPrice; - - /** - * 子订单分摊金额(总),单位:分 - * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice} - * - * 对应 taobao 的 order.part_mjz_discount 字段 - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 - */ - private Integer orderPartPrice; - /** - * 分摊后子订单实付金额(总),单位:分 - * - * = {@link #payPrice} - * - {@link #orderPartPrice} - * - * 对应 taobao 的 divide_order_fee 字段 - */ - private Integer orderDividePrice; - - } - - /** - * 营销明细 - */ - @Data - public static class Promotion { - - /** - * 营销编号 - * - * 例如说:营销活动的编号、优惠劵的编号 - */ - private Long id; - /** - * 营销名字 - */ - private String name; - /** - * 营销类型 - * - * 枚举 {@link PromotionTypeEnum} - */ - private Integer type; - /** - * 营销级别 - * - * 枚举 {@link PromotionLevelEnum} - */ - private Integer level; - /** - * 计算时的原价(总),单位:分 - */ - private Integer originalPrice; - /** - * 计算时的优惠(总),单位:分 - */ - private Integer discountPrice; - /** - * 匹配的商品 SKU 数组 - */ - private List items; - - // ========== 匹配情况 ========== - - /** - * 是否满足优惠条件 - */ - private Boolean meet; - /** - * 满足条件的提示 - * - * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” - * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” - */ - private String meetTip; - - } - - /** - * 营销匹配的商品 SKU - */ - @Data - public static class PromotionItem { - - /** - * 商品 SKU 编号 - */ - private Long skuId; - /** - * 计算时的原价(总),单位:分 - */ - private Integer originalPrice; - /** - * 计算时的优惠(总),单位:分 - */ - private Integer discountPrice; - - } - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/ErrorCodeConstants.java deleted file mode 100644 index 1cdf4bf..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/ErrorCodeConstants.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.market.enums; - -import cn.iocoder.yudao.framework.common.exception.ErrorCode; - -/** - * market 错误码枚举类 - *

- * market 系统,使用 1-003-000-000 段 - */ -public interface ErrorCodeConstants { - - // ========== 促销活动相关 1003001000 ============ TODO 芋艿:看看是不是要删除掉 - ErrorCode ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "促销活动不存在"); - - // ========== Banner 相关 1003002000 ============ - ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); - - // ========== Coupon 相关 1003003000 ============ - ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); - ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "不满足优惠劵使用的最低金额"); - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java deleted file mode 100644 index 9577841..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.iocoder.yudao.module.market.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 促销活动的状态枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum PromotionActivityStatusEnum implements IntArrayValuable { - - WAIT(10, "未开始"), - RUN(20, "进行中"), - END(30, "已结束"), - CLOSE(40, "已关闭"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray(); - - /** - * 状态值 - */ - private final Integer status; - /** - * 状态名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java deleted file mode 100644 index 4df0e69..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.market.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的条件类型枚举 - * - * @author 芋道源码 - */ -@AllArgsConstructor -@Getter -public enum PromotionConditionTypeEnum implements IntArrayValuable { - - PRICE(10, "满 N 元"), - COUNT(20, "满 N 件"); - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray(); - - /** - * 类型值 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java deleted file mode 100644 index 2f599dc..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.market.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的级别枚举 - * - * 参考有赞:营销级别 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionLevelEnum implements IntArrayValuable { - - ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 - SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 - COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); - - /** - * 级别值 - */ - private final Integer level; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java deleted file mode 100644 index e1792ee..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.market.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销的商品范围枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionProductScopeEnum implements IntArrayValuable { - - ALL(1, "全部商品参与"), - SPU(2, "指定商品参与"), - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); - - /** - * 范围值 - */ - private final Integer scope; - /** - * 范围名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } - -} diff --git a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java deleted file mode 100644 index 53f71fe..0000000 --- a/yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java +++ /dev/null @@ -1,40 +0,0 @@ -package cn.iocoder.yudao.module.market.enums.common; - -import cn.iocoder.yudao.framework.common.core.IntArrayValuable; -import lombok.AllArgsConstructor; -import lombok.Getter; - -import java.util.Arrays; - -/** - * 营销类型枚举 - * - * @author 芋道源码 - */ -@Getter -@AllArgsConstructor -public enum PromotionTypeEnum implements IntArrayValuable { - - DISCOUNT_ACTIVITY(1, "限时折扣"), - REWARD_ACTIVITY(2, "满减送"), - - MEMBER(3, "会员折扣"), - COUPON(4, "优惠劵") - ; - - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); - - /** - * 类型值 - */ - private final Integer type; - /** - * 类型名 - */ - private final String name; - - @Override - public int[] array() { - return ARRAYS; - } -} diff --git a/yudao-module-mall/yudao-module-market-biz/pom.xml b/yudao-module-mall/yudao-module-market-biz/pom.xml deleted file mode 100644 index dc90257..0000000 --- a/yudao-module-mall/yudao-module-market-biz/pom.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - cn.iocoder.boot - yudao-module-mall - ${revision} - - 4.0.0 - jar - yudao-module-market-biz - - ${project.artifactId} - - - market模块,主要实现营销相关功能 - 例如:营销活动、banner广告、优惠券、优惠码等功能。 - - - - - cn.iocoder.boot - yudao-module-market-api - ${revision} - - - cn.iocoder.boot - yudao-module-product-api - ${revision} - - - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-operatelog - - - cn.iocoder.boot - yudao-spring-boot-starter-biz-weixin - - - - - cn.iocoder.boot - yudao-spring-boot-starter-web - - - cn.iocoder.boot - yudao-spring-boot-starter-security - - - - - cn.iocoder.boot - yudao-spring-boot-starter-mybatis - - - - - cn.iocoder.boot - yudao-spring-boot-starter-test - - - - - cn.iocoder.boot - yudao-spring-boot-starter-excel - - - - diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/discount/package-info.java deleted file mode 100644 index 47820ec..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/discount/package-info.java +++ /dev/null @@ -1 +0,0 @@ -package cn.iocoder.yudao.module.market.api.discount; diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java deleted file mode 100644 index 74806dc..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApiImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.market.api.price; - -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.market.service.price.PriceService; -import org.springframework.stereotype.Service; - -import javax.annotation.Resource; - -/** - * 价格 API 实现类 - * - * @author 芋道源码 - */ -@Service -public class PriceApiImpl implements PriceApi { - - @Resource - private PriceService priceService; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - return priceService.calculatePrice(calculateReqDTO); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/BannerController.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/BannerController.java deleted file mode 100644 index 932ead7..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/BannerController.java +++ /dev/null @@ -1,71 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.*; -import cn.iocoder.yudao.module.market.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.market.service.banner.BannerService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiImplicitParam; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.*; - -import javax.annotation.Resource; -import javax.validation.Valid; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Api(tags = "管理后台 - Banner 管理") -@RestController -@RequestMapping("/market/banner") -@Validated -public class BannerController { - - @Resource - private BannerService bannerService; - - @PostMapping("/create") - @ApiOperation("创建 Banner") - @PreAuthorize("@ss.hasPermission('market:banner:create')") - public CommonResult createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) { - return success(bannerService.createBanner(createReqVO)); - } - - @PutMapping("/update") - @ApiOperation("更新 Banner") - @PreAuthorize("@ss.hasPermission('market:banner:update')") - public CommonResult updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) { - bannerService.updateBanner(updateReqVO); - return success(true); - } - - @DeleteMapping("/delete") - @ApiOperation("删除 Banner") - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('market:banner:delete')") - public CommonResult deleteBanner(@RequestParam("id") Long id) { - bannerService.deleteBanner(id); - return success(true); - } - - @GetMapping("/get") - @ApiOperation("获得 Banner") - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult getBanner(@RequestParam("id") Long id) { - BannerDO banner = bannerService.getBanner(id); - return success(BannerConvert.INSTANCE.convert(banner)); - } - - @GetMapping("/page") - @ApiOperation("获得 Banner 分页") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult> getBannerPage(@Valid BannerPageReqVO pageVO) { - PageResult pageResult = bannerService.getBannerPage(pageVO); - return success(BannerConvert.INSTANCE.convertPage(pageResult)); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerBaseVO.java deleted file mode 100644 index f5f37db..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerBaseVO.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner.vo; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; - -import javax.validation.constraints.NotNull; - -/** - * Banner Base VO,提供给添加、修改、详细的子 VO 使用 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 - * @author xia - */ -@Data -public class BannerBaseVO { - - @ApiModelProperty(value = "标题", required = true) - @NotNull(message = "标题不能为空") - private String title; - - @ApiModelProperty(value = "跳转链接", required = true) - @NotNull(message = "跳转链接不能为空") - private String url; - - @ApiModelProperty(value = "图片地址", required = true) - @NotNull(message = "图片地址不能为空") - private String picUrl; - - @ApiModelProperty(value = "排序", required = true) - @NotNull(message = "排序不能为空") - private Integer sort; - - @ApiModelProperty(value = "状态", required = true) - @NotNull(message = "状态不能为空") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @ApiModelProperty(value = "备注") - private String memo; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerCreateReqVO.java deleted file mode 100644 index 0bb0c1b..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerCreateReqVO.java +++ /dev/null @@ -1,22 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import java.util.Date; - -/** - * @author xia - */ -@ApiModel("管理后台 - Banner 创建 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerCreateReqVO extends BannerBaseVO { - - - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerPageReqVO.java deleted file mode 100644 index e1b960f..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerPageReqVO.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner.vo; - -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.framework.common.pojo.PageParam; -import cn.iocoder.yudao.framework.common.validation.InEnum; -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; -import org.springframework.format.annotation.DateTimeFormat; - -import java.util.Date; - -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; - -/** - * @author xia - */ -@ApiModel("管理后台 - Banner 分页 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerPageReqVO extends PageParam { - - @ApiModelProperty(value = "标题") - private String title; - - - @ApiModelProperty(value = "状态") - @InEnum(CommonStatusEnum.class) - private Integer status; - - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) - @ApiModelProperty(value = "创建时间") - private Date[] createTime; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerRespVO.java deleted file mode 100644 index f4045b9..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerRespVO.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.ToString; - -import javax.validation.constraints.NotNull; -import java.util.Date; - -/** - * @author xia - */ -@ApiModel("管理后台 - Banner Response VO") -@Data -@ToString(callSuper = true) -public class BannerRespVO extends BannerBaseVO { - - @ApiModelProperty(value = "banner编号", required = true) - @NotNull(message = "banner编号不能为空") - private Long id; - - @ApiModelProperty(value = "创建时间", required = true) - private Date createTime; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerUpdateReqVO.java deleted file mode 100644 index 1f2d7ce..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/banner/vo/BannerUpdateReqVO.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.admin.banner.vo; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.ToString; - -import javax.validation.constraints.NotNull; - -/** - * @author xia - */ -@ApiModel("管理后台 - Banner更新 Request VO") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public class BannerUpdateReqVO extends BannerBaseVO { - - @ApiModelProperty(value = "banner 编号", required = true) - @NotNull(message = "banner 编号不能为空") - private Long id; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java deleted file mode 100644 index a3f145f..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * TODO 占位 - */ -package cn.iocoder.yudao.module.market.controller.admin.discount; diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/AppMarketTestController.java deleted file mode 100644 index 7d45b87..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/AppMarketTestController.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.app; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Api(tags = "用户 App - 营销") -@RestController -@RequestMapping("/market/test") -@Validated -public class AppMarketTestController { - - @GetMapping("/get") - @ApiOperation("获取 market 信息") - public CommonResult get() { - return success("true"); - } -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/banner/AppBannerController.java deleted file mode 100644 index 9af420a..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/app/banner/AppBannerController.java +++ /dev/null @@ -1,42 +0,0 @@ -package cn.iocoder.yudao.module.market.controller.app.banner; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerRespVO; -import cn.iocoder.yudao.module.market.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.market.service.banner.BannerService; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -/** - * @author: XIA - */ -@RestController -@RequestMapping("/market/banner") -@Api(tags = "用户APP- 首页Banner") -@Validated -public class AppBannerController { - - @Resource - private BannerService bannerService; - - // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 - @GetMapping("/list") - @ApiOperation("获得banner列表") - @PreAuthorize("@ss.hasPermission('market:banner:query')") - public CommonResult> getBannerList() { - List list = bannerService.getBannerList(); - return success(BannerConvert.INSTANCE.convertList(list)); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/banner/BannerConvert.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/banner/BannerConvert.java deleted file mode 100644 index a78650f..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/banner/BannerConvert.java +++ /dev/null @@ -1,34 +0,0 @@ -package cn.iocoder.yudao.module.market.convert.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerRespVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.List; - -/** - * Banner Convert - * - * @author xia - */ -@Mapper -public interface BannerConvert { - - BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class); - - - List convertList(List list); - - PageResult convertPage(PageResult pageResult); - - BannerRespVO convert(BannerDO banner); - - BannerDO convert(BannerCreateReqVO createReqVO); - - BannerDO convert(BannerUpdateReqVO updateReqVO); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java deleted file mode 100644 index 7874924..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * TODO 占位 - */ -package cn.iocoder.yudao.module.market.convert.discount; diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/price/PriceConvert.java deleted file mode 100644 index d48553b..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/price/PriceConvert.java +++ /dev/null @@ -1,44 +0,0 @@ -package cn.iocoder.yudao.module.market.convert.price; - -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -@Mapper -public interface PriceConvert { - - PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class); - - default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List skuList) { - // 创建 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); - // 创建它的 Order 属性 - PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setOriginalPrice(0).setDiscountPrice(0) - .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) - .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); - priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); - // 创建它的 OrderItem 属性 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - skuList.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem() - .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) - .setOriginalUnitPrice(sku.getPrice()).setOriginalPrice(sku.getPrice() * count) - .setDiscountPrice(0).setOrderPartPrice(0); - orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); - priceCalculate.getOrder().getItems().add(orderItem); - // 补充价格信息到 Order 中 - order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); - }); - return priceCalculate; - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/banner/BannerDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/banner/BannerDO.java deleted file mode 100644 index 1f48f71..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/banner/BannerDO.java +++ /dev/null @@ -1,53 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.dataobject.banner; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.*; - -/** - * banner DO - * - * @author xia - */ -@TableName("market_banner") -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -@Builder -@NoArgsConstructor -@AllArgsConstructor -public class BannerDO extends BaseDO { - - /** - * 编号 - */ - private Long id; - /** - * 标题 - */ - private String title; - /** - * 跳转链接 - */ - private String url; - /** - * 图片链接 - */ - private String picUrl; - /** - * 排序 - */ - private Integer sort; - - /** - * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} - */ - private Integer status; - /** - * 备注 - */ - private String memo; - - // TODO 芋艿 点击次数。&& 其他数据相关 - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/coupon/CouponDO.java deleted file mode 100644 index 8c72e64..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/coupon/CouponDO.java +++ /dev/null @@ -1,139 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.dataobject.coupon; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.experimental.Accessors; - -import java.util.Date; -import java.util.List; - -// TODO 芋艿:待完善该实体 -/** - * 优惠劵 DO - */ -@TableName("coupon") -@Data -@EqualsAndHashCode(callSuper = true) -@Accessors(chain = true) -public class CouponDO extends BaseDO { - - // ========== 基本信息 BEGIN ========== - /** - * 优惠劵编号 - */ - private Long id; - /** - * 优惠劵(码)分组编号,{@link CouponTemplateDO} 的 id - */ - private Integer templateId; - /** - * 优惠劵名 - * - * 冗余自 {@link CouponTemplateDO} 的 title - * - * TODO 芋艿,暂时不考虑冗余的更新 - */ - private String title; -// /** -// * 核销码 -// */ -// private String verifyCode; - /** - * 优惠码状态 - * - * 1-未使用 - * 2-已使用 - * 3-已失效 - */ - private Integer status; - - // ========== 基本信息 END ========== - - // ========== 领取情况 BEGIN ========== - /** - * 用户编号 - */ - private Integer userId; - /** - * 领取类型 - * - * 1 - 用户主动领取 - * 2 - 后台自动发放 - */ - private Integer takeType; - // ========== 领取情况 END ========== - - // ========== 使用规则 BEGIN ========== - /** - * 是否设置满多少金额可用,单位:分 - */ - private Integer priceAvailable; - /** - * 生效开始时间 - */ - private Date validStartTime; - /** - * 生效结束时间 - */ - private Date validEndTime; - /** - * 商品范围 - * - * 枚举 {@link PromotionProductScopeEnum} - */ - private Integer productScope; - /** - * 商品 SPU 编号的数组 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List spuIds; - // ========== 使用规则 END ========== - - // ========== 使用效果 BEGIN ========== - /** - * 优惠类型 - * - * 1-代金卷 - * 2-折扣卷 - */ - private Integer preferentialType; - /** - * 折扣 - */ - private Integer percentOff; - /** - * 优惠金额,单位:分。 - */ - private Integer priceOff; - /** - * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 - * - * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 - */ - private Integer discountPriceLimit; - // ========== 使用效果 END ========== - - // ========== 使用情况 BEGIN ========== -// /** -// * 使用订单号 -// */ -// private Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段 -// /** -// * 订单中优惠面值,单位:分 -// */ -// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段 - /** - * 使用时间 - */ - private Date usedTime; - - // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 - - // ========== 使用情况 END ========== - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java deleted file mode 100644 index 8780546..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java +++ /dev/null @@ -1,55 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.dataobject.discount; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; - -/** - * 限时折扣活动 DO - * - * 一个活动下,可以有 {@link DiscountProductDO} 商品; - * 一个商品,在指定时间段内,只能属于一个活动; - * - * @author 芋道源码 - */ -@TableName(value = "promotion_discount_activity", autoResultMap = true) -@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class DiscountActivityDO extends BaseDO { - - /** - * 活动编号,主键自增 - */ - @TableId - private Long id; - /** - * 活动标题 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link PromotionActivityStatusEnum} - */ - private Integer status; - /** - * 开始时间 - */ - private Date startTime; - /** - * 结束时间 - */ - private Date endTime; - /** - * 备注 - */ - private String remark; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java deleted file mode 100644 index 42d4f85..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java +++ /dev/null @@ -1,71 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.dataobject.discount; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; - -/** - * 限时折扣商品 DO - * - * @author 芋道源码 - */ -@TableName(value = "promotion_discount_product", autoResultMap = true) -@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class DiscountProductDO extends BaseDO { - - /** - * 编号,主键自增 - */ - @TableId - private Long id; - /** - * 限时折扣活动的编号 - * - * 关联 {@link DiscountActivityDO#getId()} - */ - private Long activityId; - /** - * 限时折扣活动的名字 - * - * 冗余 {@link DiscountActivityDO#getName()} - */ - private String activityName; - /** - * 商品 SPU 编号 - * - * 关联 ProductSpuDO 的 id 编号 - */ - private Long spuId; - /** - * 商品 SKU 编号 - * - * 关联 ProductSkuDO 的 id 编号 - */ - private Long skuId; - /** - * 开始时间 - */ - private Date startTime; - /** - * 结束时间 - */ - private Date endTime; - /** - * 销售价格,单位:分 - * - * 冗余 ProductSkuDO 的 price 字段 - */ - private Integer originalPrice; - /** - * 优惠价格,单位:分 - */ - private Integer promotionPrice; - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java deleted file mode 100644 index 756e574..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java +++ /dev/null @@ -1,116 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.dataobject.reward; - -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; -import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionConditionTypeEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum; -import com.baomidou.mybatisplus.annotation.KeySequence; -import com.baomidou.mybatisplus.annotation.TableField; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableName; -import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; -import lombok.Data; -import lombok.EqualsAndHashCode; - -import java.util.Date; -import java.util.List; - -/** - * 满减送活动 DO - * - * @author 芋道源码 - */ -@TableName(value = "promotion_reward_activity", autoResultMap = true) -@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 -@Data -@EqualsAndHashCode(callSuper = true) -public class RewardActivityDO extends BaseDO { - - /** - * 活动编号,主键自增 - */ - @TableId - private Long id; - /** - * 活动标题 - */ - private String name; - /** - * 状态 - * - * 枚举 {@link PromotionActivityStatusEnum} - */ - private Integer status; - /** - * 开始时间 - */ - private Date startTime; - /** - * 结束时间 - */ - private Date endTime; - /** - * 备注 - */ - private String remark; - /** - * 条件类型 - * - * 枚举 {@link PromotionConditionTypeEnum} - */ - private Integer conditionType; - /** - * 商品范围 - * - * 枚举 {@link PromotionProductScopeEnum} - */ - private Integer productScope; - /** - * 商品 SPU 编号的数组 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List spuIds; - /** - * 优惠规则的数组 - */ - @TableField(typeHandler = JacksonTypeHandler.class) - private List rules; - - /** - * 优惠规则 - */ - @Data - public static class Rule { - - /** - * 优惠门槛 - * - * 1. 满 N 元,单位:分 - * 2. 满 N 件 - */ - private Integer limit; - /** - * 优惠价格,单位:分 - */ - private Integer discountPrice; - /** - * 是否包邮 - */ - private Boolean freeDelivery; - /** - * 赠送的积分 - */ - private Integer point; - /** - * 赠送的优惠劵编号的数组 - */ - private List couponIds; - /** - * 赠送的优惠卷数量的数组 - */ - private List couponCounts; - - } - - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/banner/BannerMapper.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/banner/BannerMapper.java deleted file mode 100644 index 4d22f61..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/banner/BannerMapper.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.market.dal.mysql.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; -import org.apache.ibatis.annotations.Mapper; - -/** - * Banner Mapper - * - * @author xia - */ -@Mapper -public interface BannerMapper extends BaseMapperX { - - default PageResult selectPage(BannerPageReqVO reqVO) { - return selectPage(reqVO, new LambdaQueryWrapperX() - .likeIfPresent(BannerDO::getTitle, reqVO.getTitle()) - .eqIfPresent(BannerDO::getStatus, reqVO.getStatus()) - .betweenIfPresent(BannerDO::getCreateTime, reqVO.getCreateTime()) - .orderByDesc(BannerDO::getSort)); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java deleted file mode 100644 index f8de42c..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * TODO 占位 - */ -package cn.iocoder.yudao.module.market.dal.mysql.discount; diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java deleted file mode 100644 index 92b9c69..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java +++ /dev/null @@ -1,8 +0,0 @@ -/** - * promotion 模块,我们放营销业务。 - * 例如说:营销活动、banner、优惠券等等 - * - * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突 - * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分 - */ -package cn.iocoder.yudao.module.market; diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerService.java deleted file mode 100644 index 67debdc..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerService.java +++ /dev/null @@ -1,63 +0,0 @@ -package cn.iocoder.yudao.module.market.service.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; - -import javax.validation.Valid; -import java.util.List; - -/** - * 首页 Banner Service 接口 - * - * @author xia - */ -public interface BannerService { - - /** - * 创建 Banner - * - * @param createReqVO 创建信息 - * @return 编号 - */ - Long createBanner(@Valid BannerCreateReqVO createReqVO); - - /** - * 更新 Banner - * - * @param updateReqVO 更新信息 - */ - void updateBanner(@Valid BannerUpdateReqVO updateReqVO); - - /** - * 删除 Banner - * - * @param id 编号 - */ - void deleteBanner(Long id); - - /** - * 获得 Banner - * - * @param id 编号 - * @return Banner - */ - BannerDO getBanner(Long id); - - /** - * 获得所有 Banner列表 - * @return Banner列表 - */ - List getBannerList(); - - /** - * 获得 Banner 分页 - * - * @param pageReqVO 分页查询 - * @return Banner分页 - */ - PageResult getBannerPage(BannerPageReqVO pageReqVO); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerServiceImpl.java deleted file mode 100644 index d36db0c..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/banner/BannerServiceImpl.java +++ /dev/null @@ -1,78 +0,0 @@ -package cn.iocoder.yudao.module.market.service.banner; - -import cn.iocoder.yudao.framework.common.pojo.PageResult; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerCreateReqVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerPageReqVO; -import cn.iocoder.yudao.module.market.controller.admin.banner.vo.BannerUpdateReqVO; -import cn.iocoder.yudao.module.market.convert.banner.BannerConvert; -import cn.iocoder.yudao.module.market.dal.dataobject.banner.BannerDO; -import cn.iocoder.yudao.module.market.dal.mysql.banner.BannerMapper; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.List; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.BANNER_NOT_EXISTS; - -/** - * 首页 banner 实现类 - * - * @author xia - */ -@Service -@Validated -public class BannerServiceImpl implements BannerService { - - @Resource - private BannerMapper bannerMapper; - - @Override - public Long createBanner(BannerCreateReqVO createReqVO) { - // 插入 - BannerDO banner = BannerConvert.INSTANCE.convert(createReqVO); - bannerMapper.insert(banner); - // 返回 - return banner.getId(); - } - - @Override - public void updateBanner(BannerUpdateReqVO updateReqVO) { - // 校验存在 - this.validateBannerExists(updateReqVO.getId()); - // 更新 - BannerDO updateObj = BannerConvert.INSTANCE.convert(updateReqVO); - bannerMapper.updateById(updateObj); - } - - @Override - public void deleteBanner(Long id) { - // 校验存在 - this.validateBannerExists(id); - // 删除 - bannerMapper.deleteById(id); - } - - private void validateBannerExists(Long id) { - if (bannerMapper.selectById(id) == null) { - throw exception(BANNER_NOT_EXISTS); - } - } - - @Override - public BannerDO getBanner(Long id) { - return bannerMapper.selectById(id); - } - - @Override - public List getBannerList() { - return bannerMapper.selectList(); - } - - @Override - public PageResult getBannerPage(BannerPageReqVO pageReqVO) { - return bannerMapper.selectPage(pageReqVO); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponService.java deleted file mode 100644 index 943f20e..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponService.java +++ /dev/null @@ -1,24 +0,0 @@ -package cn.iocoder.yudao.module.market.service.coupon; - -import cn.iocoder.yudao.module.market.dal.dataobject.coupon.CouponDO; - -/** - * 优惠劵 Service 接口 - * - * @author 芋道源码 - */ -public interface CouponService { - - /** - * 校验优惠劵,包括状态、有限期 - * - * 1. 如果校验通过,则返回优惠劵信息 - * 2. 如果校验不通过,则直接抛出业务异常 - * - * @param id 优惠劵编号 - * @param userId 用户编号 - * @return 优惠劵信息 - */ - CouponDO validCoupon(Long id, Long userId); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponServiceImpl.java deleted file mode 100644 index 8afaab4..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/coupon/CouponServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.market.service.coupon; - -import cn.iocoder.yudao.module.market.dal.dataobject.coupon.CouponDO; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -/** - * 优惠劵 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class CouponServiceImpl implements CouponService { - - // TODO 芋艿:待实现 - @Override - public CouponDO validCoupon(Long id, Long userId) { - return null; - } -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountService.java deleted file mode 100644 index 12c497d..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountService.java +++ /dev/null @@ -1,25 +0,0 @@ -package cn.iocoder.yudao.module.market.service.discount; - -import cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountProductDO; - -import java.util.Collection; -import java.util.Map; - -/** - * 限时折扣 Service 接口 - * - * @author 芋道源码 - */ -public interface DiscountService { - - /** - * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 - * - * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 - * - * @param skuIds SKU 编号数组 - * @return 匹配的限时折扣商品 - */ - Map getMatchDiscountProducts(Collection skuIds); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountServiceImpl.java deleted file mode 100644 index 2b8440d..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/DiscountServiceImpl.java +++ /dev/null @@ -1,29 +0,0 @@ -package cn.iocoder.yudao.module.market.service.discount; - -import cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountProductDO; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * 限时折扣 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class DiscountServiceImpl implements DiscountService { - - // TODO 芋艿:待实现 - @Override - public Map getMatchDiscountProducts(Collection skuIds) { - Map products = new HashMap<>(); - products.put(1L, new DiscountProductDO().setPromotionPrice(100)); - products.put(2L, new DiscountProductDO().setPromotionPrice(50)); - return products; - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceService.java deleted file mode 100644 index 9158199..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceService.java +++ /dev/null @@ -1,21 +0,0 @@ -package cn.iocoder.yudao.module.market.service.price; - -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; - -/** - * 价格计算 Service 接口 - * - * @author 芋道源码 - */ -public interface PriceService { - - /** - * 计算商品的价格 - * - * @param calculateReqDTO 价格请求 - * @return 价格相应 - */ - PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java deleted file mode 100644 index 737a0e4..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceServiceImpl.java +++ /dev/null @@ -1,487 +0,0 @@ -package cn.iocoder.yudao.module.market.service.price; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.market.convert.price.PriceConvert; -import cn.iocoder.yudao.module.market.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.market.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.market.enums.common.PromotionConditionTypeEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum; -import cn.iocoder.yudao.module.market.service.coupon.CouponService; -import cn.iocoder.yudao.module.market.service.discount.DiscountService; -import cn.iocoder.yudao.module.market.service.reward.RewardService; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import com.google.common.base.Suppliers; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import javax.annotation.Resource; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.function.Supplier; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; -import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE; -import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU; -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; -import static java.util.Collections.singletonList; - -/** - * 价格计算 Service 实现类 - * - * 优惠计算顺序:min(限时折扣, 会员折扣) > 满减送 > 优惠券。 - * 参考文档: - * 1. 有赞文档:限时折扣、满减送、优惠券哪个优先计算? - * - * TODO 芋艿:进一步完善 - * 1. 限时折扣:指定金额、减免金额、折扣 - * 2. 满减送:循环、折扣 - * 3. 优惠劵:待定 - * - * @author 芋道源码 - */ -@Service -@Validated -public class PriceServiceImpl implements PriceService { - - @Resource - private DiscountService discountService; - @Resource - private RewardService rewardService; - @Resource - private CouponService couponService; - - @Resource - private ProductSkuApi productSkuApi; - - @Override - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - List skuList = checkSkus(calculateReqDTO); - // 初始化 PriceCalculateRespDTO 对象 - PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); - - // 计算商品级别的价格 - calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算订单级别的价格 - calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); - // 计算优惠劵级别的价格 - calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); - // 计算【优惠劵】促销 TODO 待实现 - return priceCalculate; - } - - private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { - // 获得商品 SKU 数组 - Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), - PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); - List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); - - // 校验商品 SKU - skus.forEach(sku -> { - Integer count = skuIdCountMap.get(sku.getId()); - if (count == null) { - throw exception(SKU_NOT_EXISTS); - } - // 不校验库存不足,避免购物车场景,商品无货的情况 - }); - return skus; - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算商品级别的价格,例如说: - * 1. 会员折扣 - * 2. 限时折扣 {@link cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountActivityDO} - * - * 其中,会员折扣、限时折扣取最低价 - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Supplier memberDiscountSupplier = getMemberDiscountSupplier(userId); - Map discountProducts = discountService.getMatchDiscountProducts( - convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); - - // 处理每个 SKU 的优惠 - priceCalculate.getOrder().getItems().forEach(orderItem -> { - // 获取该 SKU 的优惠信息 - Double memberDiscount = memberDiscountSupplier.get(); - DiscountProductDO discountProduct = discountProducts.get(orderItem.getSkuId()); - if (discountProduct != null // 假设优惠价格更贵,则认为没优惠 - && discountProduct.getPromotionPrice() >= orderItem.getOriginalUnitPrice()) { - discountProduct = null; - } - if (memberDiscount == null && discountProduct == null) { - return; - } - // 计算价格,判断选择哪个折扣 - Integer memberPrice = memberDiscount != null ? (int) (orderItem.getPayPrice() * memberDiscount / 100) : null; - Integer promotionPrice = discountProduct != null ? discountProduct.getPromotionPrice() * orderItem.getCount() : null; - if (memberPrice == null) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else if (promotionPrice == null) { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } else if (memberPrice < promotionPrice) { - calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); - } else { - calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); - } - }); - } - - private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Integer memberPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), - PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, - true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); - } - - private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - DiscountProductDO discountProduct, Integer promotionPrice) { - // 记录优惠明细 - addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), - PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, - true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); - // 修改 SKU 的优惠 - modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); - } - - // TODO 芋艿:提前实现 - private Supplier getMemberDiscountSupplier(Long userId) { - return Suppliers.memoize(() -> { - if (userId == 1) { - return 90d; - } - if (userId == 2) { - return 80d; - } - return null; // 无优惠 - }); - } - - // ========== 计算商品级别的价格 ========== - - /** - * 计算订单级别的价格,例如说: - * 1. 满减送 {@link cn.iocoder.yudao.module.market.dal.dataobject.reward.RewardActivityDO} - * - * @param userId 用户编号 - * @param priceCalculate 价格计算的结果 - */ - @SuppressWarnings("unused") - private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { - // 获取 SKU 级别的所有优惠信息 - Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); - Map> rewardActivities = rewardService.getMatchRewardActivities(spuIds); - - // 处理满减送活动 - if (CollUtil.isNotEmpty(rewardActivities)) { - rewardActivities.forEach((rewardActivity, activitySpuIds) -> { - List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); - calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); - }); - } - } - - private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, - RewardActivityDO rewardActivity) { - // 获得最大匹配的满减送活动的规格 - RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); - if (rule == null) { - // 获取不到的情况下,记录不满足的优惠明细 - addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), - getRewardActivityNotMeetTip(rewardActivity)); - return; - } - - // 分摊金额 - // TODO 芋艿:limit 不能超过最大价格 - List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), - PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, - true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); - } - } - - /** - * 获得最大匹配的满减送活动的规格 - * - * @param rewardActivity 满减送活动 - * @param orderItems 商品项 - * @return 匹配的活动规格 - */ - private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, - List orderItems) { - Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); - // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 - Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert count != null && price != null; - for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { - RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); - if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) - && price >= rule.getLimit()) { - return rule; - } - if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) - && count >= rule.getLimit()) { - return rule; - } - } - return null; - } - - /** - * 获得满减送活动部匹配时的提示 - * - * @param rewardActivity 满减送活动 - * @return 提示 - */ - private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { - return "TODO"; // TODO 芋艿:后面再想想 - } - - // ========== 计算优惠劵级别的价格 ========== - - private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { - // 校验优惠劵 - if (couponId == null) { - return; - } - CouponDO coupon = couponService.validCoupon(couponId, userId); - - // 获得匹配的商品 SKU 数组 - List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); - if (CollUtil.isEmpty(orderItems)) { - throw exception(COUPON_NO_MATCH_SPU); - } - - // 计算是否满足优惠劵的使用金额 - Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert originPrice != null; - if (originPrice < coupon.getPriceAvailable()) { - throw exception(COUPON_NO_MATCH_MIN_PRICE); - } - - // 计算可以优惠的金额 - priceCalculate.getOrder().setCouponId(couponId); - Integer couponPrice = getCouponPrice(coupon, originPrice); - // 分摊金额 - // TODO 芋艿:limit 不能超过最大价格 - List couponPartPrices = dividePrice(orderItems, couponPrice); - // 记录优惠明细 - addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getTitle(), - PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, - true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); - // 修改 SKU 的分摊 - for (int i = 0; i < orderItems.size(); i++) { - modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); - } - } - - private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, - CouponDO coupon) { - if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { - return priceCalculate.getOrder().getItems(); - } - return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), - orderItem -> coupon.getSpuIds().contains(orderItem.getSpuId())); - } - - private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { - // TODO 芋艿 getPreferentialType 的枚举判断 - if (coupon.getPreferentialType().equals(1)) { // 减价 - return coupon.getPriceOff(); - } else if (coupon.getPreferentialType().equals(2)) { // 打折 - Integer couponPrice = originPrice * coupon.getPercentOff() / 100; - return coupon.getDiscountPriceLimit() == null ? couponPrice - : Math.min(couponPrice, coupon.getDiscountPriceLimit()); // 优惠上限 - } - throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon.toString())); - } - - // ========== 其它相对通用的方法 ========== - - /** - * 添加单个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItem 单个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param newPayPrice 新的单实付金额(总) - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, - Long id, String name, Integer type, Integer level, - Integer newPayPrice, Boolean meet, String meetTip) { - // 创建营销明细 Item - // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice - PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) - .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 添加多个 OrderItem 的营销明细 - * - * @param priceCalculate 价格计算结果 - * @param orderItems 多个订单商品 SKU - * @param id 营销编号 - * @param name 营销名字 - * @param type 营销类型 - * @param level 营销级别 - * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 - * @param meet 是否满足优惠条件 - * @param meetTip 满足条件的提示 - */ - private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, - List discountPrices, Boolean meet, String meetTip) { - // 创建营销明细 Item - List promotionItems = new ArrayList<>(discountPrices.size()); - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); - } - // 创建营销明细 - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) - .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) - .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, - Long id, String name, Integer type, Integer level, String meetTip) { - // 创建营销明细 Item - List promotionItems = CollectionUtils.convertList(orderItems, - orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) - .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); - // 创建营销明细 - Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() - .setId(id).setName(name).setType(type).setLevel(level) - .setOriginalPrice(originalPrice).setDiscountPrice(0) - .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); - priceCalculate.getPromotions().add(promotion); - } - - /** - * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 - * - * @param orderItem 订单商品 SKU - * @param newPayPrice 新的 payPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, - PriceCalculateRespDTO priceCalculate) { - int diffPayPrice = orderItem.getPayPrice() - newPayPrice; - // 设置 OrderItem 价格相关字段 - orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); - orderItem.setPayPrice(newPayPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - priceCalculate.getOrder().setPayPrice(priceCalculate.getOrder().getPayPrice() - diffPayPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 - * - * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 discountPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - /** - * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 - * - * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 - * - * @param orderItem 订单商品 SKU - * @param addOrderPartPrice 新增的 couponPrice 价格 - * @param priceCalculate 价格计算结果 - */ - private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, - PriceCalculateRespDTO priceCalculate) { - // 设置 OrderItem 价格相关字段 - orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); - orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); - // 设置 Order 相关相关字段 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); - order.setPayPrice(order.getPayPrice() - addOrderPartPrice); - } - - private List dividePrice(List orderItems, Integer price) { - List prices = new ArrayList<>(orderItems.size()); - Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); - assert total != null; - int remainPrice = price; - // 遍历每一个,进行分摊 - for (int i = 0; i < orderItems.size(); i++) { - PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); - int partPrice; - if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 - partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); - remainPrice -= partPrice; - } else { - partPrice = remainPrice; - } - Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); - prices.add(partPrice); - } - return prices; - } - - private String formatPrice(Integer price) { - return String.format("%.2f", price / 100d); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardService.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardService.java deleted file mode 100644 index bffa573..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardService.java +++ /dev/null @@ -1,23 +0,0 @@ -package cn.iocoder.yudao.module.market.service.reward; - -import cn.iocoder.yudao.module.market.dal.dataobject.reward.RewardActivityDO; - -import java.util.Map; -import java.util.Set; - -/** - * 满减送 Service 接口 - * - * @author 芋道源码 - */ -public interface RewardService { - - /** - * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 - * - * @param spuIds SPU 编号数组 - * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 - */ - Map> getMatchRewardActivities(Set spuIds); - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardServiceImpl.java b/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardServiceImpl.java deleted file mode 100644 index 8d3c364..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/reward/RewardServiceImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package cn.iocoder.yudao.module.market.service.reward; - -import cn.iocoder.yudao.module.market.dal.dataobject.reward.RewardActivityDO; -import org.springframework.stereotype.Service; -import org.springframework.validation.annotation.Validated; - -import java.util.Collections; -import java.util.Map; -import java.util.Set; - -/** - * 满减送 Service 实现类 - * - * @author 芋道源码 - */ -@Service -@Validated -public class RewardServiceImpl implements RewardService { - - // TODO 芋艿:待实现 - @Override - public Map> getMatchRewardActivities(Set spuIds) { - return Collections.emptyMap(); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java deleted file mode 100644 index 0664f78..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/price/PriceServiceTest.java +++ /dev/null @@ -1,446 +0,0 @@ -package cn.iocoder.yudao.module.market.service.price; - -import cn.hutool.core.map.MapUtil; -import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.market.dal.dataobject.coupon.CouponDO; -import cn.iocoder.yudao.module.market.dal.dataobject.discount.DiscountProductDO; -import cn.iocoder.yudao.module.market.dal.dataobject.reward.RewardActivityDO; -import cn.iocoder.yudao.module.market.enums.common.PromotionConditionTypeEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum; -import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum; -import cn.iocoder.yudao.module.market.service.coupon.CouponService; -import cn.iocoder.yudao.module.market.service.discount.DiscountService; -import cn.iocoder.yudao.module.market.service.reward.RewardService; -import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; -import static java.util.Arrays.asList; -import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; - -/** - * {@link PriceServiceImpl} 的单元测试 - * - * @author 芋道源码 - */ -public class PriceServiceTest extends BaseMockitoUnitTest { - - @InjectMocks - private PriceServiceImpl priceService; - - @Mock - private DiscountService discountService; - @Mock - private RewardService rewardService; - @Mock - private CouponService couponService; - @Mock - private ProductSkuApi productSkuApi; - - @Test - public void testCalculatePrice_memberDiscount() { - // 准备参数 - // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) - .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 200); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 180); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 1); - PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); - assertEquals(orderItem.getSkuId(), 10L); - assertEquals(orderItem.getCount(), 2); - assertEquals(orderItem.getOriginalPrice(), 200); - assertEquals(orderItem.getOriginalUnitPrice(), 100); - assertEquals(orderItem.getDiscountPrice(), 20); - assertEquals(orderItem.getPayPrice(), 180); - assertEquals(orderItem.getOrderPartPrice(), 0); - assertEquals(orderItem.getOrderDividePrice(), 180); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); - assertNull(promotion.getId()); - assertEquals(promotion.getName(), "会员折扣"); - assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); - assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion.getOriginalPrice(), 200); - assertEquals(promotion.getDiscountPrice(), 20); - assertTrue(promotion.getMeet()); - assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); - PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); - assertEquals(promotion.getItems().size(), 1); - assertEquals(promotionItem.getSkuId(), 10L); - assertEquals(promotionItem.getOriginalPrice(), 200); - assertEquals(promotionItem.getDiscountPrice(), 20); - } - - @Test - public void testCalculatePrice_discountActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - DiscountProductDO discountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(1000L).setActivityName("活动 1000 号") - .setSkuId(10L).setPromotionPrice(80)); - DiscountProductDO discountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(2000L).setActivityName("活动 2000 号") - .setSkuId(20L).setPromotionPrice(40)); - when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( - MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 280); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 40); - assertEquals(orderItem01.getPayPrice(), 160); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 30); - assertEquals(orderItem02.getPayPrice(), 120); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 120); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 200); - assertEquals(promotion01.getDiscountPrice(), 40); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.40 元"); - PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); - assertEquals(promotion01.getItems().size(), 1); - assertEquals(promotionItem01.getSkuId(), 10L); - assertEquals(promotionItem01.getOriginalPrice(), 200); - assertEquals(promotionItem01.getDiscountPrice(), 40); - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 150); - assertEquals(promotion02.getDiscountPrice(), 30); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.30 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 20L); - assertEquals(promotionItem02.getOriginalPrice(), 150); - assertEquals(promotionItem02.getDiscountPrice(), 30); - } - - /** - * 测试满减送活动,匹配的情况 - */ - @Test - public void testCalculatePrice_rewardActivity() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(200).setDiscountPrice(70)))); - RewardActivityDO rewardActivity02 = randomPojo(RewardActivityDO.class, o -> o.setId(2000L).setName("活动 2000 号") - .setSpuIds(singletonList(30L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) - .setRules(asList(new RewardActivityDO.Rule().setLimit(1).setDiscountPrice(10), - new RewardActivityDO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 - new RewardActivityDO.Rule().setLimit(10).setDiscountPrice(100)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - matchRewardActivities.put(rewardActivity02, asSet(3L)); - when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getDiscountPrice(), 130); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 340); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 60); - assertEquals(orderItem03.getOrderDividePrice(), 60); - // 断言 Promotion 部分(第一个) - assertEquals(priceCalculate.getPromotions().size(), 2); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - // 断言 Promotion 部分(第二个) - PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); - assertEquals(promotion02.getId(), 2000L); - assertEquals(promotion02.getName(), "活动 2000 号"); - assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion02.getOriginalPrice(), 120); - assertEquals(promotion02.getDiscountPrice(), 60); - assertTrue(promotion02.getMeet()); - assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); - PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); - assertEquals(promotion02.getItems().size(), 1); - assertEquals(promotionItem02.getSkuId(), 30L); - assertEquals(promotionItem02.getOriginalPrice(), 120); - assertEquals(promotionItem02.getDiscountPrice(), 60); - } - - /** - * 测试满减送活动,不匹配的情况 - */ - @Test - public void testCalculatePrice_rewardActivityNotMeet() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); - // mock 方法(限时折扣 DiscountActivity 信息) - RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") - .setSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) - .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); - Map> matchRewardActivities = new LinkedHashMap<>(); - matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); - when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 350); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 350); - assertNull(order.getCouponId()); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 2); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 0); - assertEquals(orderItem01.getOrderDividePrice(), 200); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 0); - assertEquals(orderItem02.getOrderDividePrice(), 150); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1000L); - assertEquals(promotion01.getName(), "活动 1000 号"); - assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 0); - assertFalse(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 0); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 0); - } - - @Test - public void testCalculatePrice_coupon() { - // 准备参数 - PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) - .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), - new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), - new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) - .setCouponId(1024L); - // mock 方法(商品 SKU 信息) - ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); - ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); - ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); - when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); - // mock 方法(优惠劵 Coupon 信息) - CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setTitle("程序员节") - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setSpuIds(asList(1L, 2L)) - .setPriceAvailable(350).setPreferentialType(2).setPercentOff(50).setDiscountPriceLimit(70)); - when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); - - // 200 + 150; 350 - // - - // 调用 - PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); - // 断言 Order 部分 - PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); - assertEquals(order.getOriginalPrice(), 470); - assertEquals(order.getDiscountPrice(), 0); - assertEquals(order.getPointPrice(), 0); - assertEquals(order.getDeliveryPrice(), 0); - assertEquals(order.getPayPrice(), 400); - assertEquals(order.getCouponId(), 1024L); - assertEquals(order.getCouponPrice(), 70); - // 断言 OrderItem 部分 - assertEquals(order.getItems().size(), 3); - PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); - assertEquals(orderItem01.getSkuId(), 10L); - assertEquals(orderItem01.getCount(), 2); - assertEquals(orderItem01.getOriginalPrice(), 200); - assertEquals(orderItem01.getOriginalUnitPrice(), 100); - assertEquals(orderItem01.getDiscountPrice(), 0); - assertEquals(orderItem01.getPayPrice(), 200); - assertEquals(orderItem01.getOrderPartPrice(), 40); - assertEquals(orderItem01.getOrderDividePrice(), 160); - PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); - assertEquals(orderItem02.getSkuId(), 20L); - assertEquals(orderItem02.getCount(), 3); - assertEquals(orderItem02.getOriginalPrice(), 150); - assertEquals(orderItem02.getOriginalUnitPrice(), 50); - assertEquals(orderItem02.getDiscountPrice(), 0); - assertEquals(orderItem02.getPayPrice(), 150); - assertEquals(orderItem02.getOrderPartPrice(), 30); - assertEquals(orderItem02.getOrderDividePrice(), 120); - PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); - assertEquals(orderItem03.getSkuId(), 30L); - assertEquals(orderItem03.getCount(), 4); - assertEquals(orderItem03.getOriginalPrice(), 120); - assertEquals(orderItem03.getOriginalUnitPrice(), 30); - assertEquals(orderItem03.getDiscountPrice(), 0); - assertEquals(orderItem03.getPayPrice(), 120); - assertEquals(orderItem03.getOrderPartPrice(), 0); - assertEquals(orderItem03.getOrderDividePrice(), 120); - // 断言 Promotion 部分 - assertEquals(priceCalculate.getPromotions().size(), 1); - PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); - assertEquals(promotion01.getId(), 1024L); - assertEquals(promotion01.getName(), "程序员节"); - assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); - assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); - assertEquals(promotion01.getOriginalPrice(), 350); - assertEquals(promotion01.getDiscountPrice(), 70); - assertTrue(promotion01.getMeet()); - assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); - assertEquals(promotion01.getItems().size(), 2); - PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); - assertEquals(promotionItem011.getSkuId(), 10L); - assertEquals(promotionItem011.getOriginalPrice(), 200); - assertEquals(promotionItem011.getDiscountPrice(), 40); - PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); - assertEquals(promotionItem012.getSkuId(), 20L); - assertEquals(promotionItem012.getOriginalPrice(), 150); - assertEquals(promotionItem012.getDiscountPrice(), 30); - } - -} diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-market-biz/src/test/resources/application-unit-test.yaml deleted file mode 100644 index 60914d9..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/test/resources/application-unit-test.yaml +++ /dev/null @@ -1,49 +0,0 @@ -spring: - main: - lazy-initialization: true # 开启懒加载,加快速度 - banner-mode: off # 单元测试,禁用 Banner - ---- #################### 数据库相关配置 #################### - -spring: - # 数据源配置项 - datasource: - name: ruoyi-vue-pro - url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 - driver-class-name: org.h2.Driver - username: sa - password: - druid: - async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 - initial-size: 1 # 单元测试,配置为 1,提升启动速度 - sql: - init: - schema-locations: classpath:/sql/create_tables.sql - - # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 - redis: - host: 127.0.0.1 # 地址 - port: 16379 # 端口(单元测试,使用 16379 端口) - database: 0 # 数据库索引 - -mybatis: - lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 - ---- #################### 定时任务相关配置 #################### - ---- #################### 配置中心相关配置 #################### - ---- #################### 服务保障相关配置 #################### - -# Lock4j 配置项(单元测试,禁用 Lock4j) - -# Resilience4j 配置项 - ---- #################### 监控相关配置 #################### - ---- #################### 芋道相关配置 #################### - -# 芋道配置项,设置当前项目所有自定义的配置 -yudao: - info: - base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-market-biz/src/test/resources/logback.xml deleted file mode 100644 index daf756b..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/test/resources/logback.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/clean.sql deleted file mode 100644 index abad7c0..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/clean.sql +++ /dev/null @@ -1 +0,0 @@ -DELETE FROM "market_activity"; diff --git a/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/create_tables.sql deleted file mode 100644 index 3f3ce3c..0000000 --- a/yudao-module-mall/yudao-module-market-biz/src/test/resources/sql/create_tables.sql +++ /dev/null @@ -1,19 +0,0 @@ -CREATE TABLE IF NOT EXISTS "market_activity" ( - "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, - "title" varchar(50) NOT NULL, - "activity_type" tinyint(4) NOT NULL, - "status" tinyint(4) NOT NULL, - "start_time" datetime NOT NULL, - "end_time" datetime NOT NULL, - "invalid_time" datetime, - "delete_time" datetime, - "time_limited_discount" varchar(2000), - "full_privilege" varchar(2000), - "creator" varchar(64) DEFAULT '', - "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - "updater" varchar(64) DEFAULT '', - "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, - "deleted" bit NOT NULL DEFAULT FALSE, - "tenant_id" bigint(20) NOT NULL, - PRIMARY KEY ("id") - ) COMMENT '促销活动'; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-promotion-api/pom.xml b/yudao-module-mall/yudao-module-promotion-api/pom.xml new file mode 100644 index 0000000..510b17b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/pom.xml @@ -0,0 +1,33 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + yudao-module-promotion-api + jar + + ${project.artifactId} + + market 模块 API,暴露给其它模块调用 + + + + + cn.iocoder.boot + yudao-common + + + + + org.springframework.boot + spring-boot-starter-validation + true + + + + diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java new file mode 100644 index 0000000..08e1020 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/package-info.java @@ -0,0 +1,4 @@ +/** + * 占位 + */ +package cn.iocoder.yudao.module.promotion.api; diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java new file mode 100644 index 0000000..b36c938 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.api.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; + +/** + * 价格 API 接口 + * + * @author 芋道源码 + */ +public interface PriceApi { + + /** + * 计算商品的价格 + * + * @param calculateReqDTO 价格请求 + * @return 价格相应 + */ + PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java new file mode 100644 index 0000000..01f0ac2 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java @@ -0,0 +1,56 @@ +package cn.iocoder.yudao.module.promotion.api.price.dto; + +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.util.List; + +/** + * 价格计算 Request DTO + * + * @author 芋道源码 + */ +@Data +public class PriceCalculateReqDTO { + + /** + * 用户编号 + * + * 对应 MemberUserDO 的 id 编号 + */ + private Long userId; + + /** + * 优惠劵编号 + */ + private Long couponId; + + /** + * 商品 SKU 数组 + */ + @NotNull(message = "商品数组不能为空") + private List items; + + /** + * 商品 SKU + */ + @Data + public static class Item { + + /** + * SKU 编号 + */ + @NotNull(message = "商品 SKU 编号不能为空") + private Long skuId; + + /** + * SKU 数量 + */ + @NotNull(message = "商品 SKU 数量不能为空") + @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况 + private Integer count; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java new file mode 100644 index 0000000..99cb36a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java @@ -0,0 +1,248 @@ +package cn.iocoder.yudao.module.promotion.api.price.dto; + +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import lombok.Data; + +import java.util.List; + +/** + * 价格计算 Response DTO + * + * 整体设计,参考 taobao 的技术文档: + * 1. 订单管理 + * 2. 常用订单金额说明 + * + * 举个例子:订单图 + * 输入: + * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元; + * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元; + * 分摊: + * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元; + * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元; + * + * @author 芋道源码 + */ +@Data +public class PriceCalculateRespDTO { + + /** + * 订单 + */ + private Order order; + + /** + * 营销活动数组 + * + * 只对应 {@link Order#items} 商品匹配的活动 + */ + private List promotions; + + /** + * 订单 + */ + @Data + public static class Order { + + /** + * 商品原价(总),单位:分 + * + * 基于 {@link OrderItem#getOriginalPrice()} 求和 + * 对应 taobao 的 trade.total_fee 字段 + */ + private Integer originalPrice; + /** + * 订单优惠(总),单位:分 + * + * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 优惠劵减免金额(总),单位:分 + * + * 对应 taobao 的 trade.coupon_fee 字段 + */ + private Integer couponPrice; + /** + * 积分减免金额(总),单位:分 + * + * 对应 taobao 的 trade.point_fee 字段 + */ + private Integer pointPrice; + /** + * 运费金额,单位:分 + */ + private Integer deliveryPrice; + /** + * 最终购买金额(总),单位:分 + * + * = {@link OrderItem#getPayPrice()} 求和 + * - {@link #couponPrice} + * - {@link #pointPrice} + * + {@link #deliveryPrice} + */ + private Integer payPrice; + /** + * 商品 SKU 数组 + */ + private List items; + + // ========== 营销基本信息 ========== + /** + * 优惠劵编号 + */ + private Long couponId; + + } + + /** + * 订单商品 SKU + */ + @Data + public static class OrderItem { + + /** + * SPU 编号 + */ + private Long spuId; + /** + * SKU 编号 + */ + private Long skuId; + /** + * 购买数量 + */ + private Integer count; + + /** + * 商品原价(总),单位:分 + * + * = {@link #originalUnitPrice} * {@link #getCount()} + */ + private Integer originalPrice; + /** + * 商品原价(单),单位:分 + * + * 对应 ProductSkuDO 的 price 字段 + * 对应 taobao 的 order.price 字段 + */ + private Integer originalUnitPrice; + /** + * 商品优惠(总),单位:分 + * + * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元 + * + * 对应 taobao 的 order.discount_fee 字段 + */ + private Integer discountPrice; + /** + * 子订单实付金额,不算主订单分摊金额,单位:分 + * + * = {@link #originalPrice} + * - {@link #discountPrice} + * + * 对应 taobao 的 order.payment 字段 + */ + private Integer payPrice; + + /** + * 子订单分摊金额(总),单位:分 + * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice} + * + * 对应 taobao 的 order.part_mjz_discount 字段 + * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。 + */ + private Integer orderPartPrice; + /** + * 分摊后子订单实付金额(总),单位:分 + * + * = {@link #payPrice} + * - {@link #orderPartPrice} + * + * 对应 taobao 的 divide_order_fee 字段 + */ + private Integer orderDividePrice; + + } + + /** + * 营销明细 + */ + @Data + public static class Promotion { + + /** + * 营销编号 + * + * 例如说:营销活动的编号、优惠劵的编号 + */ + private Long id; + /** + * 营销名字 + */ + private String name; + /** + * 营销类型 + * + * 枚举 {@link PromotionTypeEnum} + */ + private Integer type; + /** + * 营销级别 + * + * 枚举 {@link PromotionLevelEnum} + */ + private Integer level; + /** + * 计算时的原价(总),单位:分 + */ + private Integer originalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + /** + * 匹配的商品 SKU 数组 + */ + private List items; + + // ========== 匹配情况 ========== + + /** + * 是否满足优惠条件 + */ + private Boolean meet; + /** + * 满足条件的提示 + * + * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元” + * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元” + */ + private String meetTip; + + } + + /** + * 营销匹配的商品 SKU + */ + @Data + public static class PromotionItem { + + /** + * 商品 SKU 编号 + */ + private Long skuId; + /** + * 计算时的原价(总),单位:分 + */ + private Integer originalPrice; + /** + * 计算时的优惠(总),单位:分 + */ + private Integer discountPrice; + + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java new file mode 100644 index 0000000..0976f84 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.promotion.enums; + +import cn.iocoder.yudao.framework.common.exception.ErrorCode; + +/** + * market 错误码枚举类 + *

+ * market 系统,使用 1-003-000-000 段 + */ +public interface ErrorCodeConstants { + + // ========== 促销活动相关 1003001000 ============ TODO 芋艿:看看是不是要删除掉 + ErrorCode ACTIVITY_NOT_EXISTS = new ErrorCode(1003001000, "促销活动不存在"); + + // ========== Banner 相关 1003002000 ============ + ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1003002000, "Banner 不存在"); + + // ========== Coupon 相关 1003003000 ============ + ErrorCode COUPON_NO_MATCH_SPU = new ErrorCode(1003003000, "优惠劵没有可使用的商品!"); + ErrorCode COUPON_NO_MATCH_MIN_PRICE = new ErrorCode(1003003000, "不满足优惠劵使用的最低金额"); + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java new file mode 100644 index 0000000..db79f87 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionActivityStatusEnum.java @@ -0,0 +1,39 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 促销活动的状态枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum PromotionActivityStatusEnum implements IntArrayValuable { + + WAIT(10, "未开始"), + RUN(20, "进行中"), + END(30, "已结束"), + CLOSE(40, "已关闭"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray(); + + /** + * 状态值 + */ + private final Integer status; + /** + * 状态名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java new file mode 100644 index 0000000..05e62e3 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionConditionTypeEnum.java @@ -0,0 +1,37 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的条件类型枚举 + * + * @author 芋道源码 + */ +@AllArgsConstructor +@Getter +public enum PromotionConditionTypeEnum implements IntArrayValuable { + + PRICE(10, "满 N 元"), + COUNT(20, "满 N 件"); + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray(); + + /** + * 类型值 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java new file mode 100644 index 0000000..ed0564a --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionLevelEnum.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的级别枚举 + * + * 参考有赞:营销级别 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionLevelEnum implements IntArrayValuable { + + ORDER(1, "订单级"), // 多个商品,进行组合后优惠。例如说:满减送、打包一口价、第二件半价 + SKU(2, "商品级"), // 单个商品,直接优惠。例如说:限时折扣、会员折扣 + COUPON(3, "优惠劵"), // 多个商品,进行组合后优惠。例如说:优惠劵 + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray(); + + /** + * 级别值 + */ + private final Integer level; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java new file mode 100644 index 0000000..0a7a499 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionProductScopeEnum.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销的商品范围枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionProductScopeEnum implements IntArrayValuable { + + ALL(1, "全部商品参与"), + SPU(2, "指定商品参与"), + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray(); + + /** + * 范围值 + */ + private final Integer scope; + /** + * 范围名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java new file mode 100644 index 0000000..eea48f7 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/common/PromotionTypeEnum.java @@ -0,0 +1,40 @@ +package cn.iocoder.yudao.module.promotion.enums.common; + +import cn.iocoder.yudao.framework.common.core.IntArrayValuable; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +/** + * 营销类型枚举 + * + * @author 芋道源码 + */ +@Getter +@AllArgsConstructor +public enum PromotionTypeEnum implements IntArrayValuable { + + DISCOUNT_ACTIVITY(1, "限时折扣"), + REWARD_ACTIVITY(2, "满减送"), + + MEMBER(3, "会员折扣"), + COUPON(4, "优惠劵") + ; + + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray(); + + /** + * 类型值 + */ + private final Integer type; + /** + * 类型名 + */ + private final String name; + + @Override + public int[] array() { + return ARRAYS; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/pom.xml b/yudao-module-mall/yudao-module-promotion-biz/pom.xml new file mode 100644 index 0000000..e8b7640 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/pom.xml @@ -0,0 +1,72 @@ + + + + cn.iocoder.boot + yudao-module-mall + ${revision} + + 4.0.0 + jar + yudao-module-promotion-biz + + ${project.artifactId} + + + market模块,主要实现营销相关功能 + 例如:营销活动、banner广告、优惠券、优惠码等功能。 + + + + + cn.iocoder.boot + yudao-module-promotion-api + ${revision} + + + cn.iocoder.boot + yudao-module-product-api + ${revision} + + + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-operatelog + + + cn.iocoder.boot + yudao-spring-boot-starter-biz-weixin + + + + + cn.iocoder.boot + yudao-spring-boot-starter-web + + + cn.iocoder.boot + yudao-spring-boot-starter-security + + + + + cn.iocoder.boot + yudao-spring-boot-starter-mybatis + + + + + cn.iocoder.boot + yudao-spring-boot-starter-test + + + + + cn.iocoder.boot + yudao-spring-boot-starter-excel + + + + diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java new file mode 100644 index 0000000..4e3ce77 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/package-info.java @@ -0,0 +1 @@ +package cn.iocoder.yudao.module.promotion.api.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java new file mode 100644 index 0000000..3c415f1 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.api.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.service.price.PriceService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 价格 API 实现类 + * + * @author 芋道源码 + */ +@Service +public class PriceApiImpl implements PriceApi { + + @Resource + private PriceService priceService; + + @Override + public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { + return priceService.calculatePrice(calculateReqDTO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java new file mode 100644 index 0000000..0fbef12 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/BannerController.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.*; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.service.banner.BannerService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.validation.Valid; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "管理后台 - Banner 管理") +@RestController +@RequestMapping("/market/banner") +@Validated +public class BannerController { + + @Resource + private BannerService bannerService; + + @PostMapping("/create") + @ApiOperation("创建 Banner") + @PreAuthorize("@ss.hasPermission('market:banner:create')") + public CommonResult createBanner(@Valid @RequestBody BannerCreateReqVO createReqVO) { + return success(bannerService.createBanner(createReqVO)); + } + + @PutMapping("/update") + @ApiOperation("更新 Banner") + @PreAuthorize("@ss.hasPermission('market:banner:update')") + public CommonResult updateBanner(@Valid @RequestBody BannerUpdateReqVO updateReqVO) { + bannerService.updateBanner(updateReqVO); + return success(true); + } + + @DeleteMapping("/delete") + @ApiOperation("删除 Banner") + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('market:banner:delete')") + public CommonResult deleteBanner(@RequestParam("id") Long id) { + bannerService.deleteBanner(id); + return success(true); + } + + @GetMapping("/get") + @ApiOperation("获得 Banner") + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult getBanner(@RequestParam("id") Long id) { + BannerDO banner = bannerService.getBanner(id); + return success(BannerConvert.INSTANCE.convert(banner)); + } + + @GetMapping("/page") + @ApiOperation("获得 Banner 分页") + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult> getBannerPage(@Valid BannerPageReqVO pageVO) { + PageResult pageResult = bannerService.getBannerPage(pageVO); + return success(BannerConvert.INSTANCE.convertPage(pageResult)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java new file mode 100644 index 0000000..3083856 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerBaseVO.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotNull; + +/** + * Banner Base VO,提供给添加、修改、详细的子 VO 使用 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 + * @author xia + */ +@Data +public class BannerBaseVO { + + @ApiModelProperty(value = "标题", required = true) + @NotNull(message = "标题不能为空") + private String title; + + @ApiModelProperty(value = "跳转链接", required = true) + @NotNull(message = "跳转链接不能为空") + private String url; + + @ApiModelProperty(value = "图片地址", required = true) + @NotNull(message = "图片地址不能为空") + private String picUrl; + + @ApiModelProperty(value = "排序", required = true) + @NotNull(message = "排序不能为空") + private Integer sort; + + @ApiModelProperty(value = "状态", required = true) + @NotNull(message = "状态不能为空") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @ApiModelProperty(value = "备注") + private String memo; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java new file mode 100644 index 0000000..c058fd8 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerCreateReqVO.java @@ -0,0 +1,19 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +/** + * @author xia + */ +@ApiModel("管理后台 - Banner 创建 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerCreateReqVO extends BannerBaseVO { + + + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java new file mode 100644 index 0000000..0928efe --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerPageReqVO.java @@ -0,0 +1,38 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import cn.iocoder.yudao.framework.common.validation.InEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; + +/** + * @author xia + */ +@ApiModel("管理后台 - Banner 分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerPageReqVO extends PageParam { + + @ApiModelProperty(value = "标题") + private String title; + + + @ApiModelProperty(value = "状态") + @InEnum(CommonStatusEnum.class) + private Integer status; + + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + @ApiModelProperty(value = "创建时间") + private Date[] createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java new file mode 100644 index 0000000..bdcac8d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerRespVO.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.ToString; + +import javax.validation.constraints.NotNull; +import java.util.Date; + +/** + * @author xia + */ +@ApiModel("管理后台 - Banner Response VO") +@Data +@ToString(callSuper = true) +public class BannerRespVO extends BannerBaseVO { + + @ApiModelProperty(value = "banner编号", required = true) + @NotNull(message = "banner编号不能为空") + private Long id; + + @ApiModelProperty(value = "创建时间", required = true) + private Date createTime; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java new file mode 100644 index 0000000..971a873 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/banner/vo/BannerUpdateReqVO.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.controller.admin.banner.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.validation.constraints.NotNull; + +/** + * @author xia + */ +@ApiModel("管理后台 - Banner更新 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class BannerUpdateReqVO extends BannerBaseVO { + + @ApiModelProperty(value = "banner 编号", required = true) + @NotNull(message = "banner 编号不能为空") + private Long id; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java new file mode 100644 index 0000000..06f40bb --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/discount/package-info.java @@ -0,0 +1,4 @@ +/** + * TODO 占位 + */ +package cn.iocoder.yudao.module.promotion.controller.admin.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java new file mode 100644 index 0000000..d6d6689 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/AppMarketTestController.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.controller.app; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +@Api(tags = "用户 App - 营销") +@RestController +@RequestMapping("/market/test") +@Validated +public class AppMarketTestController { + + @GetMapping("/get") + @ApiOperation("获取 market 信息") + public CommonResult get() { + return success("true"); + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java new file mode 100644 index 0000000..4edd1ed --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/banner/AppBannerController.java @@ -0,0 +1,42 @@ +package cn.iocoder.yudao.module.promotion.controller.app.banner; + +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.service.banner.BannerService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; + +/** + * @author: XIA + */ +@RestController +@RequestMapping("/market/banner") +@Api(tags = "用户APP- 首页Banner") +@Validated +public class AppBannerController { + + @Resource + private BannerService bannerService; + + // TODO @xia:新建一个 AppBannerRespVO,只返回必要的字段。status 要过滤下。然后 sort 下结果 + @GetMapping("/list") + @ApiOperation("获得banner列表") + @PreAuthorize("@ss.hasPermission('market:banner:query')") + public CommonResult> getBannerList() { + List list = bannerService.getBannerList(); + return success(BannerConvert.INSTANCE.convertList(list)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java new file mode 100644 index 0000000..87d2da1 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/banner/BannerConvert.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.promotion.convert.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerRespVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * Banner Convert + * + * @author xia + */ +@Mapper +public interface BannerConvert { + + BannerConvert INSTANCE = Mappers.getMapper(BannerConvert.class); + + + List convertList(List list); + + PageResult convertPage(PageResult pageResult); + + BannerRespVO convert(BannerDO banner); + + BannerDO convert(BannerCreateReqVO createReqVO); + + BannerDO convert(BannerUpdateReqVO updateReqVO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java new file mode 100644 index 0000000..ce5ff84 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/discount/package-info.java @@ -0,0 +1,4 @@ +/** + * TODO 占位 + */ +package cn.iocoder.yudao.module.promotion.convert.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java new file mode 100644 index 0000000..bca6bb9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/price/PriceConvert.java @@ -0,0 +1,44 @@ +package cn.iocoder.yudao.module.promotion.convert.price; + +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@Mapper +public interface PriceConvert { + + PriceConvert INSTANCE = Mappers.getMapper(PriceConvert.class); + + default PriceCalculateRespDTO convert(PriceCalculateReqDTO calculateReqDTO, List skuList) { + // 创建 PriceCalculateRespDTO 对象 + PriceCalculateRespDTO priceCalculate = new PriceCalculateRespDTO(); + // 创建它的 Order 属性 + PriceCalculateRespDTO.Order order = new PriceCalculateRespDTO.Order().setOriginalPrice(0).setDiscountPrice(0) + .setCouponPrice(0).setPointPrice(0).setDeliveryPrice(0).setPayPrice(0) + .setItems(new ArrayList<>()).setCouponId(calculateReqDTO.getCouponId()); + priceCalculate.setOrder(order).setPromotions(new ArrayList<>()); + // 创建它的 OrderItem 属性 + Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), + PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); + skuList.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + PriceCalculateRespDTO.OrderItem orderItem = new PriceCalculateRespDTO.OrderItem() + .setSpuId(sku.getSpuId()).setSkuId(sku.getId()).setCount(count) + .setOriginalUnitPrice(sku.getPrice()).setOriginalPrice(sku.getPrice() * count) + .setDiscountPrice(0).setOrderPartPrice(0); + orderItem.setPayPrice(orderItem.getOriginalPrice()).setOrderDividePrice(orderItem.getOriginalPrice()); + priceCalculate.getOrder().getItems().add(orderItem); + // 补充价格信息到 Order 中 + order.setOriginalPrice(order.getOriginalPrice() + orderItem.getOriginalPrice()).setPayPrice(order.getOriginalPrice()); + }); + return priceCalculate; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java new file mode 100644 index 0000000..585462b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/banner/BannerDO.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.banner; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.*; + +/** + * banner DO + * + * @author xia + */ +@TableName("market_banner") +@Data +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BannerDO extends BaseDO { + + /** + * 编号 + */ + private Long id; + /** + * 标题 + */ + private String title; + /** + * 跳转链接 + */ + private String url; + /** + * 图片链接 + */ + private String picUrl; + /** + * 排序 + */ + private Integer sort; + + /** + * 状态 {@link cn.iocoder.yudao.framework.common.enums.CommonStatusEnum} + */ + private Integer status; + /** + * 备注 + */ + private String memo; + + // TODO 芋艿 点击次数。&& 其他数据相关 + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java new file mode 100644 index 0000000..2e37c58 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java @@ -0,0 +1,139 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.coupon; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.util.Date; +import java.util.List; + +// TODO 芋艿:待完善该实体 +/** + * 优惠劵 DO + */ +@TableName("coupon") +@Data +@EqualsAndHashCode(callSuper = true) +@Accessors(chain = true) +public class CouponDO extends BaseDO { + + // ========== 基本信息 BEGIN ========== + /** + * 优惠劵编号 + */ + private Long id; + /** + * 优惠劵(码)分组编号,{@link CouponTemplateDO} 的 id + */ + private Integer templateId; + /** + * 优惠劵名 + * + * 冗余自 {@link CouponTemplateDO} 的 title + * + * TODO 芋艿,暂时不考虑冗余的更新 + */ + private String title; +// /** +// * 核销码 +// */ +// private String verifyCode; + /** + * 优惠码状态 + * + * 1-未使用 + * 2-已使用 + * 3-已失效 + */ + private Integer status; + + // ========== 基本信息 END ========== + + // ========== 领取情况 BEGIN ========== + /** + * 用户编号 + */ + private Integer userId; + /** + * 领取类型 + * + * 1 - 用户主动领取 + * 2 - 后台自动发放 + */ + private Integer takeType; + // ========== 领取情况 END ========== + + // ========== 使用规则 BEGIN ========== + /** + * 是否设置满多少金额可用,单位:分 + */ + private Integer priceAvailable; + /** + * 生效开始时间 + */ + private Date validStartTime; + /** + * 生效结束时间 + */ + private Date validEndTime; + /** + * 商品范围 + * + * 枚举 {@link PromotionProductScopeEnum} + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List spuIds; + // ========== 使用规则 END ========== + + // ========== 使用效果 BEGIN ========== + /** + * 优惠类型 + * + * 1-代金卷 + * 2-折扣卷 + */ + private Integer preferentialType; + /** + * 折扣 + */ + private Integer percentOff; + /** + * 优惠金额,单位:分。 + */ + private Integer priceOff; + /** + * 折扣上限,仅在 {@link #preferentialType} 等于 2 时生效。 + * + * 例如,折扣上限为 20 元,当使用 8 折优惠券,订单金额为 1000 元时,最高只可折扣 20 元,而非 80 元。 + */ + private Integer discountPriceLimit; + // ========== 使用效果 END ========== + + // ========== 使用情况 BEGIN ========== +// /** +// * 使用订单号 +// */ +// private Integer usedOrderId; // TODO 芋艿,暂时不考虑这个字段 +// /** +// * 订单中优惠面值,单位:分 +// */ +// private Integer usedPrice; // TODO 芋艿,暂时不考虑这个字段 + /** + * 使用时间 + */ + private Date usedTime; + + // TODO 芋艿,后续要加优惠劵的使用日志,因为下单后,可能会取消。 + + // ========== 使用情况 END ========== + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java new file mode 100644 index 0000000..ca5dfdd --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountActivityDO.java @@ -0,0 +1,55 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 限时折扣活动 DO + * + * 一个活动下,可以有 {@link DiscountProductDO} 商品; + * 一个商品,在指定时间段内,只能属于一个活动; + * + * @author 芋道源码 + */ +@TableName(value = "promotion_discount_activity", autoResultMap = true) +@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class DiscountActivityDO extends BaseDO { + + /** + * 活动编号,主键自增 + */ + @TableId + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link PromotionActivityStatusEnum} + */ + private Integer status; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 备注 + */ + private String remark; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java new file mode 100644 index 0000000..aacbc28 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/discount/DiscountProductDO.java @@ -0,0 +1,71 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.discount; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 限时折扣商品 DO + * + * @author 芋道源码 + */ +@TableName(value = "promotion_discount_product", autoResultMap = true) +@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class DiscountProductDO extends BaseDO { + + /** + * 编号,主键自增 + */ + @TableId + private Long id; + /** + * 限时折扣活动的编号 + * + * 关联 {@link DiscountActivityDO#getId()} + */ + private Long activityId; + /** + * 限时折扣活动的名字 + * + * 冗余 {@link DiscountActivityDO#getName()} + */ + private String activityName; + /** + * 商品 SPU 编号 + * + * 关联 ProductSpuDO 的 id 编号 + */ + private Long spuId; + /** + * 商品 SKU 编号 + * + * 关联 ProductSkuDO 的 id 编号 + */ + private Long skuId; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 销售价格,单位:分 + * + * 冗余 ProductSkuDO 的 price 字段 + */ + private Integer originalPrice; + /** + * 优惠价格,单位:分 + */ + private Integer promotionPrice; + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java new file mode 100644 index 0000000..e63f40f --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/reward/RewardActivityDO.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.promotion.dal.dataobject.reward; + +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionActivityStatusEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; +import java.util.List; + +/** + * 满减送活动 DO + * + * @author 芋道源码 + */ +@TableName(value = "promotion_reward_activity", autoResultMap = true) +@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +public class RewardActivityDO extends BaseDO { + + /** + * 活动编号,主键自增 + */ + @TableId + private Long id; + /** + * 活动标题 + */ + private String name; + /** + * 状态 + * + * 枚举 {@link PromotionActivityStatusEnum} + */ + private Integer status; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date endTime; + /** + * 备注 + */ + private String remark; + /** + * 条件类型 + * + * 枚举 {@link PromotionConditionTypeEnum} + */ + private Integer conditionType; + /** + * 商品范围 + * + * 枚举 {@link PromotionProductScopeEnum} + */ + private Integer productScope; + /** + * 商品 SPU 编号的数组 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List spuIds; + /** + * 优惠规则的数组 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private List rules; + + /** + * 优惠规则 + */ + @Data + public static class Rule { + + /** + * 优惠门槛 + * + * 1. 满 N 元,单位:分 + * 2. 满 N 件 + */ + private Integer limit; + /** + * 优惠价格,单位:分 + */ + private Integer discountPrice; + /** + * 是否包邮 + */ + private Boolean freeDelivery; + /** + * 赠送的积分 + */ + private Integer point; + /** + * 赠送的优惠劵编号的数组 + */ + private List couponIds; + /** + * 赠送的优惠卷数量的数组 + */ + private List couponCounts; + + } + + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java new file mode 100644 index 0000000..d983753 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/banner/BannerMapper.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.dal.mysql.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import org.apache.ibatis.annotations.Mapper; + +/** + * Banner Mapper + * + * @author xia + */ +@Mapper +public interface BannerMapper extends BaseMapperX { + + default PageResult selectPage(BannerPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .likeIfPresent(BannerDO::getTitle, reqVO.getTitle()) + .eqIfPresent(BannerDO::getStatus, reqVO.getStatus()) + .betweenIfPresent(BannerDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(BannerDO::getSort)); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java new file mode 100644 index 0000000..3588ffd --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/discount/package-info.java @@ -0,0 +1,4 @@ +/** + * TODO 占位 + */ +package cn.iocoder.yudao.module.promotion.dal.mysql.discount; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java new file mode 100644 index 0000000..c022c62 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/package-info.java @@ -0,0 +1,8 @@ +/** + * promotion 模块,我们放营销业务。 + * 例如说:营销活动、banner、优惠券等等 + * + * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突 + * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分 + */ +package cn.iocoder.yudao.module.promotion; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java new file mode 100644 index 0000000..d541211 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerService.java @@ -0,0 +1,63 @@ +package cn.iocoder.yudao.module.promotion.service.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; + +import javax.validation.Valid; +import java.util.List; + +/** + * 首页 Banner Service 接口 + * + * @author xia + */ +public interface BannerService { + + /** + * 创建 Banner + * + * @param createReqVO 创建信息 + * @return 编号 + */ + Long createBanner(@Valid BannerCreateReqVO createReqVO); + + /** + * 更新 Banner + * + * @param updateReqVO 更新信息 + */ + void updateBanner(@Valid BannerUpdateReqVO updateReqVO); + + /** + * 删除 Banner + * + * @param id 编号 + */ + void deleteBanner(Long id); + + /** + * 获得 Banner + * + * @param id 编号 + * @return Banner + */ + BannerDO getBanner(Long id); + + /** + * 获得所有 Banner列表 + * @return Banner列表 + */ + List getBannerList(); + + /** + * 获得 Banner 分页 + * + * @param pageReqVO 分页查询 + * @return Banner分页 + */ + PageResult getBannerPage(BannerPageReqVO pageReqVO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java new file mode 100644 index 0000000..013ae89 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/banner/BannerServiceImpl.java @@ -0,0 +1,78 @@ +package cn.iocoder.yudao.module.promotion.service.banner; + +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerCreateReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerPageReqVO; +import cn.iocoder.yudao.module.promotion.controller.admin.banner.vo.BannerUpdateReqVO; +import cn.iocoder.yudao.module.promotion.convert.banner.BannerConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.banner.BannerDO; +import cn.iocoder.yudao.module.promotion.dal.mysql.banner.BannerMapper; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.List; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BANNER_NOT_EXISTS; + +/** + * 首页 banner 实现类 + * + * @author xia + */ +@Service +@Validated +public class BannerServiceImpl implements BannerService { + + @Resource + private BannerMapper bannerMapper; + + @Override + public Long createBanner(BannerCreateReqVO createReqVO) { + // 插入 + BannerDO banner = BannerConvert.INSTANCE.convert(createReqVO); + bannerMapper.insert(banner); + // 返回 + return banner.getId(); + } + + @Override + public void updateBanner(BannerUpdateReqVO updateReqVO) { + // 校验存在 + this.validateBannerExists(updateReqVO.getId()); + // 更新 + BannerDO updateObj = BannerConvert.INSTANCE.convert(updateReqVO); + bannerMapper.updateById(updateObj); + } + + @Override + public void deleteBanner(Long id) { + // 校验存在 + this.validateBannerExists(id); + // 删除 + bannerMapper.deleteById(id); + } + + private void validateBannerExists(Long id) { + if (bannerMapper.selectById(id) == null) { + throw exception(BANNER_NOT_EXISTS); + } + } + + @Override + public BannerDO getBanner(Long id) { + return bannerMapper.selectById(id); + } + + @Override + public List getBannerList() { + return bannerMapper.selectList(); + } + + @Override + public PageResult getBannerPage(BannerPageReqVO pageReqVO) { + return bannerMapper.selectPage(pageReqVO); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java new file mode 100644 index 0000000..7fdac90 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponService.java @@ -0,0 +1,24 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; + +/** + * 优惠劵 Service 接口 + * + * @author 芋道源码 + */ +public interface CouponService { + + /** + * 校验优惠劵,包括状态、有限期 + * + * 1. 如果校验通过,则返回优惠劵信息 + * 2. 如果校验不通过,则直接抛出业务异常 + * + * @param id 优惠劵编号 + * @param userId 用户编号 + * @return 优惠劵信息 + */ + CouponDO validCoupon(Long id, Long userId); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java new file mode 100644 index 0000000..067bd84 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.service.coupon; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +/** + * 优惠劵 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class CouponServiceImpl implements CouponService { + + // TODO 芋艿:待实现 + @Override + public CouponDO validCoupon(Long id, Long userId) { + return null; + } +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java new file mode 100644 index 0000000..9af2389 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountService.java @@ -0,0 +1,25 @@ +package cn.iocoder.yudao.module.promotion.service.discount; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; + +import java.util.Collection; +import java.util.Map; + +/** + * 限时折扣 Service 接口 + * + * @author 芋道源码 + */ +public interface DiscountService { + + /** + * 基于指定 SKU 编号数组,获得匹配的限时折扣商品 + * + * 注意,匹配的条件,仅仅是日期符合,并且处于开启状态 + * + * @param skuIds SKU 编号数组 + * @return 匹配的限时折扣商品 + */ + Map getMatchDiscountProducts(Collection skuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java new file mode 100644 index 0000000..5b241e0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/discount/DiscountServiceImpl.java @@ -0,0 +1,29 @@ +package cn.iocoder.yudao.module.promotion.service.discount; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * 限时折扣 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class DiscountServiceImpl implements DiscountService { + + // TODO 芋艿:待实现 + @Override + public Map getMatchDiscountProducts(Collection skuIds) { + Map products = new HashMap<>(); + products.put(1L, new DiscountProductDO().setPromotionPrice(100)); + products.put(2L, new DiscountProductDO().setPromotionPrice(50)); + return products; + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java new file mode 100644 index 0000000..c7e518d --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceService.java @@ -0,0 +1,21 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; + +/** + * 价格计算 Service 接口 + * + * @author 芋道源码 + */ +public interface PriceService { + + /** + * 计算商品的价格 + * + * @param calculateReqDTO 价格请求 + * @return 价格相应 + */ + PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java new file mode 100644 index 0000000..8a57fa0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceImpl.java @@ -0,0 +1,487 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.convert.price.PriceConvert; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountService; +import cn.iocoder.yudao.module.promotion.service.reward.RewardService; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import com.google.common.base.Suppliers; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.getSumValue; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_MIN_PRICE; +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COUPON_NO_MATCH_SPU; +import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; +import static java.util.Collections.singletonList; + +/** + * 价格计算 Service 实现类 + * + * 优惠计算顺序:min(限时折扣, 会员折扣) > 满减送 > 优惠券。 + * 参考文档: + * 1. 有赞文档:限时折扣、满减送、优惠券哪个优先计算? + * + * TODO 芋艿:进一步完善 + * 1. 限时折扣:指定金额、减免金额、折扣 + * 2. 满减送:循环、折扣 + * 3. 优惠劵:待定 + * + * @author 芋道源码 + */ +@Service +@Validated +public class PriceServiceImpl implements PriceService { + + @Resource + private DiscountService discountService; + @Resource + private RewardService rewardService; + @Resource + private CouponService couponService; + + @Resource + private ProductSkuApi productSkuApi; + + @Override + public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) { + // 获得商品 SKU 数组 + List skuList = checkSkus(calculateReqDTO); + // 初始化 PriceCalculateRespDTO 对象 + PriceCalculateRespDTO priceCalculate = PriceConvert.INSTANCE.convert(calculateReqDTO, skuList); + + // 计算商品级别的价格 + calculatePriceForSkuLevel(calculateReqDTO.getUserId(), priceCalculate); + // 计算订单级别的价格 + calculatePriceForOrderLevel(calculateReqDTO.getUserId(), priceCalculate); + // 计算优惠劵级别的价格 + calculatePriceForCouponLevel(calculateReqDTO.getUserId(), calculateReqDTO.getCouponId(), priceCalculate); + // 计算【优惠劵】促销 TODO 待实现 + return priceCalculate; + } + + private List checkSkus(PriceCalculateReqDTO calculateReqDTO) { + // 获得商品 SKU 数组 + Map skuIdCountMap = CollectionUtils.convertMap(calculateReqDTO.getItems(), + PriceCalculateReqDTO.Item::getSkuId, PriceCalculateReqDTO.Item::getCount); + List skus = productSkuApi.getSkuList(skuIdCountMap.keySet()); + + // 校验商品 SKU + skus.forEach(sku -> { + Integer count = skuIdCountMap.get(sku.getId()); + if (count == null) { + throw exception(SKU_NOT_EXISTS); + } + // 不校验库存不足,避免购物车场景,商品无货的情况 + }); + return skus; + } + + // ========== 计算商品级别的价格 ========== + + /** + * 计算商品级别的价格,例如说: + * 1. 会员折扣 + * 2. 限时折扣 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountActivityDO} + * + * 其中,会员折扣、限时折扣取最低价 + * + * @param userId 用户编号 + * @param priceCalculate 价格计算的结果 + */ + private void calculatePriceForSkuLevel(Long userId, PriceCalculateRespDTO priceCalculate) { + // 获取 SKU 级别的所有优惠信息 + Supplier memberDiscountSupplier = getMemberDiscountSupplier(userId); + Map discountProducts = discountService.getMatchDiscountProducts( + convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSkuId)); + + // 处理每个 SKU 的优惠 + priceCalculate.getOrder().getItems().forEach(orderItem -> { + // 获取该 SKU 的优惠信息 + Double memberDiscount = memberDiscountSupplier.get(); + DiscountProductDO discountProduct = discountProducts.get(orderItem.getSkuId()); + if (discountProduct != null // 假设优惠价格更贵,则认为没优惠 + && discountProduct.getPromotionPrice() >= orderItem.getOriginalUnitPrice()) { + discountProduct = null; + } + if (memberDiscount == null && discountProduct == null) { + return; + } + // 计算价格,判断选择哪个折扣 + Integer memberPrice = memberDiscount != null ? (int) (orderItem.getPayPrice() * memberDiscount / 100) : null; + Integer promotionPrice = discountProduct != null ? discountProduct.getPromotionPrice() * orderItem.getCount() : null; + if (memberPrice == null) { + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); + } else if (promotionPrice == null) { + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); + } else if (memberPrice < promotionPrice) { + calculatePriceByDiscountActivity(priceCalculate, orderItem, discountProduct, promotionPrice); + } else { + calculatePriceByMemberDiscount(priceCalculate, orderItem, memberPrice); + } + }); + } + + private void calculatePriceByMemberDiscount(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + Integer memberPrice) { + // 记录优惠明细 + addPromotion(priceCalculate, orderItem, null, PromotionTypeEnum.MEMBER.getName(), + PromotionTypeEnum.MEMBER.getType(), PromotionLevelEnum.SKU.getLevel(), memberPrice, + true, StrUtil.format("会员折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - memberPrice))); + // 修改 SKU 的优惠 + modifyOrderItemPayPrice(orderItem, memberPrice, priceCalculate); + } + + private void calculatePriceByDiscountActivity(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + DiscountProductDO discountProduct, Integer promotionPrice) { + // 记录优惠明细 + addPromotion(priceCalculate, orderItem, discountProduct.getActivityId(), discountProduct.getActivityName(), + PromotionTypeEnum.DISCOUNT_ACTIVITY.getType(), PromotionLevelEnum.SKU.getLevel(), promotionPrice, + true, StrUtil.format("限时折扣:省 {} 元", formatPrice(orderItem.getPayPrice() - promotionPrice))); + // 修改 SKU 的优惠 + modifyOrderItemPayPrice(orderItem, promotionPrice, priceCalculate); + } + + // TODO 芋艿:提前实现 + private Supplier getMemberDiscountSupplier(Long userId) { + return Suppliers.memoize(() -> { + if (userId == 1) { + return 90d; + } + if (userId == 2) { + return 80d; + } + return null; // 无优惠 + }); + } + + // ========== 计算商品级别的价格 ========== + + /** + * 计算订单级别的价格,例如说: + * 1. 满减送 {@link cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO} + * + * @param userId 用户编号 + * @param priceCalculate 价格计算的结果 + */ + @SuppressWarnings("unused") + private void calculatePriceForOrderLevel(Long userId, PriceCalculateRespDTO priceCalculate) { + // 获取 SKU 级别的所有优惠信息 + Set spuIds = convertSet(priceCalculate.getOrder().getItems(), PriceCalculateRespDTO.OrderItem::getSpuId); + Map> rewardActivities = rewardService.getMatchRewardActivities(spuIds); + + // 处理满减送活动 + if (CollUtil.isNotEmpty(rewardActivities)) { + rewardActivities.forEach((rewardActivity, activitySpuIds) -> { + List orderItems = CollectionUtils.filterList(priceCalculate.getOrder().getItems(), + orderItem -> CollUtil.contains(activitySpuIds, orderItem.getSpuId())); + calculatePriceByRewardActivity(priceCalculate, orderItems, rewardActivity); + }); + } + } + + private void calculatePriceByRewardActivity(PriceCalculateRespDTO priceCalculate, List orderItems, + RewardActivityDO rewardActivity) { + // 获得最大匹配的满减送活动的规格 + RewardActivityDO.Rule rule = getLastMatchRewardActivityRule(rewardActivity, orderItems); + if (rule == null) { + // 获取不到的情况下,记录不满足的优惠明细 + addNotMeetPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), + PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), + getRewardActivityNotMeetTip(rewardActivity)); + return; + } + + // 分摊金额 + // TODO 芋艿:limit 不能超过最大价格 + List discountPartPrices = dividePrice(orderItems, rule.getDiscountPrice()); + // 记录优惠明细 + addPromotion(priceCalculate, orderItems, rewardActivity.getId(), rewardActivity.getName(), + PromotionTypeEnum.REWARD_ACTIVITY.getType(), PromotionLevelEnum.ORDER.getLevel(), discountPartPrices, + true, StrUtil.format("满减送:省 {} 元", formatPrice(rule.getDiscountPrice()))); + // 修改 SKU 的分摊 + for (int i = 0; i < orderItems.size(); i++) { + modifyOrderItemOrderPartPriceFromDiscountPrice(orderItems.get(i), discountPartPrices.get(i), priceCalculate); + } + } + + /** + * 获得最大匹配的满减送活动的规格 + * + * @param rewardActivity 满减送活动 + * @param orderItems 商品项 + * @return 匹配的活动规格 + */ + private RewardActivityDO.Rule getLastMatchRewardActivityRule(RewardActivityDO rewardActivity, + List orderItems) { + Integer count = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getCount, Integer::sum); + // price 的计算逻辑,使用 orderDividePrice 的原因,主要考虑分摊后,这个才是该 SKU 当前真实的支付总价 + Integer price = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert count != null && price != null; + for (int i = rewardActivity.getRules().size() - 1; i >= 0; i--) { + RewardActivityDO.Rule rule = rewardActivity.getRules().get(i); + if (PromotionConditionTypeEnum.PRICE.getType().equals(rewardActivity.getConditionType()) + && price >= rule.getLimit()) { + return rule; + } + if (PromotionConditionTypeEnum.COUNT.getType().equals(rewardActivity.getConditionType()) + && count >= rule.getLimit()) { + return rule; + } + } + return null; + } + + /** + * 获得满减送活动部匹配时的提示 + * + * @param rewardActivity 满减送活动 + * @return 提示 + */ + private String getRewardActivityNotMeetTip(RewardActivityDO rewardActivity) { + return "TODO"; // TODO 芋艿:后面再想想 + } + + // ========== 计算优惠劵级别的价格 ========== + + private void calculatePriceForCouponLevel(Long userId, Long couponId, PriceCalculateRespDTO priceCalculate) { + // 校验优惠劵 + if (couponId == null) { + return; + } + CouponDO coupon = couponService.validCoupon(couponId, userId); + + // 获得匹配的商品 SKU 数组 + List orderItems = getMatchCouponOrderItems(priceCalculate, coupon); + if (CollUtil.isEmpty(orderItems)) { + throw exception(COUPON_NO_MATCH_SPU); + } + + // 计算是否满足优惠劵的使用金额 + Integer originPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert originPrice != null; + if (originPrice < coupon.getPriceAvailable()) { + throw exception(COUPON_NO_MATCH_MIN_PRICE); + } + + // 计算可以优惠的金额 + priceCalculate.getOrder().setCouponId(couponId); + Integer couponPrice = getCouponPrice(coupon, originPrice); + // 分摊金额 + // TODO 芋艿:limit 不能超过最大价格 + List couponPartPrices = dividePrice(orderItems, couponPrice); + // 记录优惠明细 + addPromotion(priceCalculate, orderItems, coupon.getId(), coupon.getTitle(), + PromotionTypeEnum.COUPON.getType(), PromotionLevelEnum.COUPON.getLevel(), couponPartPrices, + true, StrUtil.format("优惠劵:省 {} 元", formatPrice(couponPrice))); + // 修改 SKU 的分摊 + for (int i = 0; i < orderItems.size(); i++) { + modifyOrderItemOrderPartPriceFromCouponPrice(orderItems.get(i), couponPartPrices.get(i), priceCalculate); + } + } + + private List getMatchCouponOrderItems(PriceCalculateRespDTO priceCalculate, + CouponDO coupon) { + if (PromotionProductScopeEnum.ALL.getScope().equals(coupon.getProductScope())) { + return priceCalculate.getOrder().getItems(); + } + return CollectionUtils.filterList(priceCalculate.getOrder().getItems(), + orderItem -> coupon.getSpuIds().contains(orderItem.getSpuId())); + } + + private Integer getCouponPrice(CouponDO coupon, Integer originPrice) { + // TODO 芋艿 getPreferentialType 的枚举判断 + if (coupon.getPreferentialType().equals(1)) { // 减价 + return coupon.getPriceOff(); + } else if (coupon.getPreferentialType().equals(2)) { // 打折 + Integer couponPrice = originPrice * coupon.getPercentOff() / 100; + return coupon.getDiscountPriceLimit() == null ? couponPrice + : Math.min(couponPrice, coupon.getDiscountPriceLimit()); // 优惠上限 + } + throw new IllegalArgumentException(String.format("优惠劵(%s) 的优惠类型不正确", coupon.toString())); + } + + // ========== 其它相对通用的方法 ========== + + /** + * 添加单个 OrderItem 的营销明细 + * + * @param priceCalculate 价格计算结果 + * @param orderItem 单个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param type 营销类型 + * @param level 营销级别 + * @param newPayPrice 新的单实付金额(总) + * @param meet 是否满足优惠条件 + * @param meetTip 满足条件的提示 + */ + private void addPromotion(PriceCalculateRespDTO priceCalculate, PriceCalculateRespDTO.OrderItem orderItem, + Long id, String name, Integer type, Integer level, + Integer newPayPrice, Boolean meet, String meetTip) { + // 创建营销明细 Item + // TODO 芋艿:orderItem.getPayPrice() 要不要改成 orderDividePrice;同时,newPayPrice 要不要改成直接传递 discountPrice + PriceCalculateRespDTO.PromotionItem promotionItem = new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(orderItem.getPayPrice() - newPayPrice); + // 创建营销明细 + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(promotionItem.getOriginalPrice()).setDiscountPrice(promotionItem.getDiscountPrice()) + .setItems(singletonList(promotionItem)).setMeet(meet).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + /** + * 添加多个 OrderItem 的营销明细 + * + * @param priceCalculate 价格计算结果 + * @param orderItems 多个订单商品 SKU + * @param id 营销编号 + * @param name 营销名字 + * @param type 营销类型 + * @param level 营销级别 + * @param discountPrices 多个订单商品 SKU 的优惠价格(总),和 orderItems 一一对应 + * @param meet 是否满足优惠条件 + * @param meetTip 满足条件的提示 + */ + private void addPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, + Long id, String name, Integer type, Integer level, + List discountPrices, Boolean meet, String meetTip) { + // 创建营销明细 Item + List promotionItems = new ArrayList<>(discountPrices.size()); + for (int i = 0; i < orderItems.size(); i++) { + PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); + promotionItems.add(new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getPayPrice()).setDiscountPrice(discountPrices.get(i))); + } + // 创建营销明细 + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum)) + .setDiscountPrice(getSumValue(discountPrices, value -> value, Integer::sum)) + .setItems(promotionItems).setMeet(meet).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + private void addNotMeetPromotion(PriceCalculateRespDTO priceCalculate, List orderItems, + Long id, String name, Integer type, Integer level, String meetTip) { + // 创建营销明细 Item + List promotionItems = CollectionUtils.convertList(orderItems, + orderItem -> new PriceCalculateRespDTO.PromotionItem().setSkuId(orderItem.getSkuId()) + .setOriginalPrice(orderItem.getOrderDividePrice()).setDiscountPrice(0)); + // 创建营销明细 + Integer originalPrice = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + PriceCalculateRespDTO.Promotion promotion = new PriceCalculateRespDTO.Promotion() + .setId(id).setName(name).setType(type).setLevel(level) + .setOriginalPrice(originalPrice).setDiscountPrice(0) + .setItems(promotionItems).setMeet(false).setMeetTip(meetTip); + priceCalculate.getPromotions().add(promotion); + } + + /** + * 修改 OrderItem 的 payPrice 价格,同时会修改 Order 的 payPrice 价格 + * + * @param orderItem 订单商品 SKU + * @param newPayPrice 新的 payPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemPayPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer newPayPrice, + PriceCalculateRespDTO priceCalculate) { + int diffPayPrice = orderItem.getPayPrice() - newPayPrice; + // 设置 OrderItem 价格相关字段 + orderItem.setDiscountPrice(orderItem.getDiscountPrice() + diffPayPrice); + orderItem.setPayPrice(newPayPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + priceCalculate.getOrder().setPayPrice(priceCalculate.getOrder().getPayPrice() - diffPayPrice); + } + + /** + * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 discountPrice 价格 + * + * 本质:分摊 Order 的 discountPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 + * + * @param orderItem 订单商品 SKU + * @param addOrderPartPrice 新增的 discountPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemOrderPartPriceFromDiscountPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, + PriceCalculateRespDTO priceCalculate) { + // 设置 OrderItem 价格相关字段 + orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + order.setDiscountPrice(order.getDiscountPrice() + addOrderPartPrice); + order.setPayPrice(order.getPayPrice() - addOrderPartPrice); + } + + /** + * 修改 OrderItem 的 orderPartPrice 价格,同时会修改 Order 的 couponPrice 价格 + * + * 本质:分摊 Order 的 couponPrice 价格,到对应的 OrderItem 的 orderPartPrice 价格中 + * + * @param orderItem 订单商品 SKU + * @param addOrderPartPrice 新增的 couponPrice 价格 + * @param priceCalculate 价格计算结果 + */ + private void modifyOrderItemOrderPartPriceFromCouponPrice(PriceCalculateRespDTO.OrderItem orderItem, Integer addOrderPartPrice, + PriceCalculateRespDTO priceCalculate) { + // 设置 OrderItem 价格相关字段 + orderItem.setOrderPartPrice(orderItem.getOrderPartPrice() + addOrderPartPrice); + orderItem.setOrderDividePrice(orderItem.getPayPrice() - orderItem.getOrderPartPrice()); + // 设置 Order 相关相关字段 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + order.setCouponPrice(order.getCouponPrice() + addOrderPartPrice); + order.setPayPrice(order.getPayPrice() - addOrderPartPrice); + } + + private List dividePrice(List orderItems, Integer price) { + List prices = new ArrayList<>(orderItems.size()); + Integer total = getSumValue(orderItems, PriceCalculateRespDTO.OrderItem::getOrderDividePrice, Integer::sum); + assert total != null; + int remainPrice = price; + // 遍历每一个,进行分摊 + for (int i = 0; i < orderItems.size(); i++) { + PriceCalculateRespDTO.OrderItem orderItem = orderItems.get(i); + int partPrice; + if (i < orderItems.size() - 1) { // 减一的原因,是因为拆分时,如果按照比例,可能会出现.所以最后一个,使用反减 + partPrice = (int) (price * (1.0D * orderItem.getOrderDividePrice() / total)); + remainPrice -= partPrice; + } else { + partPrice = remainPrice; + } + Assert.isTrue(partPrice > 0, "分摊金额必须大于 0"); + prices.add(partPrice); + } + return prices; + } + + private String formatPrice(Integer price) { + return String.format("%.2f", price / 100d); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java new file mode 100644 index 0000000..ef91237 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardService.java @@ -0,0 +1,23 @@ +package cn.iocoder.yudao.module.promotion.service.reward; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; + +import java.util.Map; +import java.util.Set; + +/** + * 满减送 Service 接口 + * + * @author 芋道源码 + */ +public interface RewardService { + + /** + * 基于指定的 SPU 编号数组,获得它们匹配的满减送活动 + * + * @param spuIds SPU 编号数组 + * @return 满减送活动,与对应的 SPU 编号的映射。即,value 就是 SPU 编号的集合 + */ + Map> getMatchRewardActivities(Set spuIds); + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java new file mode 100644 index 0000000..af715c4 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/reward/RewardServiceImpl.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.promotion.service.reward; + +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import java.util.Collections; +import java.util.Map; +import java.util.Set; + +/** + * 满减送 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class RewardServiceImpl implements RewardService { + + // TODO 芋艿:待实现 + @Override + public Map> getMatchRewardActivities(Set spuIds) { + return Collections.emptyMap(); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java new file mode 100644 index 0000000..c5bb540 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/java/cn/iocoder/yudao/module/promotion/service/price/PriceServiceTest.java @@ -0,0 +1,446 @@ +package cn.iocoder.yudao.module.promotion.service.price; + +import cn.hutool.core.map.MapUtil; +import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.discount.DiscountProductDO; +import cn.iocoder.yudao.module.promotion.dal.dataobject.reward.RewardActivityDO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionConditionTypeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionProductScopeEnum; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum; +import cn.iocoder.yudao.module.promotion.service.coupon.CouponService; +import cn.iocoder.yudao.module.promotion.service.discount.DiscountService; +import cn.iocoder.yudao.module.promotion.service.reward.RewardService; +import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId; +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +/** + * {@link PriceServiceImpl} 的单元测试 + * + * @author 芋道源码 + */ +public class PriceServiceTest extends BaseMockitoUnitTest { + + @InjectMocks + private PriceServiceImpl priceService; + + @Mock + private DiscountService discountService; + @Mock + private RewardService rewardService; + @Mock + private CouponService couponService; + @Mock + private ProductSkuApi productSkuApi; + + @Test + public void testCalculatePrice_memberDiscount() { + // 准备参数 + // TODO 芋艿:userId = 1,实现 9 折;后续改成 mock + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(1L) + .setItems(singletonList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); + when(productSkuApi.getSkuList(eq(asSet(10L)))).thenReturn(singletonList(productSku)); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 200); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 180); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 1); + PriceCalculateRespDTO.OrderItem orderItem = order.getItems().get(0); + assertEquals(orderItem.getSkuId(), 10L); + assertEquals(orderItem.getCount(), 2); + assertEquals(orderItem.getOriginalPrice(), 200); + assertEquals(orderItem.getOriginalUnitPrice(), 100); + assertEquals(orderItem.getDiscountPrice(), 20); + assertEquals(orderItem.getPayPrice(), 180); + assertEquals(orderItem.getOrderPartPrice(), 0); + assertEquals(orderItem.getOrderDividePrice(), 180); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion = priceCalculate.getPromotions().get(0); + assertNull(promotion.getId()); + assertEquals(promotion.getName(), "会员折扣"); + assertEquals(promotion.getType(), PromotionTypeEnum.MEMBER.getType()); + assertEquals(promotion.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion.getOriginalPrice(), 200); + assertEquals(promotion.getDiscountPrice(), 20); + assertTrue(promotion.getMeet()); + assertEquals(promotion.getMeetTip(), "会员折扣:省 0.20 元"); + PriceCalculateRespDTO.PromotionItem promotionItem = promotion.getItems().get(0); + assertEquals(promotion.getItems().size(), 1); + assertEquals(promotionItem.getSkuId(), 10L); + assertEquals(promotionItem.getOriginalPrice(), 200); + assertEquals(promotionItem.getDiscountPrice(), 20); + } + + @Test + public void testCalculatePrice_discountActivity() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); + // mock 方法(限时折扣 DiscountActivity 信息) + DiscountProductDO discountProduct01 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(1000L).setActivityName("活动 1000 号") + .setSkuId(10L).setPromotionPrice(80)); + DiscountProductDO discountProduct02 = randomPojo(DiscountProductDO.class, o -> o.setActivityId(2000L).setActivityName("活动 2000 号") + .setSkuId(20L).setPromotionPrice(40)); + when(discountService.getMatchDiscountProducts(eq(asSet(10L, 20L)))).thenReturn( + MapUtil.builder(10L, discountProduct01).put(20L, discountProduct02).map()); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 350); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 280); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 2); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 40); + assertEquals(orderItem01.getPayPrice(), 160); + assertEquals(orderItem01.getOrderPartPrice(), 0); + assertEquals(orderItem01.getOrderDividePrice(), 160); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 30); + assertEquals(orderItem02.getPayPrice(), 120); + assertEquals(orderItem02.getOrderPartPrice(), 0); + assertEquals(orderItem02.getOrderDividePrice(), 120); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 2); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 200); + assertEquals(promotion01.getDiscountPrice(), 40); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "限时折扣:省 0.40 元"); + PriceCalculateRespDTO.PromotionItem promotionItem01 = promotion01.getItems().get(0); + assertEquals(promotion01.getItems().size(), 1); + assertEquals(promotionItem01.getSkuId(), 10L); + assertEquals(promotionItem01.getOriginalPrice(), 200); + assertEquals(promotionItem01.getDiscountPrice(), 40); + PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); + assertEquals(promotion02.getId(), 2000L); + assertEquals(promotion02.getName(), "活动 2000 号"); + assertEquals(promotion02.getType(), PromotionTypeEnum.DISCOUNT_ACTIVITY.getType()); + assertEquals(promotion02.getLevel(), PromotionLevelEnum.SKU.getLevel()); + assertEquals(promotion02.getOriginalPrice(), 150); + assertEquals(promotion02.getDiscountPrice(), 30); + assertTrue(promotion02.getMeet()); + assertEquals(promotion02.getMeetTip(), "限时折扣:省 0.30 元"); + PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); + assertEquals(promotion02.getItems().size(), 1); + assertEquals(promotionItem02.getSkuId(), 20L); + assertEquals(promotionItem02.getOriginalPrice(), 150); + assertEquals(promotionItem02.getDiscountPrice(), 30); + } + + /** + * 测试满减送活动,匹配的情况 + */ + @Test + public void testCalculatePrice_rewardActivity() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), + new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); + // mock 方法(限时折扣 DiscountActivity 信息) + RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityDO.Rule().setLimit(200).setDiscountPrice(70)))); + RewardActivityDO rewardActivity02 = randomPojo(RewardActivityDO.class, o -> o.setId(2000L).setName("活动 2000 号") + .setSpuIds(singletonList(30L)).setConditionType(PromotionConditionTypeEnum.COUNT.getType()) + .setRules(asList(new RewardActivityDO.Rule().setLimit(1).setDiscountPrice(10), + new RewardActivityDO.Rule().setLimit(2).setDiscountPrice(60), // 最大可满足,因为是 4 个 + new RewardActivityDO.Rule().setLimit(10).setDiscountPrice(100)))); + Map> matchRewardActivities = new LinkedHashMap<>(); + matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); + matchRewardActivities.put(rewardActivity02, asSet(3L)); + when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L, 3L)))).thenReturn(matchRewardActivities); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 470); + assertEquals(order.getDiscountPrice(), 130); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 340); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 3); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 40); + assertEquals(orderItem01.getOrderDividePrice(), 160); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 30); + assertEquals(orderItem02.getOrderDividePrice(), 120); + PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getOriginalPrice(), 120); + assertEquals(orderItem03.getOriginalUnitPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 120); + assertEquals(orderItem03.getOrderPartPrice(), 60); + assertEquals(orderItem03.getOrderDividePrice(), 60); + // 断言 Promotion 部分(第一个) + assertEquals(priceCalculate.getPromotions().size(), 2); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "满减送:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + // 断言 Promotion 部分(第二个) + PriceCalculateRespDTO.Promotion promotion02 = priceCalculate.getPromotions().get(1); + assertEquals(promotion02.getId(), 2000L); + assertEquals(promotion02.getName(), "活动 2000 号"); + assertEquals(promotion02.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion02.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion02.getOriginalPrice(), 120); + assertEquals(promotion02.getDiscountPrice(), 60); + assertTrue(promotion02.getMeet()); + assertEquals(promotion02.getMeetTip(), "满减送:省 0.60 元"); + PriceCalculateRespDTO.PromotionItem promotionItem02 = promotion02.getItems().get(0); + assertEquals(promotion02.getItems().size(), 1); + assertEquals(promotionItem02.getSkuId(), 30L); + assertEquals(promotionItem02.getOriginalPrice(), 120); + assertEquals(promotionItem02.getDiscountPrice(), 60); + } + + /** + * 测试满减送活动,不匹配的情况 + */ + @Test + public void testCalculatePrice_rewardActivityNotMeet() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3))); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L)))).thenReturn(asList(productSku01, productSku02)); + // mock 方法(限时折扣 DiscountActivity 信息) + RewardActivityDO rewardActivity01 = randomPojo(RewardActivityDO.class, o -> o.setId(1000L).setName("活动 1000 号") + .setSpuIds(asList(10L, 20L)).setConditionType(PromotionConditionTypeEnum.PRICE.getType()) + .setRules(singletonList(new RewardActivityDO.Rule().setLimit(351).setDiscountPrice(70)))); + Map> matchRewardActivities = new LinkedHashMap<>(); + matchRewardActivities.put(rewardActivity01, asSet(1L, 2L)); + when(rewardService.getMatchRewardActivities(eq(asSet(1L, 2L)))).thenReturn(matchRewardActivities); + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 350); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 350); + assertNull(order.getCouponId()); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 2); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 0); + assertEquals(orderItem01.getOrderDividePrice(), 200); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 0); + assertEquals(orderItem02.getOrderDividePrice(), 150); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1000L); + assertEquals(promotion01.getName(), "活动 1000 号"); + assertEquals(promotion01.getType(), PromotionTypeEnum.REWARD_ACTIVITY.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.ORDER.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 0); + assertFalse(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "TODO"); // TODO 芋艿:后面再想想 + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 0); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 0); + } + + @Test + public void testCalculatePrice_coupon() { + // 准备参数 + PriceCalculateReqDTO calculateReqDTO = new PriceCalculateReqDTO().setUserId(randomLongId()) + .setItems(asList(new PriceCalculateReqDTO.Item().setSkuId(10L).setCount(2), + new PriceCalculateReqDTO.Item().setSkuId(20L).setCount(3), + new PriceCalculateReqDTO.Item().setSkuId(30L).setCount(4))) + .setCouponId(1024L); + // mock 方法(商品 SKU 信息) + ProductSkuRespDTO productSku01 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(10L).setPrice(100).setSpuId(1L)); + ProductSkuRespDTO productSku02 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(20L).setPrice(50).setSpuId(2L)); + ProductSkuRespDTO productSku03 = randomPojo(ProductSkuRespDTO.class, o -> o.setId(30L).setPrice(30).setSpuId(3L)); + when(productSkuApi.getSkuList(eq(asSet(10L, 20L, 30L)))).thenReturn(asList(productSku01, productSku02, productSku03)); + // mock 方法(优惠劵 Coupon 信息) + CouponDO coupon = randomPojo(CouponDO.class, o -> o.setId(1024L).setTitle("程序员节") + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setSpuIds(asList(1L, 2L)) + .setPriceAvailable(350).setPreferentialType(2).setPercentOff(50).setDiscountPriceLimit(70)); + when(couponService.validCoupon(eq(1024L), eq(calculateReqDTO.getUserId()))).thenReturn(coupon); + + // 200 + 150; 350 + // + + // 调用 + PriceCalculateRespDTO priceCalculate = priceService.calculatePrice(calculateReqDTO); + // 断言 Order 部分 + PriceCalculateRespDTO.Order order = priceCalculate.getOrder(); + assertEquals(order.getOriginalPrice(), 470); + assertEquals(order.getDiscountPrice(), 0); + assertEquals(order.getPointPrice(), 0); + assertEquals(order.getDeliveryPrice(), 0); + assertEquals(order.getPayPrice(), 400); + assertEquals(order.getCouponId(), 1024L); + assertEquals(order.getCouponPrice(), 70); + // 断言 OrderItem 部分 + assertEquals(order.getItems().size(), 3); + PriceCalculateRespDTO.OrderItem orderItem01 = order.getItems().get(0); + assertEquals(orderItem01.getSkuId(), 10L); + assertEquals(orderItem01.getCount(), 2); + assertEquals(orderItem01.getOriginalPrice(), 200); + assertEquals(orderItem01.getOriginalUnitPrice(), 100); + assertEquals(orderItem01.getDiscountPrice(), 0); + assertEquals(orderItem01.getPayPrice(), 200); + assertEquals(orderItem01.getOrderPartPrice(), 40); + assertEquals(orderItem01.getOrderDividePrice(), 160); + PriceCalculateRespDTO.OrderItem orderItem02 = order.getItems().get(1); + assertEquals(orderItem02.getSkuId(), 20L); + assertEquals(orderItem02.getCount(), 3); + assertEquals(orderItem02.getOriginalPrice(), 150); + assertEquals(orderItem02.getOriginalUnitPrice(), 50); + assertEquals(orderItem02.getDiscountPrice(), 0); + assertEquals(orderItem02.getPayPrice(), 150); + assertEquals(orderItem02.getOrderPartPrice(), 30); + assertEquals(orderItem02.getOrderDividePrice(), 120); + PriceCalculateRespDTO.OrderItem orderItem03 = order.getItems().get(2); + assertEquals(orderItem03.getSkuId(), 30L); + assertEquals(orderItem03.getCount(), 4); + assertEquals(orderItem03.getOriginalPrice(), 120); + assertEquals(orderItem03.getOriginalUnitPrice(), 30); + assertEquals(orderItem03.getDiscountPrice(), 0); + assertEquals(orderItem03.getPayPrice(), 120); + assertEquals(orderItem03.getOrderPartPrice(), 0); + assertEquals(orderItem03.getOrderDividePrice(), 120); + // 断言 Promotion 部分 + assertEquals(priceCalculate.getPromotions().size(), 1); + PriceCalculateRespDTO.Promotion promotion01 = priceCalculate.getPromotions().get(0); + assertEquals(promotion01.getId(), 1024L); + assertEquals(promotion01.getName(), "程序员节"); + assertEquals(promotion01.getType(), PromotionTypeEnum.COUPON.getType()); + assertEquals(promotion01.getLevel(), PromotionLevelEnum.COUPON.getLevel()); + assertEquals(promotion01.getOriginalPrice(), 350); + assertEquals(promotion01.getDiscountPrice(), 70); + assertTrue(promotion01.getMeet()); + assertEquals(promotion01.getMeetTip(), "优惠劵:省 0.70 元"); + assertEquals(promotion01.getItems().size(), 2); + PriceCalculateRespDTO.PromotionItem promotionItem011 = promotion01.getItems().get(0); + assertEquals(promotionItem011.getSkuId(), 10L); + assertEquals(promotionItem011.getOriginalPrice(), 200); + assertEquals(promotionItem011.getDiscountPrice(), 40); + PriceCalculateRespDTO.PromotionItem promotionItem012 = promotion01.getItems().get(1); + assertEquals(promotionItem012.getSkuId(), 20L); + assertEquals(promotionItem012.getOriginalPrice(), 150); + assertEquals(promotionItem012.getDiscountPrice(), 30); + } + +} diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml new file mode 100644 index 0000000..60914d9 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/application-unit-test.yaml @@ -0,0 +1,49 @@ +spring: + main: + lazy-initialization: true # 开启懒加载,加快速度 + banner-mode: off # 单元测试,禁用 Banner + +--- #################### 数据库相关配置 #################### + +spring: + # 数据源配置项 + datasource: + name: ruoyi-vue-pro + url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写 + driver-class-name: org.h2.Driver + username: sa + password: + druid: + async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度 + initial-size: 1 # 单元测试,配置为 1,提升启动速度 + sql: + init: + schema-locations: classpath:/sql/create_tables.sql + + # Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优 + redis: + host: 127.0.0.1 # 地址 + port: 16379 # 端口(单元测试,使用 16379 端口) + database: 0 # 数据库索引 + +mybatis: + lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试 + +--- #################### 定时任务相关配置 #################### + +--- #################### 配置中心相关配置 #################### + +--- #################### 服务保障相关配置 #################### + +# Lock4j 配置项(单元测试,禁用 Lock4j) + +# Resilience4j 配置项 + +--- #################### 监控相关配置 #################### + +--- #################### 芋道相关配置 #################### + +# 芋道配置项,设置当前项目所有自定义的配置 +yudao: + info: + base-package: cn.iocoder.yudao.module diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml new file mode 100644 index 0000000..daf756b --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/logback.xml @@ -0,0 +1,4 @@ + + + + diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql new file mode 100644 index 0000000..abad7c0 --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/clean.sql @@ -0,0 +1 @@ +DELETE FROM "market_activity"; diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql new file mode 100644 index 0000000..3f3ce3c --- /dev/null +++ b/yudao-module-mall/yudao-module-promotion-biz/src/test/resources/sql/create_tables.sql @@ -0,0 +1,19 @@ +CREATE TABLE IF NOT EXISTS "market_activity" ( + "id" bigint(20) NOT NULL GENERATED BY DEFAULT AS IDENTITY, + "title" varchar(50) NOT NULL, + "activity_type" tinyint(4) NOT NULL, + "status" tinyint(4) NOT NULL, + "start_time" datetime NOT NULL, + "end_time" datetime NOT NULL, + "invalid_time" datetime, + "delete_time" datetime, + "time_limited_discount" varchar(2000), + "full_privilege" varchar(2000), + "creator" varchar(64) DEFAULT '', + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updater" varchar(64) DEFAULT '', + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + "deleted" bit NOT NULL DEFAULT FALSE, + "tenant_id" bigint(20) NOT NULL, + PRIMARY KEY ("id") + ) COMMENT '促销活动'; \ No newline at end of file diff --git a/yudao-module-mall/yudao-module-trade-biz/pom.xml b/yudao-module-mall/yudao-module-trade-biz/pom.xml index 4e95c09..30f108f 100644 --- a/yudao-module-mall/yudao-module-trade-biz/pom.xml +++ b/yudao-module-mall/yudao-module-trade-biz/pom.xml @@ -38,7 +38,7 @@ cn.iocoder.boot - yudao-module-market-api + yudao-module-promotion-api ${revision} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java index a3f6d47..eb696ae 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/cart/TradeCartConvert.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.trade.convert.cart; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; import cn.iocoder.yudao.module.trade.dal.dataobject.cart.TradeCartItemDO; import org.mapstruct.Mapper; 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 f72ab6b..9cdb583 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 @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.convert.order; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import org.mapstruct.Mapper; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java index ac2e74d..d65d633 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderItemConvert.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.convert.order; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java index da28b9e..dd8bda8 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/price/PriceConvert.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.convert.price; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderCreateReqVO; import org.mapstruct.Mapper; import org.mapstruct.Mapping; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java index fa58ac2..ae0301e 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/cart/TradeCartServiceImpl.java @@ -4,9 +4,9 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; -import cn.iocoder.yudao.module.market.api.price.PriceApi; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; -import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.enums.common.PromotionLevelEnum; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; import cn.iocoder.yudao.module.trade.controller.app.cart.vo.AppTradeCartDetailRespVO; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java index a694390..ecab7d9 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceImpl.java @@ -8,9 +8,9 @@ import cn.iocoder.yudao.framework.common.enums.TerminalEnum; import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.string.StrUtils; -import cn.iocoder.yudao.module.market.api.price.PriceApi; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; import cn.iocoder.yudao.module.pay.api.order.PayOrderInfoCreateReqDTO; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java b/yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java index 6b3281d..a2c1972 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/test/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderServiceTest.java @@ -2,8 +2,8 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; -import cn.iocoder.yudao.module.market.api.price.PriceApi; -import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO; +import cn.iocoder.yudao.module.promotion.api.price.PriceApi; +import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO; import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; diff --git a/yudao-server/pom.xml b/yudao-server/pom.xml index c7090aa..061e0d9 100644 --- a/yudao-server/pom.xml +++ b/yudao-server/pom.xml @@ -43,7 +43,7 @@ cn.iocoder.boot - yudao-module-market-biz + yudao-module-promotion-biz ${revision} -- libgit2 0.21.4