From f130cd708e71af7cb21100cc5e3e59c85e6a724a Mon Sep 17 00:00:00 2001 From: liujiang <569804566@qq.com> Date: Fri, 9 May 2025 19:53:26 +0800 Subject: [PATCH] =?UTF-8?q?master=EF=BC=9A=E6=8E=A8=E5=B9=BF=E8=90=A5?= =?UTF-8?q?=E9=94=80=E8=BD=AE=E6=AC=A1=E8=8E=B7=E5=8F=96=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=B0=83=E4=BC=98=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xkt/StoreProductController.java | 8 +- .../xkt/vo/advertRound/AdRoundStoreResVO.java | 14 +- .../ruoyi/xkt/domain/AdvertRoundRecord.java | 8 + .../dto/advertRound/AdRoundStoreResDTO.java | 16 +- .../dto/storeProduct/StoreProdPageResDTO.java | 4 +- .../com/ruoyi/xkt/enums/AdBiddingStatus.java | 6 +- .../service/impl/AdvertRoundServiceImpl.java | 141 +++++++++++++++--- 7 files changed, 150 insertions(+), 47 deletions(-) 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 8552fb58c..daa9ac0e9 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 @@ -51,7 +51,7 @@ public class StoreProductController extends XktBaseController { /** * 模糊查询档口商品 */ - @PreAuthorize("@ss.hasPermi('system:product:query')") +// @PreAuthorize("@ss.hasPermi('system:product:query')") @ApiOperation(value = "模糊查询档口商品", httpMethod = "GET", response = R.class) @GetMapping(value = "/fuzzy") public R> fuzzyQueryColorList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum, @@ -62,7 +62,7 @@ public class StoreProductController extends XktBaseController { /** * 模糊查询档口商品 */ - @PreAuthorize("@ss.hasPermi('system:product:query')") +// @PreAuthorize("@ss.hasPermi('system:product:query')") @ApiOperation(value = "模糊查询档口商品", httpMethod = "GET", response = R.class) @GetMapping(value = "/fuzzy/pic") public R> fuzzyQueryResPicList(@RequestParam(value = "prodArtNum", required = false) String prodArtNum, @@ -74,7 +74,7 @@ public class StoreProductController extends XktBaseController { /** * 查询档口商品列表 */ - @PreAuthorize("@ss.hasPermi('system:product:list')") +// @PreAuthorize("@ss.hasPermi('system:product:list')") @ApiOperation(value = "查询档口商品列表", httpMethod = "POST", response = R.class) @PostMapping("/page") public R> page(@Validated @RequestBody StoreProdPageVO pageVO) { @@ -84,7 +84,7 @@ public class StoreProductController extends XktBaseController { /** * 获取档口商品详细信息 */ - @PreAuthorize("@ss.hasPermi('system:product:query')") +// @PreAuthorize("@ss.hasPermi('system:product:query')") @ApiOperation(value = "获取档口商品详细信息", httpMethod = "GET", response = R.class) @GetMapping(value = "/detail/{storeProdId}") public R getInfo(@PathVariable("storeProdId") Long storeProdId) { diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java index a226ee2cc..882ee908d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRound/AdRoundStoreResVO.java @@ -57,8 +57,6 @@ public class AdRoundStoreResVO { private Integer biddingStatus; @ApiModelProperty(value = "竞价状态名称") private String biddingStatusName; - @ApiModelProperty(value = "竞价结果描述") - private String biddingStatusStr; } @Data @@ -88,19 +86,21 @@ public class AdRoundStoreResVO { @ApiModelProperty(value = "广告ID") private Long advertId; @ApiModelProperty(value = "广告轮次ID") - private Long roundId; + private Integer roundId; @ApiModelProperty(value = "广告类型ID") private Integer typeId; + @ApiModelProperty(value = "广告类型名称") + private String typeName; @ApiModelProperty(value = "推广档口ID") private Long storeId; @ApiModelProperty(value = "对象锁符号") private String symbol; - @ApiModelProperty(value = "广告类型名称") - private String typeName; @ApiModelProperty(value = "广告位置 A B C D E") private String position; - @ApiModelProperty(value = "竞价结果描述") - private String biddingStr; + @ApiModelProperty(value = "竞价状态") + private Integer biddingStatus; + @ApiModelProperty(value = "竞价状态名称及描述") + private String biddingStatusName; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java index 66953c363..9c16ea9fd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundRecord.java @@ -39,6 +39,10 @@ public class AdvertRoundRecord extends XktBaseEntity { * 广告ID */ private Long advertId; + /** + * 推广类型 + */ + private Integer typeId; /** * 轮次ID */ @@ -67,6 +71,10 @@ public class AdvertRoundRecord extends XktBaseEntity { * 推广档口ID */ private Long storeId; + /** + * 起拍价格 + */ + private BigDecimal startPrice; /** * 推广档口出价 */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java index 11170998a..ac47ee4f0 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRound/AdRoundStoreResDTO.java @@ -61,8 +61,6 @@ public class AdRoundStoreResDTO { private Integer biddingStatus; @ApiModelProperty(value = "竞价状态名称") private String biddingStatusName; - @ApiModelProperty(value = "竞价结果描述") - private String biddingStatusStr; } @Data @@ -73,7 +71,7 @@ public class AdRoundStoreResDTO { @ApiModelProperty(value = "广告ID") private Long advertId; @ApiModelProperty(value = "广告轮次ID") - private Long roundId; + private Integer roundId; @ApiModelProperty(value = "typeId") private Integer typeId; @ApiModelProperty(value = "广告位置 A B C D E") @@ -92,19 +90,21 @@ public class AdRoundStoreResDTO { @ApiModelProperty(value = "广告ID") private Long advertId; @ApiModelProperty(value = "广告轮次ID") - private Long roundId; + private Integer roundId; @ApiModelProperty(value = "广告类型ID") private Integer typeId; + @ApiModelProperty(value = "广告类型名称") + private String typeName; @ApiModelProperty(value = "推广档口ID") private Long storeId; @ApiModelProperty(value = "对象锁符号") private String symbol; - @ApiModelProperty(value = "广告类型名称") - private String typeName; @ApiModelProperty(value = "广告位置 A B C D E") private String position; - @ApiModelProperty(value = "竞价结果描述") - private String biddingStr; + @ApiModelProperty(value = "竞价状态") + private Integer biddingStatus; + @ApiModelProperty(value = "竞价状态名称及描述") + private String biddingStatusName; } diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPageResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPageResDTO.java index 7700b17b8..80334a7e4 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPageResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/storeProduct/StoreProdPageResDTO.java @@ -1,6 +1,7 @@ package com.ruoyi.xkt.dto.storeProduct; import com.fasterxml.jackson.annotation.JsonFormat; +import com.ruoyi.common.annotation.Excel; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -30,9 +31,8 @@ public class StoreProdPageResDTO { private String prodArtNum; @ApiModelProperty(value = "颜色") private String colorName; - + @ApiModelProperty(name = "商品分类ID") private Long prodCateId; - @ApiModelProperty(value = "分类类目") private String prodCateName; @ApiModelProperty(value = "标准尺码") diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java index 49e31bd50..9aa595ed1 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java @@ -14,10 +14,10 @@ public enum AdBiddingStatus { // 已出价 BIDDING(1, "已出价"), - // 竞价失败 - BIDDING_FAIL(2, "竞价失败"), // 竞价成功 - BIDDING_SUCCESS(3, "竞价成功"), + BIDDING_SUCCESS(2, "竞价成功"), + // 竞价失败 + BIDDING_FAIL(3, "竞价失败"), ; 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 index 7c9020fd7..3422267bb 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundServiceImpl.java @@ -5,6 +5,7 @@ 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.enums.AdType; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.xkt.domain.AdvertRound; @@ -146,15 +147,6 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { } - /** - * 根据广告ID获取推广轮次列表,并返回当前档口在这些推广轮次的数据 - * - * @param storeId 档口ID - * @param advertId 推广ID - * @param typeId 类型ID - * @return AdRoundPlayStoreResDTO - */ - /** * 根据广告ID获取推广轮次列表,并返回当前档口在这些推广轮次的数据 * @@ -184,6 +176,18 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { advertRoundList = voucherDate.before(firstRoundEndTime) ? advertRoundList.stream().filter(x -> !Objects.equals(x.getRoundId(), AdRoundType.FIFTH_ROUND.getValue())).collect(Collectors.toList()) : advertRoundList.stream().filter(x -> !Objects.equals(x.getRoundId(), AdRoundType.PLAY_ROUND.getValue())).collect(Collectors.toList()); + // 有档口购买的所有轮次 + Set roundIdSet = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).map(AdvertRound::getRoundId).collect(Collectors.toSet()); + // 当前档口购买的轮次 + Set boughtIdSet = advertRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)).map(AdvertRound::getRoundId).collect(Collectors.toSet()); + // 当前档口未购买的轮次 + roundIdSet.removeAll(boughtIdSet); + List recordList = CollectionUtils.isNotEmpty(roundIdSet) + ? this.advertRoundRecordMapper.selectRecordList(advertId, storeId, voucherDate, roundIdSet) : new ArrayList<>(); + + // 获取已抢购推广位列表 + AdRoundStoreResDTO roundResDTO = AdRoundStoreResDTO.builder().recordList(this.getStoreBoughtList(storeId, advertRoundList, recordList)).build(); + // 如果投放类型是:时间范围,则只需要返回每一轮的开始时间和结束时间;如果投放类型是:位置枚举,则需要返回每一个位置的详细情况 if (Objects.equals(showType, AdShowType.TIME_RANGE.getValue())) { // 构建当前round基础数据 @@ -195,16 +199,17 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { // 当前档口购买的推广轮次 Map boughtRoundMap = advertRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)) .collect(Collectors.toMap(AdvertRound::getRoundId, Function.identity())); - // 所有的轮次 - Set roundIdSet = advertRoundList.stream().map(AdvertRound::getRoundId).collect(Collectors.toSet()); + /*// 所有的轮次 + Set roundIdSet = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).map(AdvertRound::getRoundId).collect(Collectors.toSet());*/ // 未购买的轮次 = 所有的轮次 - 已购买轮次 - roundIdSet.removeAll(boughtRoundMap.keySet()); - Map recordMap = new ConcurrentHashMap<>(); +// roundIdSet.removeAll(boughtRoundMap.keySet()); + + Map unBoughtRoundMap = recordList.stream().collect(Collectors.toConcurrentMap(AdvertRoundRecord::getRoundId, Function.identity())); // 有未购买轮次,则查找未购买轮次是否有竞价 - if (CollectionUtils.isNotEmpty(roundIdSet)) { - List recordList = this.advertRoundRecordMapper.selectRecordList(advertId, storeId, voucherDate, roundIdSet); - Optional.ofNullable(recordList).ifPresent(list -> list.forEach(x -> recordMap.put(x.getRoundId(), x))); - } +// if (CollectionUtils.isNotEmpty(roundIdSet)) { +// List recordList = this.advertRoundRecordMapper.selectRecordList(advertId, storeId, voucherDate, roundIdSet); +// Optional.ofNullable(recordList).ifPresent(list -> list.forEach(x -> unBoughtRoundMap.put(x.getRoundId(), x))); +// } final Date date = new Date(); // 设置当前档口在推广轮次中的数据详情 rangeDTOList.forEach(x -> { @@ -223,19 +228,30 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { x.setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(boughtRound.getBiddingStatus())).getLabel()); } // 未购买推广位轮次 - final AdvertRoundRecord record = recordMap.get(x.getRoundId()); - if (ObjectUtils.isNotEmpty(record)) { - x.setBiddingStatus(record.getBiddingStatus()); - x.setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(record.getBiddingStatus())).getLabel()); + final AdvertRoundRecord unBought = unBoughtRoundMap.get(x.getRoundId()); + if (ObjectUtils.isNotEmpty(unBought)) { + x.setBiddingStatus(unBought.getBiddingStatus()); + x.setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(unBought.getBiddingStatus())).getLabel()); } }); - return AdRoundStoreResDTO.builder().timeRangeList(rangeDTOList).build(); + return roundResDTO.setTimeRangeList(rangeDTOList); } else { // 位置枚举 - + } + + + + + // 已抢购推广列表 显示单据日期大于等于当天的数据 针对某一轮 如果抢购成功了,则这一轮所以失败的记录都不显示。如果未来的某一轮:已出价或者竞价失败有多次,则只显示最新的那一条数据。 + // 如果是已出价,要显示最新出价。如果是竞价失败,要显示最新的价格 + + // 针对当前播放轮,如果竞价成功,则显示。就算是当前轮最后一天 也要显示 竞价成功 + + + // 写 sql 从advertRound中获取 advertId 和 roundId 最高的价格 /* Map otherRoundMaxPriceMap = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())) .filter(x -> remainRoundIdList.contains(x.getRoundId())) @@ -265,6 +281,7 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { } + /** * 档口购买推广营销 * 主要是两个场景:1. 某个广告位(advert_id)某个轮次(round_id)按照出价(pay_price)决定能否购买。[eg: A B C D E] @@ -340,6 +357,84 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService { return 1; } + /** + * 获取已抢购推广位列表 + * + * @param storeId 档口ID + * @param advertRoundList 播放轮次列表 + * @param recordList 未购买的播放轮次列表 + * @return List + */ + private List getStoreBoughtList(Long storeId, List advertRoundList, List recordList) { + /*// 每一轮最高的出价map + Map maxBidMap = advertRoundList.stream() + .filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).collect(Collectors + .groupingBy(AdvertRound::getRoundId, Collectors + .mapping(AdvertRound::getPayPrice, Collectors.reducing(BigDecimal.ZERO, BigDecimal::max)))); + // 先处理 已抢购广告位列表,此处不用管 播放的轮次 统一展示前4轮的结果 + List boughtRoundList = advertRoundList.stream() + .filter(x -> !Objects.equals(x.getRoundId(), AdRoundType.FIFTH_ROUND.getValue())) + .filter(x -> Objects.equals(x.getStoreId(), storeId)) + .map(x -> BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class) + .setTypeName(Objects.requireNonNull(AdType.of(x.getTypeId())).getLabel()) + .setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(x.getBiddingStatus())).getLabel())) + .collect(Collectors.toList()); + // 所有有档口出价的轮次 + Set roundIdSet = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).map(AdvertRound::getRoundId).collect(Collectors.toSet()); + Set boughtRoundIdSet = boughtRoundList.stream().map(AdRoundStoreResDTO.ADRSRoundRecordDTO::getRoundId).collect(Collectors.toSet()); + // 抢购记录当前档口未购买的轮次 + roundIdSet.removeAll(boughtRoundIdSet); + // 查询其它轮次是否有购买记录 + if (CollectionUtils.isEmpty(roundIdSet)) { + return boughtRoundList; + } + List recordList = this.advertRoundRecordMapper.selectRecordList(advertId, storeId, voucherDate, roundIdSet); + if (CollectionUtils.isEmpty(recordList)) { + return boughtRoundList; + } + boughtRoundList.addAll(recordList.stream().sorted(Comparator.comparing(AdvertRoundRecord::getBiddingStatus)) + .map(x -> BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setTypeName(Objects.requireNonNull(AdType.of(x.getTypeId())).getLabel()) + .setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(x.getBiddingStatus())).getLabel() + ",最新出价:" + maxBidMap.get(x.getRoundId()))) + .collect(Collectors.toList()));*/ + + + + + // 每一轮最高的出价map + Map maxBidMap = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).collect(Collectors + .groupingBy(AdvertRound::getRoundId, Collectors + .mapping(AdvertRound::getPayPrice, Collectors.reducing(BigDecimal.ZERO, BigDecimal::max)))); + + // 先处理 已抢购广告位列表,此处不用管 播放的轮次 统一展示前4轮的结果 + List boughtRoundList = advertRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)) + .map(x -> BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setTypeName(Objects.requireNonNull(AdType.of(x.getTypeId())).getLabel()) + .setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(x.getBiddingStatus())).getLabel())) + .collect(Collectors.toList()); + + + + // 所有有档口出价的轮次 +// Set roundIdSet = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).map(AdvertRound::getRoundId).collect(Collectors.toSet()); + +// Set boughtRoundIdSet = boughtRoundList.stream().map(AdRoundStoreResDTO.ADRSRoundRecordDTO::getRoundId).collect(Collectors.toSet()); + // 抢购记录当前档口未购买的轮次 +// roundIdSet.removeAll(boughtRoundIdSet); + // 查询其它轮次是否有购买记录 + if (CollectionUtils.isEmpty(recordList)) { + return boughtRoundList; + } +// List recordList = this.advertRoundRecordMapper.selectRecordList(advertId, storeId, voucherDate, unBoughtRoundIdSet); +// if (CollectionUtils.isEmpty(recordList)) { +// return boughtRoundList; +// } + boughtRoundList.addAll(recordList.stream().sorted(Comparator.comparing(AdvertRoundRecord::getBiddingStatus)) + .map(x -> BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setTypeName(Objects.requireNonNull(AdType.of(x.getTypeId())).getLabel()) + .setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(x.getBiddingStatus())).getLabel() + ",最新出价:" + maxBidMap.get(x.getRoundId()))) + .collect(Collectors.toList())); + return boughtRoundList; + } + + /** * 通过定时任务往redis中放当前推广位 当前播放轮 或 即将播放轮 的截止时间; * 比如:5.1 - 5.3