From b33cf81155cd8a5fdce1af75f3ceaf6a9c33b73f Mon Sep 17 00:00:00 2001 From: liujiang <569804566@qq.com> Date: Wed, 7 May 2025 16:14:30 +0800 Subject: [PATCH] =?UTF-8?q?master=EF=BC=9A=E6=A1=A3=E5=8F=A3=E8=B4=AD?= =?UTF-8?q?=E4=B9=B0=E6=8E=A8=E5=B9=BF=E4=BD=8D=E5=8A=9F=E8=83=BDv1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/SysProductCategoryController.java | 13 + ...roller.java => AdvertRoundController.java} | 40 +-- .../web/controller/xkt/StoreController.java | 9 + .../xkt/StoreProductController.java | 9 + .../vo/advertRound/AdRoundStoreCreateVO.java | 49 ++++ .../AdRoundStoreResVO.java} | 4 +- .../xkt/vo/store/StoreAppResVO.java | 33 +++ .../controller/xkt/website/IndexSearchVO.java | 2 + .../com/ruoyi/common/constant/Constants.java | 24 +- .../java/com/ruoyi/common}/enums/AdType.java | 2 +- .../controller/DailyTaskController.java | 9 + .../java/com/ruoyi/quartz/task/XktTask.java | 64 ++++- .../mapper/quartz/DailySaleCustomerMapper.xml | 4 +- .../mapper/quartz/DailySaleMapper.xml | 4 +- .../mapper/quartz/DailySaleProductMapper.xml | 4 +- .../mapper/quartz/WeekCateSaleMapper.xml | 4 +- .../service/ISysProductCategoryService.java | 8 + .../impl/SysProductCategoryServiceImpl.java | 14 + .../java/com/ruoyi/xkt/domain/Advert.java | 8 + .../com/ruoyi/xkt/domain/AdvertRound.java | 29 +- ...tRoundPlay.java => AdvertRoundRecord.java} | 42 ++- .../com/ruoyi/xkt}/domain/DailyProdTag.java | 2 +- .../java/com/ruoyi/xkt}/domain/DailySale.java | 2 +- .../ruoyi/xkt}/domain/DailySaleCustomer.java | 2 +- .../ruoyi/xkt}/domain/DailySaleProduct.java | 2 +- .../com/ruoyi/xkt}/domain/DailyStoreTag.java | 2 +- .../advertRound/AdRoundStoreCreateDTO.java | 17 +- .../AdRoundStoreResDTO.java} | 4 +- .../advertRoundPlay/AdPlayStoreCreateDTO.java | 33 --- .../xkt/dto/dailySale}/DailySaleCusDTO.java | 2 +- .../xkt/dto/dailySale}/DailySaleDTO.java | 2 +- .../xkt/dto/dailySale}/DailySaleProdDTO.java | 2 +- .../xkt/dto/dailySale}/WeekCateSaleDTO.java | 2 +- .../com/ruoyi/xkt/dto/es/ESProductDTO.java | 2 + .../ruoyi/xkt/dto/store/StoreAppResDTO.java | 35 +++ .../ruoyi/xkt/dto/website/IndexSearchDTO.java | 2 + .../ruoyi/xkt/mapper/AdvertRoundMapper.java | 12 + .../xkt/mapper/AdvertRoundPlayMapper.java | 16 -- .../xkt/mapper/AdvertRoundRecordMapper.java | 17 ++ .../ruoyi/xkt}/mapper/DailyProdTagMapper.java | 4 +- .../xkt}/mapper/DailySaleCustomerMapper.java | 6 +- .../ruoyi/xkt}/mapper/DailySaleMapper.java | 6 +- .../xkt}/mapper/DailySaleProductMapper.java | 8 +- .../xkt}/mapper/DailyStoreTagMapper.java | 4 +- .../ruoyi/xkt/mapper/StoreProductMapper.java | 6 + .../ruoyi/xkt}/mapper/WeekCateSaleMapper.java | 4 +- .../xkt/service/IAdvertRoundPlayService.java | 31 -- .../xkt/service/IAdvertRoundService.java | 47 +++ .../xkt/service/IStoreProductService.java | 6 + .../com/ruoyi/xkt/service/IStoreService.java | 7 + .../impl/AdvertRoundPlayServiceImpl.java | 83 ------ .../service/impl/AdvertRoundServiceImpl.java | 269 ++++++++++++++++++ .../xkt/service/impl/AdvertServiceImpl.java | 24 +- .../service/impl/IndexSearchServiceImpl.java | 46 ++- .../service/impl/StoreProductServiceImpl.java | 11 + .../xkt/service/impl/StoreServiceImpl.java | 36 ++- .../resources/mapper/AdvertRoundMapper.xml | 24 ++ .../resources/mapper/StoreProductMapper.xml | 10 + 58 files changed, 886 insertions(+), 277 deletions(-) rename ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/{AdvertRoundPlayController.java => AdvertRoundController.java} (53%) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreCreateVO.java rename ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/{advertRoundPlay/AdPlayStoreResVO.java => advertRound/AdRoundStoreResVO.java} (74%) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppResVO.java rename {xkt/src/main/java/com/ruoyi/xkt => ruoyi-common/src/main/java/com/ruoyi/common}/enums/AdType.java (99%) rename xkt/src/main/java/com/ruoyi/xkt/domain/{AdvertRoundPlay.java => AdvertRoundRecord.java} (61%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/domain/DailyProdTag.java (96%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/domain/DailySale.java (97%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/domain/DailySaleCustomer.java (97%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/domain/DailySaleProduct.java (97%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/domain/DailyStoreTag.java (96%) rename ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java => xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreCreateDTO.java (69%) rename xkt/src/main/java/com/ruoyi/xkt/dto/{advertRoundPlay/AdPlayStoreResDTO.java => advertRound/AdRoundStoreResDTO.java} (77%) delete mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreCreateDTO.java rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto => xkt/src/main/java/com/ruoyi/xkt/dto/dailySale}/DailySaleCusDTO.java (93%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto => xkt/src/main/java/com/ruoyi/xkt/dto/dailySale}/DailySaleDTO.java (94%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto => xkt/src/main/java/com/ruoyi/xkt/dto/dailySale}/DailySaleProdDTO.java (94%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto => xkt/src/main/java/com/ruoyi/xkt/dto/dailySale}/WeekCateSaleDTO.java (87%) create mode 100644 xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppResDTO.java delete mode 100644 xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundRecordMapper.java rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/DailyProdTagMapper.java (71%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/DailySaleCustomerMapper.java (70%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/DailySaleMapper.java (71%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/DailySaleProductMapper.java (58%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/DailyStoreTagMapper.java (71%) rename {ruoyi-quartz/src/main/java/com/ruoyi/quartz => xkt/src/main/java/com/ruoyi/xkt}/mapper/WeekCateSaleMapper.java (79%) delete mode 100644 xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundService.java delete mode 100644 xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundPlayServiceImpl.java create mode 100644 xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java create mode 100644 xkt/src/main/resources/mapper/AdvertRoundMapper.xml diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProductCategoryController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProductCategoryController.java index bfd45564d..0714eb57b 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProductCategoryController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProductCategoryController.java @@ -87,6 +87,17 @@ public class SysProductCategoryController extends XktBaseController { return R.ok(BeanUtil.copyToList(prodCateService.selectList(BeanUtil.toBean(listVO, ProdCateListDTO.class)), ProdCateListResVO.class)); } + /** + * 根据1级分类获取二级分类列表 + */ +// @PreAuthorize("@ss.hasPermi('system:category:list')") + @ApiOperation(value = "根据1级分类获取二级分类列表", httpMethod = "GET", response = R.class) + @GetMapping("/sub/{parCateId}") + public R> getSubList(@PathVariable Long parCateId) { + return R.ok(BeanUtil.copyToList(prodCateService.getSubList(parCateId), ProdCateVO.class)); + } + + /** * APP首页获取商品分类 @@ -109,4 +120,6 @@ public class SysProductCategoryController extends XktBaseController { } + + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundPlayController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundController.java similarity index 53% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundPlayController.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundController.java index 4ee5885ca..6ba1f5a65 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundPlayController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundController.java @@ -5,18 +5,18 @@ import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.XktBaseController; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.enums.BusinessType; -import com.ruoyi.web.controller.xkt.vo.advert.AdvertCreateVO; -import com.ruoyi.web.controller.xkt.vo.advertRoundPlay.AdPlayStoreCreateVO; -import com.ruoyi.web.controller.xkt.vo.advertRoundPlay.AdPlayStoreResVO; -import com.ruoyi.xkt.dto.advert.AdvertCreateDTO; -import com.ruoyi.xkt.dto.advertRoundPlay.AdPlayStoreCreateDTO; -import com.ruoyi.xkt.service.IAdvertRoundPlayService; +import com.ruoyi.web.controller.xkt.vo.advertRound.AdRoundStoreCreateVO; +import com.ruoyi.web.controller.xkt.vo.advertRound.AdRoundStoreResVO; +import com.ruoyi.xkt.dto.advertRound.AdRoundStoreCreateDTO; +import com.ruoyi.xkt.service.IAdvertRoundService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.text.ParseException; + /** * 推广营销轮次投放Controller * @@ -26,11 +26,10 @@ import org.springframework.web.bind.annotation.*; @Api(tags = "推广营销轮次投放") @RestController @RequiredArgsConstructor -@RequestMapping("/rest/v1/ad-round-plays") -public class AdvertRoundPlayController extends XktBaseController { - - final IAdvertRoundPlayService adPlayService; +@RequestMapping("/rest/v1/ad-rounds") +public class AdvertRoundController extends XktBaseController { + final IAdvertRoundService advertRoundService; /** * 档口购买推广营销 @@ -38,23 +37,32 @@ public class AdvertRoundPlayController extends XktBaseController { @ApiOperation(value = "档口购买推广营销", httpMethod = "POST", response = R.class) @Log(title = "档口购买推广营销", businessType = BusinessType.INSERT) @PostMapping - public R create(@Validated @RequestBody AdPlayStoreCreateVO createVO) { - return R.ok(adPlayService.create(BeanUtil.toBean(createVO, AdPlayStoreCreateDTO.class))); + public R create(@Validated @RequestBody AdRoundStoreCreateVO createVO) { + return R.ok(advertRoundService.create(BeanUtil.toBean(createVO, AdRoundStoreCreateDTO.class))); } - /** * 根据类型查询当前档口的推广营销数据 */ @ApiOperation(value = "根据类型查询当前档口的推广营销数据", httpMethod = "GET", response = R.class) @GetMapping(value = "/{typeId}/{storeId}") - public R getStoreAdInfo(@PathVariable("typeId") Integer typeId, - @PathVariable("storeId") Long storeId) { - return R.ok(BeanUtil.toBean(adPlayService.getStoreAdInfo(storeId, typeId), AdPlayStoreResVO.class)); + public R getStoreAdInfo(@PathVariable("typeId") Integer typeId, + @PathVariable("storeId") Long storeId) { + return R.ok(BeanUtil.toBean(advertRoundService.getStoreAdInfo(storeId, typeId), AdRoundStoreResVO.class)); } + @GetMapping("/test") + public void test() throws ParseException { + advertRoundService.saveAdvertDeadlineToRedis(); + } + + + + // TODO 退订 + + // TODO 每晚定时任务 调整 推广营销的offerStatus diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java index ac170da5d..dcf578912 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreController.java @@ -103,5 +103,14 @@ public class StoreController extends XktBaseController { return R.ok(BeanUtil.toBean(storeService.getApproveInfo(storeId), StoreApproveResVO.class)); } + /** + * APP获取档口基本信息 + */ + @ApiOperation(value = "档口审核是获取档口基本信息", httpMethod = "GET", response = R.class) + @GetMapping(value = "/app/{storeId}") + public R getAppInfo(@PathVariable("storeId") Long storeId) { + return R.ok(BeanUtil.toBean(storeService.getAppInfo(storeId), StoreAppResVO.class)); + } + } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductController.java index 1aadff21f..2f3f320e1 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/StoreProductController.java @@ -39,6 +39,15 @@ public class StoreProductController extends XktBaseController { final IStoreProductService storeProdService; + /** + * 查询档口商品所有的风格 + */ + @ApiOperation(value = "查询档口商品所有的风格", httpMethod = "GET", response = R.class) + @GetMapping(value = "/styles") + public R> getStyleList() { + return R.ok(storeProdService.getStyleList()); + } + /** * 模糊查询档口商品 */ diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreCreateVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreCreateVO.java new file mode 100644 index 000000000..d922646b0 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreCreateVO.java @@ -0,0 +1,49 @@ +package com.ruoyi.web.controller.xkt.vo.advertRound; + +import com.fasterxml.jackson.annotation.JsonInclude; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("档口购买推广营销位") +@Data +@Accessors(chain = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class AdRoundStoreCreateVO { + + @NotNull(message = "广告ID不能为空!") + @ApiModelProperty(value = "广告ID") + private Long advertId; + @NotNull(message = "广告轮次ID不能为空!") + @ApiModelProperty(value = "广告轮次ID") + private Long roundId; + @NotNull(message = "typeId不能为空!") + @ApiModelProperty(value = "typeId") + private Integer typeId; + @ApiModelProperty(value = "[不一定传]广告位置 A B C D E") + private String position; + @NotNull(message = "推广档口ID不能为空!") + @ApiModelProperty(value = "推广档口ID") + private Long storeId; + @NotNull(message = "推广档口出价不能为空!") + @ApiModelProperty(value = "推广档口出价") + private BigDecimal payPrice; + @ApiModelProperty(value = "图片设计(1 自主设计、2 平台设计)") + private Integer picDesignType; + @ApiModelProperty(value = "推广商品ID列表") + private String prodIdStr; + @NotBlank(message = "对象锁符号不能为空!") + @ApiModelProperty(value = "对象锁符号") + private String symbol; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java similarity index 74% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreResVO.java rename to ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java index 54134acb9..48c599c72 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreResVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java @@ -1,4 +1,4 @@ -package com.ruoyi.web.controller.xkt.vo.advertRoundPlay; +package com.ruoyi.web.controller.xkt.vo.advertRound; import io.swagger.annotations.ApiModel; import lombok.Data; @@ -12,7 +12,7 @@ import lombok.experimental.Accessors; @ApiModel("当前类型档口营销推广数据") @Data @Accessors(chain = true) -public class AdPlayStoreResVO { +public class AdRoundStoreResVO { } diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppResVO.java new file mode 100644 index 000000000..bcbbc111d --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/store/StoreAppResVO.java @@ -0,0 +1,33 @@ +package com.ruoyi.web.controller.xkt.vo.store; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("档口App基本信息") +@Data +public class StoreAppResVO { + + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "是否已关注") + private Boolean attention; + @ApiModelProperty(value = "标签列表") + private List tagList; + @ApiModelProperty(value = "档口地址") + private String storeAddress; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + @ApiModelProperty(value = "备选联系电话") + private String contactBackPhone; + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java index 6bec97471..0de36b9bf 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/website/IndexSearchVO.java @@ -20,6 +20,8 @@ public class IndexSearchVO extends BasePageVO { @ApiModelProperty(value = "搜索内容") private String search; + @ApiModelProperty(value = "商品状态列表") + private List prodStatusList; @ApiModelProperty(value = "一级类目ID列表") private List parCateIdList; @ApiModelProperty(value = "二级类目ID列表") diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java index 38e077269..e197d0c87 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/Constants.java @@ -1,8 +1,12 @@ package com.ruoyi.common.constant; -import java.util.Locale; +import com.ruoyi.common.enums.AdType; import io.jsonwebtoken.Claims; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + /** * 通用常量信息 * @@ -219,5 +223,23 @@ public class Constants */ public static final Long TOPMOST_PRODUCT_CATEGORY_ID = 1L; + /** + * 枚举的广告位类型 + */ + public final static List posEnumTypeList = new ArrayList() {{ + // 人气榜中上侧 + add(AdType.PC_HOME_POP_MID_TOP.getValue()); + // 人气榜中下侧 + add(AdType.PC_HOME_POP_MID_BOTTOM.getValue()); + // 人气榜右上侧 + add(AdType.PC_HOME_POP_RIGHT_TOP.getValue()); + // 人气榜右下侧 + add(AdType.PC_HOME_POP_RIGHT_BOTTOM.getValue()); + // 新品馆热卖榜右推广商品 + add(AdType.PC_NEW_PROD_HOT_RIGHT_PRODUCT.getValue()); + // PC下载页 + add(AdType.PC_DOWNLOAD.getValue()); + }}; + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java similarity index 99% rename from xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java rename to ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java index 55833cf59..dd4489206 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/enums/AdType.java @@ -1,4 +1,4 @@ -package com.ruoyi.xkt.enums; +package com.ruoyi.common.enums; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.exception.ServiceException; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java index 96dea6d84..c03d067a1 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; +import java.text.ParseException; /** * 调度任务信息操作处理 @@ -71,4 +72,12 @@ public class DailyTaskController extends BaseController { return R.ok(); } + @PostMapping("/advert-round-filter") + public R dailyRoundFilterTime(SysJob sysJob) throws ParseException { + task.saveAdvertDeadlineToRedis(); + return R.ok(); + } + + + } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java index f31b8bc0a..38d9f5301 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/XktTask.java @@ -7,19 +7,20 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.core.domain.entity.SysProductCategory; +import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.framework.es.EsClientWrapper; -import com.ruoyi.quartz.domain.*; -import com.ruoyi.quartz.dto.DailySaleCusDTO; -import com.ruoyi.quartz.dto.DailySaleDTO; -import com.ruoyi.quartz.dto.DailySaleProdDTO; -import com.ruoyi.quartz.dto.WeekCateSaleDTO; -import com.ruoyi.quartz.mapper.*; import com.ruoyi.system.mapper.SysProductCategoryMapper; import com.ruoyi.xkt.domain.*; +import com.ruoyi.xkt.dto.dailySale.DailySaleCusDTO; +import com.ruoyi.xkt.dto.dailySale.DailySaleDTO; +import com.ruoyi.xkt.dto.dailySale.DailySaleProdDTO; +import com.ruoyi.xkt.dto.dailySale.WeekCateSaleDTO; import com.ruoyi.xkt.dto.dailyStoreTag.DailyStoreTagDTO; import com.ruoyi.xkt.enums.*; import com.ruoyi.xkt.mapper.*; +import com.ruoyi.xkt.service.IAdvertRoundService; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; @@ -27,10 +28,13 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; +import java.text.ParseException; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.ZoneId; -import java.time.temporal.ChronoUnit; +import java.time.format.DateTimeFormatter; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import java.util.stream.Collectors; @@ -63,6 +67,8 @@ public class XktTask { final EsClientWrapper esClientWrapper; final AdvertMapper advertMapper; final AdvertRoundMapper advertRoundMapper; + final RedisCache redisCache; + final IAdvertRoundService advertRoundService; /** * 每晚1点同步档口销售数据 @@ -297,7 +303,7 @@ public class XktTask { * 每晚定时任务更新推广的播放轮次,这个要次日凌晨更新 */ @Transactional - public void dailyAdvertRound(){ + public void dailyAdvertRound() { List advertList = this.advertMapper.selectList(new LambdaQueryWrapper() .eq(Advert::getDelFlag, Constants.UNDELETED).eq(Advert::getOnlineStatus, AdOnlineStatus.ONLINE.getValue())); if (CollectionUtils.isEmpty(advertList)) { @@ -325,10 +331,15 @@ public class XktTask { final LocalDate endDate = now.plusDays(advert.getPlayInterval() - 1); // 按照播放数量依次生成下一轮播放的推广位 for (int j = 0; j < advert.getPlayNum(); j++) { - updateList.add(new AdvertRound().setAdvertId(advert.getId()).setRoundId(i + 1).setLaunchStatus(launchStatus) - .setStartTime(java.sql.Date.valueOf(now)).setEndTime(java.sql.Date.valueOf(endDate)) - // 依次按照26个字母顺序 如果i == 0 则A i == 1 则B i==2则C - .setPosition(String.valueOf((char) ('A' + j)))); + // 依次按照26个字母顺序 如果i == 0 则A i == 1 则B i==2则C + final String position = String.valueOf((char) ('A' + j)); + // 当前播放轮次id + final int roundId = i + 1; + updateList.add(new AdvertRound().setAdvertId(advert.getId()).setTypeId(advert.getTypeId()).setRoundId(roundId).setLaunchStatus(launchStatus) + .setStartTime(java.sql.Date.valueOf(now)).setEndTime(java.sql.Date.valueOf(endDate)).setPosition(position) + .setSymbol(Constants.posEnumTypeList.contains(advert.getTypeId()) + // 如果是位置枚举的推广位,则需要精确到某一个position的推广位,反之,若是时间范围,则直接精确到播放轮次即可 + ? advert.getBasicSymbol() + roundId + position : advert.getBasicSymbol() + roundId)); } } } else { @@ -364,13 +375,20 @@ public class XktTask { final LocalDate endDate = startDate.plusDays(advert.getPlayInterval() - 1); // 每一轮的播放数量 for (int i = 0; i < advert.getPlayNum(); i++) { + // 依次按照26个字母顺序 如果i == 0 则A i == 1 则B i==2则C + final String position = String.valueOf((char) ('A' + j)); // 生成最新的下一轮推广位 - updateList.add(new AdvertRound().setAdvertId(advert.getId()).setRoundId(maxRoundId).setLaunchStatus(AdLaunchStatus.UN_LAUNCH.getValue()) + updateList.add(new AdvertRound().setAdvertId(advert.getId()).setTypeId(advert.getTypeId()).setRoundId(maxRoundId) + .setLaunchStatus(AdLaunchStatus.UN_LAUNCH.getValue()).setPosition(position) + // java.sql.Date 直接转化成yyyy-MM-dd格式 .setStartTime(java.sql.Date.valueOf(startDate)).setEndTime(java.sql.Date.valueOf(endDate)) - // 依次按照26个字母顺序 如果i == 0 则A i == 1 则B i==2则C - .setPosition(String.valueOf((char) ('A' + i)))); + .setSymbol(Constants.posEnumTypeList.contains(advert.getTypeId()) + // 如果是位置枚举的推广位,则需要精确到某一个position的推广位,反之,若是时间范围,则直接精确到播放轮次即可 + ? advert.getBasicSymbol() + maxRoundId + position : advert.getBasicSymbol() + maxRoundId)); } } + // 需要更新推广位轮次最新的资源锁 + this.advertRoundService.initAdvertLockMap(); } } } @@ -381,6 +399,22 @@ public class XktTask { } + /** + * 通过定时任务(每天晚上9:00)往redis中放当前推广位 当前播放轮 或 即将播放轮 的截止时间; + * 比如:5.1 - 5.3 + * a. 现在是4.30 则截止时间是 4.30 22:00 + * b. 现在是5.2,则截止时间是 5.2 22:00:00 。 + * c. 现在是5.3,则第一轮还有请求,肯定是人为的不用管。请求第三轮 或者 第四轮 不报错。只处理第二轮请求 + * + * @throws ParseException + */ + public void saveAdvertDeadlineToRedis() throws ParseException { + // 直接调service方法,若当时redis出了问题,也方便第一时间 通过业务流程弥补 两边都有一个补偿机制 + advertRoundService.saveAdvertDeadlineToRedis(); + } + + + /** * 给商品打风格标签 * diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleCustomerMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleCustomerMapper.xml index 1b68e43cd..426a26ff2 100644 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleCustomerMapper.xml +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleCustomerMapper.xml @@ -2,9 +2,9 @@ - + - SELECT ss.store_id, ss.store_cus_id, diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleMapper.xml index d3f96596d..c61475954 100644 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleMapper.xml +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleMapper.xml @@ -2,9 +2,9 @@ - + - SELECT ss.store_id, COALESCE(SUM(CASE WHEN ssd.sale_type = 1 THEN ssd.amount ELSE 0 END), 0) AS saleAmount, diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml index 8242e52fd..7bb457c1a 100644 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/DailySaleProductMapper.xml @@ -2,9 +2,9 @@ - + - SELECT sp.store_id, sp.id AS store_prod_id, diff --git a/ruoyi-quartz/src/main/resources/mapper/quartz/WeekCateSaleMapper.xml b/ruoyi-quartz/src/main/resources/mapper/quartz/WeekCateSaleMapper.xml index 165996237..401aed212 100644 --- a/ruoyi-quartz/src/main/resources/mapper/quartz/WeekCateSaleMapper.xml +++ b/ruoyi-quartz/src/main/resources/mapper/quartz/WeekCateSaleMapper.xml @@ -2,9 +2,9 @@ - + - SELECT sp.prod_cate_id, COUNT( prod_cate_id ) AS count diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysProductCategoryService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysProductCategoryService.java index 37843d6ff..517f4c728 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysProductCategoryService.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysProductCategoryService.java @@ -68,4 +68,12 @@ public interface ISysProductCategoryService { */ List appCate(); + /** + * 根据1级分类获取二级分类列表 + * + * @param parCateId 一级分类ID + * @return + */ + List getSubList(Long parCateId); + } diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysProductCategoryServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysProductCategoryServiceImpl.java index 7e24f08b0..78bbfcc39 100644 --- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysProductCategoryServiceImpl.java +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysProductCategoryServiceImpl.java @@ -161,6 +161,20 @@ public class SysProductCategoryServiceImpl implements ISysProductCategoryService .map(x -> BeanUtil.toBean(x, AppHomeProdCateListResDTO.class)).collect(Collectors.toList()); } + /** + * 根据1级分类获取二级分类列表 + * + * @param parCateId 一级分类ID + * @return + */ + @Override + @Transactional(readOnly = true) + public List getSubList(Long parCateId) { + List subCateList = this.prodCateMapper.selectList(new LambdaQueryWrapper() + .eq(SysProductCategory::getParentId, parCateId).eq(SysProductCategory::getDelFlag, Constants.UNDELETED)); + return BeanUtil.copyToList(subCateList, ProdCateDTO.class); + } + /** * 组装商品分类树 diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java b/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java index 0dbd8ffcd..51cf17ed7 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java @@ -25,6 +25,14 @@ public class Advert extends XktBaseEntity { */ @TableId private Long id; + /** + * 每一个广告位基础锁符号 10位大小写、字母组成的字符串 + */ + private String basicSymbol; + /** + * 每个档口可以购买当前广告位数量限制 + */ + private Integer storeBuyLimit; /** * 推广平台 电脑端 、APP */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java index 34584c671..a71b54abb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java @@ -31,10 +31,18 @@ public class AdvertRound extends XktBaseEntity { * 广告ID */ private Long advertId; + /** + * 推广类型 + */ + private Integer typeId; /** * 轮次ID */ private Integer roundId; + /** + * 资源锁标识 位置枚举的推广位精确到A B C D E 等,时间范围的推广位精确到具体类型 + */ + private String symbol; /** * 投放状态 */ @@ -51,21 +59,6 @@ public class AdvertRound extends XktBaseEntity { * 广告位置 A B C D E... 对应advert中的playNum */ private String position; - - - - - - - - - - - - - - - /** * 推广档口ID */ @@ -75,9 +68,13 @@ public class AdvertRound extends XktBaseEntity { */ private BigDecimal payPrice; /** - * 竞价状态 + * 只要有人出价:这个就被置为 已出价 晚上定时任务改为 竞价成功 */ private Integer biddingStatus; + /** + * 竞价状态 竞价成功 竞价失败的进入到 advert_round_record表中 + */ + private Integer biddingTempStatus; /** * 图片审核状态 */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java similarity index 61% rename from xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java index 1a7c7e2dc..b6ec35cfb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java @@ -4,39 +4,61 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.ruoyi.common.core.domain.XktBaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; import java.math.BigDecimal; +import java.util.Date; /** - * 广告营销每一轮播放 advert_round_play + * 广告营销每一轮竞价历史数据 advert_round_record * * @author liujiang * @date 2025-05-03 */ @EqualsAndHashCode(callSuper = true) @Data -public class AdvertRoundPlay extends XktBaseEntity { +@Accessors(chain = true) +public class AdvertRoundRecord extends XktBaseEntity { private static final long serialVersionUID = 1L; /** - * 广告轮次播放ID + * 广告营销每一轮历史竞价记录ID */ @TableId private Long id; + /** + * 推广营销轮次位置ID + */ + private Long advertRoundId; /** * 广告ID */ private Long advertId; /** - * 广告轮次ID + * 轮次ID */ - private Long advertRoundId; - - - - - + private Integer roundId; + /** + * 资源锁标识 位置枚举的推广位精确到A B C D E 等,时间范围的推广位精确到具体类型 + */ + private String symbol; + /** + * 投放状态 + */ + private Integer launchStatus; + /** + * 投放开始时间 + */ + private Date startTime; + /** + * 投放结束时间 + */ + private Date endTime; + /** + * 广告位置 A B C D E... 对应advert中的playNum + */ + private String position; /** * 推广档口ID */ diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyProdTag.java b/xkt/src/main/java/com/ruoyi/xkt/domain/DailyProdTag.java similarity index 96% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyProdTag.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/DailyProdTag.java index 5f2796e73..4362cb67a 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyProdTag.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/DailyProdTag.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.domain; +package com.ruoyi.xkt.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySale.java b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySale.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySale.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/DailySale.java index 1fb48dd7b..9cced4479 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySale.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySale.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.domain; +package com.ruoyi.xkt.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleCustomer.java b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleCustomer.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleCustomer.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleCustomer.java index 276a60c5e..ab725cf1b 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleCustomer.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleCustomer.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.domain; +package com.ruoyi.xkt.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleProduct.java b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleProduct.java similarity index 97% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleProduct.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleProduct.java index f8aa3adc5..af106e38c 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailySaleProduct.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/DailySaleProduct.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.domain; +package com.ruoyi.xkt.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyStoreTag.java b/xkt/src/main/java/com/ruoyi/xkt/domain/DailyStoreTag.java similarity index 96% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyStoreTag.java rename to xkt/src/main/java/com/ruoyi/xkt/domain/DailyStoreTag.java index 018c29cc0..ec161349b 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/DailyStoreTag.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/DailyStoreTag.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.domain; +package com.ruoyi.xkt.domain; import com.baomidou.mybatisplus.annotation.TableId; import com.fasterxml.jackson.annotation.JsonFormat; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreCreateDTO.java similarity index 69% rename from ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreCreateDTO.java index b94943803..ca439022c 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreCreateDTO.java @@ -1,10 +1,11 @@ -package com.ruoyi.web.controller.xkt.vo.advertRoundPlay; +package com.ruoyi.xkt.dto.advertRound; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.experimental.Accessors; +import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; import java.math.BigDecimal; @@ -16,23 +17,25 @@ import java.math.BigDecimal; @ApiModel("档口购买推广营销位") @Data @Accessors(chain = true) -public class AdPlayStoreCreateVO { +public class AdRoundStoreCreateDTO { - @NotNull(message = "广告ID不能为空!") @ApiModelProperty(value = "广告ID") private Long advertId; - @NotNull(message = "广告轮次ID不能为空!") @ApiModelProperty(value = "广告轮次ID") - private Long advertRoundId; - @NotNull(message = "推广档口ID不能为空!") + private Long roundId; + @ApiModelProperty(value = "typeId") + private Integer typeId; + @ApiModelProperty(value = "广告位置 A B C D E") + private String position; @ApiModelProperty(value = "推广档口ID") private Long storeId; - @NotNull(message = "推广档口出价不能为空!") @ApiModelProperty(value = "推广档口出价") private BigDecimal payPrice; @ApiModelProperty(value = "图片设计(1 自主设计、2 平台设计)") private Integer picDesignType; @ApiModelProperty(value = "推广商品ID列表") private String prodIdStr; + @ApiModelProperty(value = "对象锁符号") + private String symbol; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java similarity index 77% rename from xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java index e2d2bea88..144bc7f4e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java @@ -1,4 +1,4 @@ -package com.ruoyi.xkt.dto.advertRoundPlay; +package com.ruoyi.xkt.dto.advertRound; import io.swagger.annotations.ApiModel; import lombok.Data; @@ -12,7 +12,7 @@ import lombok.experimental.Accessors; @ApiModel("当前类型档口营销推广数据") @Data @Accessors(chain = true) -public class AdPlayStoreResDTO { +public class AdRoundStoreResDTO { } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreCreateDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreCreateDTO.java deleted file mode 100644 index 85b2be69d..000000000 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreCreateDTO.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.ruoyi.xkt.dto.advertRoundPlay; - -import io.swagger.annotations.ApiModel; -import io.swagger.annotations.ApiModelProperty; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.math.BigDecimal; - -/** - * @author liujiang - * @version v1.0 - * @date 2025/3/27 15:12 - */ -@ApiModel("档口购买推广营销位") -@Data -@Accessors(chain = true) -public class AdPlayStoreCreateDTO { - - @ApiModelProperty(value = "广告ID") - private Long advertId; - @ApiModelProperty(value = "广告轮次ID") - private Long advertRoundId; - @ApiModelProperty(value = "推广档口ID") - private Long storeId; - @ApiModelProperty(value = "推广档口出价") - private BigDecimal payPrice; - @ApiModelProperty(value = "图片设计(1 自主设计、2 平台设计)") - private Integer picDesignType; - @ApiModelProperty(value = "推广商品ID列表") - private String prodIdStr; - -} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleCusDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleCusDTO.java similarity index 93% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleCusDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleCusDTO.java index 6e14116d6..f8f03d64b 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleCusDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleCusDTO.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.dto; +package com.ruoyi.xkt.dto.dailySale; import lombok.Data; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleDTO.java similarity index 94% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleDTO.java index 5d433a92f..7035de9dc 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleDTO.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.dto; +package com.ruoyi.xkt.dto.dailySale; import lombok.Data; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleProdDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleProdDTO.java similarity index 94% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleProdDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleProdDTO.java index 9d544cecd..b09018a5a 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/DailySaleProdDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/DailySaleProdDTO.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.dto; +package com.ruoyi.xkt.dto.dailySale; import com.ruoyi.common.annotation.Excel; import lombok.Data; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/WeekCateSaleDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/WeekCateSaleDTO.java similarity index 87% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/WeekCateSaleDTO.java rename to xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/WeekCateSaleDTO.java index 06b0ecdbc..7ffa9888f 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/dto/WeekCateSaleDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/dailySale/WeekCateSaleDTO.java @@ -1,4 +1,4 @@ -package com.ruoyi.quartz.dto; +package com.ruoyi.xkt.dto.dailySale; import lombok.Data; diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java index 48d3bebaa..6c8b1b386 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/es/ESProductDTO.java @@ -17,6 +17,8 @@ import java.util.List; @Accessors(chain = true) public class ESProductDTO { + @ApiModelProperty(value = "档口商品ID") + private String storeProdId; @ApiModelProperty(value = "货号") private String prodArtNum; @ApiModelProperty(value = "档口商品分类ID") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppResDTO.java new file mode 100644 index 000000000..b465d793c --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/store/StoreAppResDTO.java @@ -0,0 +1,35 @@ +package com.ruoyi.xkt.dto.store; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("档口App基本信息") +@Data +@Accessors(chain = true) +public class StoreAppResDTO { + + @ApiModelProperty(value = "档口ID") + private Long storeId; + @ApiModelProperty(value = "档口名称") + private String storeName; + @ApiModelProperty(value = "是否已关注") + private Boolean attention; + @ApiModelProperty(value = "标签列表") + private List tagList; + @ApiModelProperty(value = "档口地址") + private String storeAddress; + @ApiModelProperty(value = "联系电话") + private String contactPhone; + @ApiModelProperty(value = "备选联系电话") + private String contactBackPhone; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/website/IndexSearchDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/website/IndexSearchDTO.java index 4693db047..6e0c235cf 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/website/IndexSearchDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/website/IndexSearchDTO.java @@ -21,6 +21,8 @@ public class IndexSearchDTO extends BasePageDTO { @ApiModelProperty(value = "搜索内容") private String search; + @ApiModelProperty(value = "商品状态列表") + private List prodStatusList; @ApiModelProperty(value = "一级类目ID列表") private List parCateIdList; @ApiModelProperty(value = "二级类目ID列表") diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java index 365314c53..084675106 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java @@ -2,6 +2,7 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.AdvertRound; +import org.apache.ibatis.annotations.Param; import org.springframework.stereotype.Repository; /** @@ -13,4 +14,15 @@ import org.springframework.stereotype.Repository; @Repository public interface AdvertRoundMapper extends BaseMapper { + /** + * 判断当前档口是否超买广告位 + * + * @param advertId 推广位ID + * @param roundId 播放轮次ID + * @param storeId 档口ID + * @param position 位置 + * @return true 已超 false 未超 + */ + boolean isStallOverBuy(@Param("advertId") Long advertId, @Param("roundId") Long roundId, @Param("storeId") Long storeId, @Param("position") String position); + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java deleted file mode 100644 index 9398f4541..000000000 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.ruoyi.xkt.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.xkt.domain.AdvertRoundPlay; -import org.springframework.stereotype.Repository; - -/** - * 推广营销轮次Mapper接口 - * - * @author ruoyi - * @date 2025-03-26 - */ -@Repository -public interface AdvertRoundPlayMapper extends BaseMapper { - -} diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundRecordMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundRecordMapper.java new file mode 100644 index 000000000..0b2f3c0f8 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundRecordMapper.java @@ -0,0 +1,17 @@ +package com.ruoyi.xkt.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.xkt.domain.AdvertRound; +import com.ruoyi.xkt.domain.AdvertRoundRecord; +import org.springframework.stereotype.Repository; + +/** + * 推广营销轮次历史记录Mapper接口 + * + * @author ruoyi + * @date 2025-03-26 + */ +@Repository +public interface AdvertRoundRecordMapper extends BaseMapper { + +} diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyProdTagMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailyProdTagMapper.java similarity index 71% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyProdTagMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/DailyProdTagMapper.java index 38d9f85b5..68d950469 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyProdTagMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailyProdTagMapper.java @@ -1,7 +1,7 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.quartz.domain.DailyProdTag; +import com.ruoyi.xkt.domain.DailyProdTag; /** * 调度任务信息 数据层 diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleCustomerMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleCustomerMapper.java similarity index 70% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleCustomerMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleCustomerMapper.java index e802fa9e2..ae32a86c6 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleCustomerMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleCustomerMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.quartz.domain.DailySaleCustomer; -import com.ruoyi.quartz.dto.DailySaleCusDTO; +import com.ruoyi.xkt.domain.DailySaleCustomer; +import com.ruoyi.xkt.dto.dailySale.DailySaleCusDTO; import java.util.Date; import java.util.List; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleMapper.java similarity index 71% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleMapper.java index fcb50a740..67d69f770 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleMapper.java @@ -1,8 +1,8 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.quartz.domain.DailySale; -import com.ruoyi.quartz.dto.DailySaleDTO; +import com.ruoyi.xkt.domain.DailySale; +import com.ruoyi.xkt.dto.dailySale.DailySaleDTO; import java.util.Date; import java.util.List; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleProductMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleProductMapper.java similarity index 58% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleProductMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleProductMapper.java index 482775538..f3f8b0eed 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailySaleProductMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailySaleProductMapper.java @@ -1,10 +1,8 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.quartz.domain.DailySaleCustomer; -import com.ruoyi.quartz.domain.DailySaleProduct; -import com.ruoyi.quartz.dto.DailySaleDTO; -import com.ruoyi.quartz.dto.DailySaleProdDTO; +import com.ruoyi.xkt.domain.DailySaleProduct; +import com.ruoyi.xkt.dto.dailySale.DailySaleProdDTO; import java.util.Date; import java.util.List; diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyStoreTagMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailyStoreTagMapper.java similarity index 71% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyStoreTagMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/DailyStoreTagMapper.java index 6cdeb6911..52d92ff9a 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/DailyStoreTagMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/DailyStoreTagMapper.java @@ -1,7 +1,7 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.ruoyi.quartz.domain.DailyStoreTag; +import com.ruoyi.xkt.domain.DailyStoreTag; /** * 调度任务信息 数据层 diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java index fbf8cb0fd..a2bb990b2 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/StoreProductMapper.java @@ -90,4 +90,10 @@ public interface StoreProductMapper extends BaseMapper { */ List selectESDTOList(@Param("idList") List idList); + /** + * 获取风格列表 + * @return + */ + List getStyleList(); + } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/WeekCateSaleMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/WeekCateSaleMapper.java similarity index 79% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/WeekCateSaleMapper.java rename to xkt/src/main/java/com/ruoyi/xkt/mapper/WeekCateSaleMapper.java index 8b9b433c3..793ca7160 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/mapper/WeekCateSaleMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/WeekCateSaleMapper.java @@ -1,6 +1,6 @@ -package com.ruoyi.quartz.mapper; +package com.ruoyi.xkt.mapper; -import com.ruoyi.quartz.dto.WeekCateSaleDTO; +import com.ruoyi.xkt.dto.dailySale.WeekCateSaleDTO; import org.apache.ibatis.annotations.Param; import java.util.Date; diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java deleted file mode 100644 index 433ea3409..000000000 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.ruoyi.xkt.service; - -import com.ruoyi.xkt.dto.advertRoundPlay.AdPlayStoreCreateDTO; -import com.ruoyi.xkt.dto.advertRoundPlay.AdPlayStoreResDTO; - -/** - * 推广营销Service接口 - * - * @author ruoyi - * @date 2025-03-26 - */ -public interface IAdvertRoundPlayService { - - /** - * 获取当前类型下档口的推广营销数据 - * - * @param storeId 档口ID - * @param typeId 推广类型ID - * @return AdRoundPlayStoreResDTO - */ - AdPlayStoreResDTO getStoreAdInfo(Long storeId, Integer typeId); - - /** - * 档口购买推广营销 - * - * @param createDTO 购买入参 - * @return Integer - */ - Integer create(AdPlayStoreCreateDTO createDTO); - -} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundService.java new file mode 100644 index 000000000..e6085b439 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundService.java @@ -0,0 +1,47 @@ +package com.ruoyi.xkt.service; + +import com.ruoyi.xkt.dto.advertRound.AdRoundStoreCreateDTO; +import com.ruoyi.xkt.dto.advertRound.AdRoundStoreResDTO; + +import java.text.ParseException; + +/** + * 推广营销Service接口 + * + * @author ruoyi + * @date 2025-03-26 + */ +public interface IAdvertRoundService { + + /** + * 获取当前类型下档口的推广营销数据 + * + * @param storeId 档口ID + * @param typeId 推广类型ID + * @return AdRoundPlayStoreResDTO + */ + AdRoundStoreResDTO getStoreAdInfo(Long storeId, Integer typeId); + + /** + * 档口购买推广营销 + * + * @param createDTO 购买入参 + * @return Integer + */ + Integer create(AdRoundStoreCreateDTO createDTO); + + /** + * 初始化每天购买广告的截止时间 + * + * @throws ParseException + */ + void saveAdvertDeadlineToRedis() throws ParseException; + + /** + * 初始化广告竞争的资源锁 + */ + void initAdvertLockMap(); + + void test(); + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreProductService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreProductService.java index 6da97933b..7c007515f 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreProductService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreProductService.java @@ -97,4 +97,10 @@ public interface IStoreProductService { * @return List */ List fuzzyQueryResPicList(Long storeId, String prodArtNum); + + /** + * 获取商品所有的风格 + * @return + */ + List getStyleList(); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java index 280349733..279741f0f 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IStoreService.java @@ -67,4 +67,11 @@ public interface IStoreService { */ StoreApproveResDTO getApproveInfo(Long storeId); + /** + * 获取APP档口基本信息 + * + * @param storeId 档口ID + * @return StoreAppResDTO + */ + StoreAppResDTO getAppInfo(Long storeId); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundPlayServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundPlayServiceImpl.java deleted file mode 100644 index eca04c871..000000000 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundPlayServiceImpl.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.ruoyi.xkt.service.impl; - -import com.ruoyi.xkt.dto.advertRoundPlay.AdPlayStoreCreateDTO; -import com.ruoyi.xkt.dto.advertRoundPlay.AdPlayStoreResDTO; -import com.ruoyi.xkt.mapper.AdvertRoundPlayMapper; -import com.ruoyi.xkt.service.IAdvertRoundPlayService; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -/** - * 推广营销轮次播放Service业务层处理 - * - * @author ruoyi - * @date 2025-03-26 - */ -@Service -@RequiredArgsConstructor -public class AdvertRoundPlayServiceImpl implements IAdvertRoundPlayService { - - final AdvertRoundPlayMapper adRoundPlayMapper; - - /** - * 获取当前类型下档口的推广营销数据 - * - * @param storeId 档口ID - * @param typeId 推广类型ID - * @return AdRoundPlayStoreResDTO - */ - @Override - @Transactional(readOnly = true) - public AdPlayStoreResDTO getStoreAdInfo(Long storeId, Integer typeId) { - // 先获取所有 投放中 待投放的营销推广 - // 再判断当前当前与每一轮推广营销中的关系,已出价、竞价失败、竞价成功等 - - return null; - } - - /** - * 档口购买推广营销 - * 思路:每次筛选出某个类型,价格最低的推广位,然后只操作这行数据。 - * 若:该行数据已经有其它档口先竞价了。先进行比价。如果出价低于最低价格,则抛出异常:“已经有档口出价更高了噢,请重新出价!” - * 若:新出价比原数据价格高,则:a. 给原数据档口创建转移支付单 b.新档口占据改行数据位置。 - * - * 等到晚上10:00,所有档口购买完成。再通过定时任务(11:30),给每个类型,按照价格从高到低,进行排序。 - * - * - * LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); - * wrapper.eq(Product::getType, specificType) // 筛选出特定类型的记录 - * .orderByAsc(Product::getPrice) // 升序排序,NULL 会在最前面 - * .last("LIMIT 1"); // 取第一条(即 price 最低或为 null) - * - * @param createDTO 购买入参 - * @return Integer - */ - @Override - @Transactional - - // TODO 要加锁,必须要锁住,有可能多个档口同时购买同一个推广营销位,导致购买失败,锁必须要做好 - // TODO 要加锁,必须要锁住,有可能多个档口同时购买同一个推广营销位,导致购买失败,锁必须要做好 - // TODO 要加锁,必须要锁住,有可能多个档口同时购买同一个推广营销位,导致购买失败,锁必须要做好 - - - public Integer create(AdPlayStoreCreateDTO createDTO) { - - // 判断当前档口出价是否低于最低价格,若是,则提示:“已经有档口出价更高了噢,请重新出价!” - - - // 要判断当前是多个档口购买一个推广位,没有排序。还是多个档口购买同一个推广位,需要排序。 - - - // 这里还有支付对接的情况!! 如果遇到支付延迟怎么办? - - - return null; - } - - - // TODO 新增档口广告购买时,需要加锁,一定要锁住 - // TODO 新增档口广告购买时,需要加锁,一定要锁住 - // TODO 新增档口广告购买时,需要加锁,一定要锁住 - -} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java new file mode 100644 index 000000000..b00657746 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java @@ -0,0 +1,269 @@ +package com.ruoyi.xkt.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.ruoyi.common.constant.Constants; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.core.redis.RedisCache; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.xkt.domain.AdvertRound; +import com.ruoyi.xkt.domain.AdvertRoundRecord; +import com.ruoyi.xkt.dto.advertRound.AdRoundStoreCreateDTO; +import com.ruoyi.xkt.dto.advertRound.AdRoundStoreResDTO; +import com.ruoyi.xkt.enums.AdBiddingStatus; +import com.ruoyi.xkt.enums.AdLaunchStatus; +import com.ruoyi.xkt.enums.AdRoundType; +import com.ruoyi.xkt.mapper.AdvertRoundMapper; +import com.ruoyi.xkt.mapper.AdvertRoundRecordMapper; +import com.ruoyi.xkt.service.IAdvertRoundService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.PostConstruct; +import java.math.BigDecimal; +import java.text.ParseException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * 推广营销轮次播放Service业务层处理 + * + * @author ruoyi + * @date 2025-03-26 + */ +@Service +@RequiredArgsConstructor +public class AdvertRoundServiceImpl implements IAdvertRoundService { + + final AdvertRoundMapper advertRoundMapper; + final AdvertRoundRecordMapper advertRoundRecordMapper; + final RedisCache redisCache; + + // 推广营销位锁 key:symbol + roundId 或者 symbol + roundId + position 。value都是new Object() + public static Map advertLockMap = new ConcurrentHashMap<>(); + + /** + * 项目启动后执行一次,做初始化操作 + */ + @PostConstruct + public void initAdvertLockMap() { + // 清空advertLockMap,便于多次幂等操作 + advertLockMap.clear(); + // 初始化 advertRound的 symbol 锁资源对象 + List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() + .eq(AdvertRound::getDelFlag, Constants.UNDELETED) + .in(AdvertRound::getLaunchStatus, Arrays.asList(AdLaunchStatus.LAUNCHING.getValue(), AdLaunchStatus.UN_LAUNCH.getValue()))); + if (CollectionUtils.isEmpty(advertRoundList)) { + return; + } + // 依次初始化所资源对象 如果是时间范围的推广位,则锁的是 那一个播放轮;如果是位置枚举则 锁的是某一个具体资源位 + advertRoundList.stream().collect(Collectors.groupingBy(AdvertRound::getTypeId)) + .forEach((typeId, roundList) -> roundList + // 初始化 锁资源对象 + .forEach(round -> advertLockMap.putIfAbsent(round.getSymbol(), new Object()))); + + System.err.println(advertLockMap); + + } + + public void test() { + System.err.println(advertLockMap); + } + + + + /** + * 获取当前类型下档口的推广营销数据 + * + * @param storeId 档口ID + * @param typeId 推广类型ID + * @return AdRoundPlayStoreResDTO + */ + @Override + @Transactional(readOnly = true) + public AdRoundStoreResDTO getStoreAdInfo(Long storeId, Integer typeId) { + // 先获取所有 投放中 待投放的营销推广 + // 再判断当前当前与每一轮推广营销中的关系,已出价、竞价失败、竞价成功等 + + return null; + } + + /** + * 档口购买推广营销 + * 主要是两个场景:1. 某个广告位(advert_id)某个轮次(round_id)按照出价(pay_price)决定能否购买。[eg: A B C D E] + * 2. 某个广告位(advert_id)某个轮次(round_id)某个具体位置(position)按照出价(pay_price)决定能否购买。 + * 思路:每次筛选出某个类型,价格最低的推广位,然后只操作这行数据 + * (创建索引:CREATE INDEX idx_advert_round_pay_pos ON advert_round (advert_id, round_id, pay_price, position))。 + * 若:该行数据已经有其它档口先竞价了。先进行比价。如果出价低于最低价格,则抛出异常:“已经有档口出价更高了噢,请重新出价!” + * 若:新出价比原数据价格高,则:a. 给原数据档口创建转移支付单 b.新档口占据该行位置,更新数据。 + *

+ * 等到晚上10:00,所有档口购买完成。再通过定时任务(11:30),给每个类型,按照价格从高到低,进行排序。并将首页各个位置的广告数据推送到ES中。为空的广告位如何填充?? + *

+ * + * @param createDTO 购买入参 + * @return Integer + */ + @Override + @Transactional + public Integer create(AdRoundStoreCreateDTO createDTO) { + + // 截止时间都是当天 22:00:00,并且只会处理马上播放的这一轮。比如 5.1-5.3,当前为4.30,处理这一轮;当前为5.2,处理这一轮;当前为5.3(最后一天),处理下一轮。 + if (DateUtils.getTime().compareTo(this.getDeadline(createDTO.getSymbol())) > 0) { + throw new ServiceException("竞价结束,已经有档口出价更高了噢!", HttpStatus.ERROR); + } + + // 校验position位置是否必传 + this.isPositionRequired(createDTO); + + // 判断当前推广位的这一轮每个档口可以买几个,不可超买 + boolean isOverBuy = this.advertRoundMapper.isStallOverBuy(createDTO.getAdvertId(), createDTO.getRoundId(), createDTO.getStoreId(), createDTO.getPosition()); + if (isOverBuy) { + throw new ServiceException("已购买过该推广位,不可超买哦!", HttpStatus.ERROR); + } + + + // 当前营销推广位的锁 + Object lockObj = Optional.ofNullable(advertLockMap.get(createDTO.getSymbol())).orElseThrow(() -> new ServiceException("symbol不存在!", HttpStatus.ERROR)); + // 锁当前推广营销位 + synchronized (lockObj) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(AdvertRound::getAdvertId, createDTO.getAdvertId()).eq(AdvertRound::getRoundId, createDTO.getRoundId()) + .eq(AdvertRound::getDelFlag, Constants.UNDELETED).orderByAsc(AdvertRound::getPayPrice).last("LIMIT 1"); + AdvertRound minPriceAdvert = Optional.ofNullable(this.advertRoundMapper.selectOne(queryWrapper)).orElseThrow(() -> new ServiceException("获取推广营销位置失败,请联系客服!", HttpStatus.ERROR)); + // 判断当前档口出价是否低于该推广位最低价格,若是,则提示:"已经有档口出价更高了噢,请重新出价!". + if (createDTO.getPayPrice().compareTo(ObjectUtils.defaultIfNull(minPriceAdvert.getPayPrice(), BigDecimal.ZERO)) < 0) { + throw new ServiceException("已经有档口出价更高了噢,请重新出价!", HttpStatus.ERROR); + } + + // storeId不为空,表明之前有其他的档口竞价 + if (ObjectUtils.isNotEmpty(minPriceAdvert.getStoreId())) { + + // TODO 将推广费退至原档口余额 + // TODO 将推广费退至原档口余额 + + // 记录竞价失败的档口推广营销 + this.record(minPriceAdvert); + } + + // 更新出价最低的广告位 + minPriceAdvert.setStoreId(createDTO.getStoreId()).setPayPrice(createDTO.getPayPrice()) + .setBiddingStatus(AdBiddingStatus.BIDDING.getValue()) + .setBiddingTempStatus(AdBiddingStatus.BIDDING_SUCCESS.getValue()) + .setPicDesignType(createDTO.getPicDesignType()).setProdIdStr(createDTO.getProdIdStr()); + this.advertRoundMapper.updateById(minPriceAdvert); + + // TODO 新竞价成功的档口扣减余额 + // TODO 新竞价成功的档口扣减余额 + + } + return 1; + } + + /** + * 通过定时任务往redis中放当前推广位 当前播放轮 或 即将播放轮 的截止时间; + * 比如:5.1 - 5.3 + * a. 现在是4.30 则截止时间是 4.30 22:00 + * b. 现在是5.2,则截止时间是 5.2 22:00:00 。 + * c. 现在是5.3,则第一轮还有请求,肯定是人为的不用管。请求第三轮 或者 第四轮 不报错。只处理第二轮请求 + * + * @throws ParseException + */ + public void saveAdvertDeadlineToRedis() throws ParseException { + List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() + .eq(AdvertRound::getDelFlag, Constants.UNDELETED) + .in(AdvertRound::getLaunchStatus, Arrays.asList(AdLaunchStatus.LAUNCHING.getValue(), AdLaunchStatus.UN_LAUNCH.getValue())) + .in(AdvertRound::getRoundId, Arrays.asList(AdRoundType.PLAY_ROUND.getValue(), AdRoundType.SECOND_ROUND.getValue()))); + if (CollectionUtils.isEmpty(advertRoundList)) { + return; + } + // 服务器当前时间 yyyy-MM-dd + final Date now = DateUtils.parseDate(DateUtils.getDate(), DateUtils.YYYY_MM_DD); + // 当天截止的时间 yyyy-MM-dd 22:00:00 + final String filterTime = DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS) + .format(LocalDateTime.now().withHour(22).withMinute(0).withSecond(0)); + advertRoundList.stream().collect(Collectors.groupingBy(AdvertRound::getAdvertId)) + .forEach((advertId, roundList) -> { + // 判断当前时间所处的阶段 小于第一轮播放时间(有可能新广告还未开播)、处于第一轮中间、处于第一轮最后一天 + final Date firstRoundEndTime = roundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.PLAY_ROUND.getValue())) + .max(Comparator.comparing(AdvertRound::getEndTime)) + .orElseThrow(() -> new ServiceException("获取推广结束时间失败,请联系客服!", HttpStatus.ERROR)).getEndTime(); + // 默认第一轮的symbol + String symbol = roundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.PLAY_ROUND.getValue())) + .map(AdvertRound::getSymbol).findAny().orElseThrow(() -> new ServiceException("获取推广第一轮symbol失败,请联系客服!", HttpStatus.ERROR)); + // 第一轮最后一天,则直接处理第二轮的symbol + if (now.equals(firstRoundEndTime)) { + String secondRoundSymbol = roundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.SECOND_ROUND.getValue())) + .map(AdvertRound::getSymbol).findAny().orElse(null); + // 有可能第二轮不存在,因为该推广已下线,则定时任务没有生成后续轮次 + if (StringUtils.isEmpty(secondRoundSymbol)) { + return; + } + } + // 作用于某一轮推广的symbol(包含了播放轮次的) + /*String symbol = now.before(firstRoundEndTime) + ? roundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.PLAY_ROUND.getValue())) + .map(AdvertRound::getSymbol).findAny().orElseThrow(() -> new ServiceException("获取推广第一轮symbol失败,请联系客服!", HttpStatus.ERROR)) + : roundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.SECOND_ROUND.getValue())) + .map(AdvertRound::getSymbol).findAny().orElseThrow(() -> new ServiceException("获取推广第二轮symbol失败,请联系客服!", HttpStatus.ERROR));*/ + // 存放到redis中 有效期90分钟 + redisCache.setCacheObject(symbol, filterTime, 90, TimeUnit.MINUTES); + }); + } + + /** + * 判断当前类型position是否必传 + * @param createDTO 购买广告位入参 + */ + private void isPositionRequired(AdRoundStoreCreateDTO createDTO) { + // 如果是位置枚举的推广位,则需要传position + if (Constants.posEnumTypeList.contains(createDTO.getTypeId()) && StringUtils.isEmpty(createDTO.getPosition())) { + throw new ServiceException("当前推广类型position:必传!", HttpStatus.ERROR); + } + if (!Constants.posEnumTypeList.contains(createDTO.getTypeId()) && StringUtils.isNotBlank(createDTO.getPosition())) { + throw new ServiceException("当前推广类型position:不传!", HttpStatus.ERROR); + } + } + + /** + * 获取当前推广轮次的过期时间 + * @param symbol 符号 + * @return + */ + private String getDeadline(String symbol) { + final String deadline = redisCache.getCacheObject(symbol); + return StringUtils.isNotBlank(deadline) ? deadline : ""; + } + + // TODO 在每晚11:30起定时任务,重新梳理,每个广告位的大小顺序 + // TODO 在每晚11:30起定时任务,重新梳理,每个广告位的大小顺序 + + + /** + * 记录竞价失败档口推广营销 + * @param failAdvert 竞价失败的推广营销 + */ + private void record(AdvertRound failAdvert) { + // 新增推广营销历史记录 将旧档口推广营销 置为竞价失败 + AdvertRoundRecord record = BeanUtil.toBean(failAdvert, AdvertRoundRecord.class); + record.setId(null); + record.setAdvertRoundId(failAdvert.getId()); + // 置为竞价失败 + record.setBiddingStatus(AdBiddingStatus.BIDDING_FAIL.getValue()); + this.advertRoundRecordMapper.insert(record); + } + + + // TODO 新增档口广告购买时,需要加锁,一定要锁住 + // TODO 新增档口广告购买时,需要加锁,一定要锁住 + // TODO 新增档口广告购买时,需要加锁,一定要锁住 + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertServiceImpl.java index 4bde5cd4c..1b11da63b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertServiceImpl.java @@ -1,5 +1,6 @@ package com.ruoyi.xkt.service.impl; +import java.security.SecureRandom; import cn.hutool.core.bean.BeanUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.pagehelper.PageHelper; @@ -16,7 +17,7 @@ import com.ruoyi.xkt.dto.advert.*; import com.ruoyi.xkt.enums.AdOnlineStatus; import com.ruoyi.xkt.enums.AdPlatformType; import com.ruoyi.xkt.enums.AdTab; -import com.ruoyi.xkt.enums.AdType; +import com.ruoyi.common.enums.AdType; import com.ruoyi.xkt.mapper.AdvertMapper; import com.ruoyi.xkt.mapper.SysFileMapper; import com.ruoyi.xkt.service.IAdvertService; @@ -64,6 +65,7 @@ public class AdvertServiceImpl implements IAdvertService { SysFile file = BeanUtil.toBean(createDTO.getExample(), SysFile.class); this.fileMapper.insert(file); Advert advert = BeanUtil.toBean(createDTO, Advert.class); + advert.setBasicSymbol(random10Str()); advert.setOnlineStatus(AdOnlineStatus.ONLINE.getValue()); advert.setExamplePicId(file.getId()); return this.advertMapper.insert(advert); @@ -222,4 +224,24 @@ public class AdvertServiceImpl implements IAdvertService { } + /** + * 随机生成10位,包含大小写字母、数字的字符串 + * @return + */ + public static String random10Str() { + final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "abcdefghijklmnopqrstuvwxyz" + + "0123456789"; + final int STRING_LENGTH = 10; + SecureRandom random = new SecureRandom(); + StringBuilder sb = new StringBuilder(STRING_LENGTH); + for (int i = 0; i < STRING_LENGTH; i++) { + int index = random.nextInt(CHARACTERS.length()); + sb.append(CHARACTERS.charAt(index)); + } + return sb.toString(); + } + + + } diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/IndexSearchServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/IndexSearchServiceImpl.java index 654284eec..4f95d0876 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/IndexSearchServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/IndexSearchServiceImpl.java @@ -8,17 +8,22 @@ import co.elastic.clients.elasticsearch.core.search.Hit; import com.github.pagehelper.PageInfo; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.page.Page; +import com.ruoyi.common.utils.DateUtils; import com.ruoyi.framework.es.EsClientWrapper; import com.ruoyi.xkt.dto.es.ESProductDTO; import com.ruoyi.xkt.dto.website.IndexSearchDTO; import com.ruoyi.xkt.service.IIndexSearchService; import lombok.RequiredArgsConstructor; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Objects; import java.util.stream.Collectors; /** @@ -58,7 +63,7 @@ public class IndexSearchServiceImpl implements IIndexSearchService { // 构建 bool 查询 BoolQuery.Builder boolQuery = new BoolQuery.Builder(); // 添加 price 范围查询 - if (searchDTO.getMinPrice() != null && searchDTO.getMaxPrice() != null) { + if (ObjectUtils.isNotEmpty(searchDTO.getMinPrice()) && ObjectUtils.isNotEmpty(searchDTO.getMaxPrice())) { RangeQuery.Builder builder = new RangeQuery.Builder(); builder.number(NumberRangeQuery.of(n -> n.field("prodPrice").gte(Double.valueOf(searchDTO.getMinPrice())) .lte(Double.valueOf(searchDTO.getMaxPrice())))); @@ -68,12 +73,21 @@ public class IndexSearchServiceImpl implements IIndexSearchService { if (StringUtils.isNotBlank(searchDTO.getSearch())) { MultiMatchQuery multiMatchQuery = MultiMatchQuery.of(m -> m .query(searchDTO.getSearch()) - .fields("prodTitle", "prodArtNum", "storeName") + .fields("prodTitle", "prodArtNum", "storeName", "prodCateName", "parCateName") ); boolQuery.must(multiMatchQuery._toQuery()); } + // 添加prodStatus 过滤条件 + if (CollectionUtils.isNotEmpty(searchDTO.getProdStatusList())) { + TermsQueryField termsQueryField = new TermsQueryField.Builder() + .value(searchDTO.getProdStatusList().stream() + .map(IndexSearchServiceImpl::newFieldValue) + .collect(Collectors.toList())) + .build(); + boolQuery.filter(f -> f.terms(t -> t.field("prodStatus").terms(termsQueryField))); + } // 添加 prodCateId 过滤条件 - if (searchDTO.getProdCateIdList() != null && !searchDTO.getProdCateIdList().isEmpty()) { + if (CollectionUtils.isNotEmpty(searchDTO.getProdCateIdList())) { TermsQueryField termsQueryField = new TermsQueryField.Builder() .value(searchDTO.getProdCateIdList().stream() .map(IndexSearchServiceImpl::newFieldValue) @@ -82,7 +96,7 @@ public class IndexSearchServiceImpl implements IIndexSearchService { boolQuery.filter(f -> f.terms(t -> t.field("prodCateId").terms(termsQueryField))); } // 添加 parCateId 过滤条件 - if (searchDTO.getParCateIdList() != null && !searchDTO.getParCateIdList().isEmpty()) { + if (CollectionUtils.isNotEmpty(searchDTO.getParCateIdList())) { TermsQueryField termsQueryField = new TermsQueryField.Builder() .value(searchDTO.getParCateIdList().stream() .map(IndexSearchServiceImpl::newFieldValue) @@ -91,7 +105,7 @@ public class IndexSearchServiceImpl implements IIndexSearchService { boolQuery.filter(f -> f.terms(t -> t.field("parCateId").terms(termsQueryField))); } // 添加 style 过滤条件 - if (searchDTO.getStyleList() != null && !searchDTO.getStyleList().isEmpty()) { + if (CollectionUtils.isNotEmpty(searchDTO.getStyleList())) { TermsQueryField termsQueryField = new TermsQueryField.Builder() .value(searchDTO.getStyleList().stream() .map(IndexSearchServiceImpl::newFieldValue) @@ -100,7 +114,7 @@ public class IndexSearchServiceImpl implements IIndexSearchService { boolQuery.filter(f -> f.terms(t -> t.field("style.keyword").terms(termsQueryField))); } // 添加 season 过滤条件 - if (searchDTO.getSeasonList() != null && !searchDTO.getSeasonList().isEmpty()) { + if (CollectionUtils.isNotEmpty(searchDTO.getSeasonList())) { TermsQueryField termsQueryField = new TermsQueryField.Builder() .value(searchDTO.getSeasonList().stream() .map(IndexSearchServiceImpl::newFieldValue) @@ -108,6 +122,20 @@ public class IndexSearchServiceImpl implements IIndexSearchService { .build(); boolQuery.filter(f -> f.terms(t -> t.field("season.keyword").terms(termsQueryField))); } + + // 如果是按照时间过滤,则表明是“新品”,则限制 时间范围 20天前到现在 + if (Objects.equals(searchDTO.getSort(), "createTime")) { + // 当前时间 + final String nowStr = DateUtils.getTime(); + // 当前时间往前推20天,获取当天的0点0分0秒 + LocalDateTime ago = LocalDateTime.now().minusDays(20).withHour(0).withMinute(0).withSecond(0); + // ago 转化为 yyyy-MM-dd HH:mm:ss + String agoStr = ago.format(DateTimeFormatter.ofPattern(DateUtils.YYYY_MM_DD_HH_MM_SS)); + RangeQuery.Builder builder = new RangeQuery.Builder(); + builder.date(DateRangeQuery.of(d -> d.field("createTime").gte(agoStr).lte(nowStr))); + boolQuery.filter(builder.build()._toQuery()); + } + // 构建最终的查询 Query query = new Query.Builder().bool(boolQuery.build()).build(); // 执行搜索 @@ -115,8 +143,12 @@ public class IndexSearchServiceImpl implements IIndexSearchService { .query(query).from(searchDTO.getPageNum() - 1).size(searchDTO.getPageSize()) .sort(sort -> sort.field(f -> f.field(searchDTO.getSort()).order(SortOrder.Desc))), ESProductDTO.class); + + System.err.println(resList); + return CollectionUtils.isEmpty(resList.hits().hits()) ? Page.empty(searchDTO.getPageSize(), searchDTO.getPageNum()) - : Page.convert(new PageInfo<>(resList.hits().hits().stream().map(Hit::source).collect(Collectors.toList()))); + : Page.convert(new PageInfo<>(resList.hits().hits().stream().map(x -> x.source().setStoreProdId(x.id())).collect(Collectors.toList()))); +// : Page.convert(new PageInfo<>(resList.hits().hits().stream().map(Hit::source).collect(Collectors.toList()))); } private static FieldValue newFieldValue(String value) { diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java index 7ee9b72be..59b92705e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreProductServiceImpl.java @@ -457,6 +457,17 @@ public class StoreProductServiceImpl implements IStoreProductService { return this.storeProdMapper.fuzzyQueryResPicList(storeId, prodArtNum); } + /** + * 获取商品所有的风格 + * + * @return List + */ + @Override + @Transactional(readOnly = true) + public List getStyleList() { + return this.storeProdMapper.getStyleList(); + } + /** * 处理档口商品属性 * diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java index df7a496d7..8967b0d74 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/StoreServiceImpl.java @@ -6,18 +6,22 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.HttpStatus; -import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.page.Page; import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.system.mapper.SysUserMapper; +import com.ruoyi.xkt.domain.DailyStoreTag; import com.ruoyi.xkt.domain.Store; +import com.ruoyi.xkt.domain.UserSubscriptions; import com.ruoyi.xkt.dto.store.*; -import com.ruoyi.xkt.dto.storeCertificate.StoreCertResDTO; import com.ruoyi.xkt.enums.StoreStatus; +import com.ruoyi.xkt.mapper.DailyStoreTagMapper; import com.ruoyi.xkt.mapper.StoreMapper; +import com.ruoyi.xkt.mapper.UserSubscriptionsMapper; import com.ruoyi.xkt.service.IStoreCertificateService; import com.ruoyi.xkt.service.IStoreService; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -27,6 +31,7 @@ import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; /** * 档口Service业务层处理 @@ -41,6 +46,8 @@ public class StoreServiceImpl implements IStoreService { final StoreMapper storeMapper; final IStoreCertificateService storeCertService; final SysUserMapper userMapper; + final DailyStoreTagMapper storeTagMapper; + final UserSubscriptionsMapper userSubMapper; /** * 注册时新增档口数据 @@ -158,6 +165,31 @@ public class StoreServiceImpl implements IStoreService { }}; } + /** + * 获取APP档口基本信息 + * + * @param storeId 档口ID + * @return StoreAppResDTO + */ + @Override + @Transactional(readOnly = true) + public StoreAppResDTO getAppInfo(Long storeId) { + Store store = Optional.ofNullable(this.storeMapper.selectOne(new LambdaQueryWrapper() + .eq(Store::getId, storeId).eq(Store::getDelFlag, Constants.UNDELETED))) + .orElseThrow(() -> new ServiceException("档口不存在!", HttpStatus.ERROR)); + // 获取档口的标签 + List storeTagList = this.storeTagMapper.selectList(new LambdaQueryWrapper() + .eq(DailyStoreTag::getStoreId, storeId).eq(DailyStoreTag::getDelFlag, Constants.UNDELETED) + .orderByAsc(DailyStoreTag::getType)); + // 判断当前用户是否已关注档口 + UserSubscriptions userSub = this.userSubMapper.selectOne(new LambdaQueryWrapper() + .eq(UserSubscriptions::getUserId, SecurityUtils.getUserId()).eq(UserSubscriptions::getStoreId, storeId) + .eq(UserSubscriptions::getDelFlag, Constants.UNDELETED)); + return BeanUtil.toBean(store, StoreAppResDTO.class) + .setAttention(ObjectUtils.isNotEmpty(userSub) ? Boolean.TRUE : Boolean.FALSE) + .setTagList(storeTagList.stream().map(DailyStoreTag::getTag).collect(Collectors.toList())); + } + /** * 修改档口基本信息 * diff --git a/xkt/src/main/resources/mapper/AdvertRoundMapper.xml b/xkt/src/main/resources/mapper/AdvertRoundMapper.xml new file mode 100644 index 000000000..ae45ce7a6 --- /dev/null +++ b/xkt/src/main/resources/mapper/AdvertRoundMapper.xml @@ -0,0 +1,24 @@ + + + + + + + \ No newline at end of file diff --git a/xkt/src/main/resources/mapper/StoreProductMapper.xml b/xkt/src/main/resources/mapper/StoreProductMapper.xml index 3933dab45..a5cd33e0a 100644 --- a/xkt/src/main/resources/mapper/StoreProductMapper.xml +++ b/xkt/src/main/resources/mapper/StoreProductMapper.xml @@ -209,4 +209,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + \ No newline at end of file