master:推广营销去掉多余的代码;
parent
3240e66b19
commit
fb9cc039e6
|
|
@ -48,13 +48,6 @@ public class AdvertRoundController extends XktBaseController {
|
|||
return R.ok(advertRoundService.create(BeanUtil.toBean(createVO, AdRoundStoreCreateDTO.class)));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')||@ss.hasSupplierSubRole()")
|
||||
@ApiOperation(value = "获取推广位数据及右侧 已订购推广位 列表", httpMethod = "GET", response = R.class)
|
||||
@GetMapping(value = "/{advertId}/{storeId}/{showType}")
|
||||
public R<AdRoundStoreResVO> getStoreAdInfo(@PathVariable("advertId") Long advertId, @PathVariable("storeId") Long storeId, @PathVariable("showType") Integer showType) {
|
||||
return R.ok(BeanUtil.toBean(advertRoundService.getStoreAdInfo(storeId, advertId, showType), AdRoundStoreResVO.class));
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasAnyRoles('admin,general_admin,store')||@ss.hasSupplierSubRole()")
|
||||
@ApiOperation(value = "获取当前推广所有轮次", httpMethod = "GET", response = R.class)
|
||||
@GetMapping(value = "/rounds/{storeId}/{typeId}")
|
||||
|
|
|
|||
|
|
@ -14,16 +14,6 @@ import java.util.List;
|
|||
*/
|
||||
public interface IAdvertRoundService {
|
||||
|
||||
/**
|
||||
* 根据广告ID获取推广轮次列表,并返回当前档口在这些推广轮次的数据
|
||||
*
|
||||
* @param storeId 档口ID
|
||||
* @param advertId 广告ID
|
||||
* @param showType 时间范围 位置枚举
|
||||
* @return AdRoundPlayStoreResDTO
|
||||
*/
|
||||
AdRoundStoreResDTO getStoreAdInfo(Long storeId, Long advertId, Integer showType);
|
||||
|
||||
/**
|
||||
* 档口购买推广营销
|
||||
*
|
||||
|
|
|
|||
|
|
@ -511,149 +511,6 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据广告ID获取推广轮次列表,并返回当前档口在这些推广轮次的数据
|
||||
*
|
||||
* @param storeId 档口ID
|
||||
* @param advertId 广告ID
|
||||
* @param showType 显示类型 时间范围 位置枚举
|
||||
* @return AdRoundPlayStoreResDTO
|
||||
*/
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public AdRoundStoreResDTO getStoreAdInfo(final Long storeId, final Long advertId, final Integer showType) {
|
||||
// 用户是否为档口管理者或子账户
|
||||
if (!SecurityUtils.isAdmin() && !SecurityUtils.isStoreManagerOrSub(storeId)) {
|
||||
throw new ServiceException("当前用户非档口管理者或子账号,无权限操作!", HttpStatus.ERROR);
|
||||
}
|
||||
final LocalTime now = LocalTime.now();
|
||||
// 当前时间 是否在 晚上22:00:00 到 晚上23:59:59之间 决定 biddingStatus 和 biddingTempStatus 用那一个字段
|
||||
boolean tenClockAfter = now.isAfter(LocalTime.of(22, 0, 0)) && now.isBefore(LocalTime.of(23, 59, 59));
|
||||
// 当天
|
||||
final Date voucherDate = java.sql.Date.valueOf(LocalDate.now());
|
||||
// 获取当前所有 正在投放 和 待投放的推广轮次
|
||||
List<AdvertRound> allRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper<AdvertRound>()
|
||||
.eq(AdvertRound::getDelFlag, Constants.UNDELETED)
|
||||
.in(AdvertRound::getLaunchStatus, Arrays.asList(AdLaunchStatus.LAUNCHING.getValue(), AdLaunchStatus.UN_LAUNCH.getValue())));
|
||||
if (CollectionUtils.isEmpty(allRoundList)) {
|
||||
return AdRoundStoreResDTO.builder().build();
|
||||
}
|
||||
// 当前 档口 在所有 待投放 及 投放中 的推广轮次竞价失败记录
|
||||
List<AdvertRoundRecord> allRecordList = this.advertRoundRecordMapper.selectList(new LambdaQueryWrapper<AdvertRoundRecord>()
|
||||
.eq(AdvertRoundRecord::getDelFlag, Constants.UNDELETED).eq(AdvertRoundRecord::getStoreId, storeId)
|
||||
.in(AdvertRoundRecord::getAdvertRoundId, allRoundList.stream().map(AdvertRound::getId).collect(Collectors.toList())));
|
||||
AdRoundStoreResDTO roundResDTO = AdRoundStoreResDTO.builder()
|
||||
// 获取档口 已抢购推广位
|
||||
.boughtRoundList(this.getStoreBoughtRecordList(allRoundList, allRecordList, storeId, voucherDate, tenClockAfter))
|
||||
.build();
|
||||
// 筛选当前 推广位 正在投放 及 待投放的推广轮次
|
||||
List<AdvertRound> advertRoundList = allRoundList.stream().filter(x -> Objects.equals(x.getAdvertId(), advertId)).collect(Collectors.toList());
|
||||
if (CollectionUtils.isEmpty(advertRoundList)) {
|
||||
return roundResDTO;
|
||||
}
|
||||
// 第一轮结束投放时间
|
||||
final Date firstRoundEndTime = advertRoundList.stream().filter(x -> x.getRoundId().equals(AdRoundType.PLAY_ROUND.getValue()))
|
||||
.max(Comparator.comparing(AdvertRound::getEndTime))
|
||||
.orElseThrow(() -> new ServiceException("获取推广结束时间失败,请联系客服!", HttpStatus.ERROR)).getEndTime();
|
||||
// 如果当前非第一轮最后一天,则展示前3轮;如果当前是第一轮最后一天,则展示第2到第4轮。
|
||||
advertRoundList = voucherDate.before(firstRoundEndTime)
|
||||
? advertRoundList.stream().filter(x -> !Objects.equals(x.getRoundId(), AdRoundType.FOURTH_ROUND.getValue())).collect(Collectors.toList())
|
||||
: advertRoundList.stream().filter(x -> !Objects.equals(x.getRoundId(), AdRoundType.PLAY_ROUND.getValue())).collect(Collectors.toList());
|
||||
// 如果投放类型是:时间范围,则只需要返回每一轮的开始时间和结束时间;如果投放类型是:位置枚举,则需要返回每一个位置的详细情况
|
||||
if (Objects.equals(showType, AdShowType.TIME_RANGE.getValue())) {
|
||||
// 有档口购买的所有轮次
|
||||
Set<Integer> roundIdSet = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice())).map(AdvertRound::getRoundId).collect(Collectors.toSet());
|
||||
// 当前档口购买的轮次
|
||||
Set<Integer> boughtIdSet = advertRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)).map(AdvertRound::getRoundId).collect(Collectors.toSet());
|
||||
// 当前档口未购买的轮次
|
||||
roundIdSet.removeAll(boughtIdSet);
|
||||
// 构建当前round基础数据
|
||||
List<AdRoundStoreResDTO.ADRSRoundTimeRangeDTO> rangeDTOList = advertRoundList.stream().map(x -> new AdRoundStoreResDTO.ADRSRoundTimeRangeDTO()
|
||||
.setAdvertId(x.getAdvertId()).setRoundId(x.getRoundId()).setSymbol(x.getSymbol()).setStartTime(x.getStartTime()).setEndTime(x.getEndTime())
|
||||
.setStartWeekDay(getDayOfWeek(x.getStartTime())).setEndWeekDay(getDayOfWeek(x.getEndTime())).setStartPrice(x.getStartPrice())
|
||||
.setDurationDay(calculateDurationDay(x.getStartTime(), x.getEndTime(), Boolean.TRUE)))
|
||||
.distinct().collect(Collectors.toList());
|
||||
// 当前档口购买的推广轮次
|
||||
Map<Integer, AdvertRound> boughtRoundMap = advertRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId))
|
||||
.collect(Collectors.toMap(AdvertRound::getRoundId, Function.identity()));
|
||||
// 未购买的推广轮次记录
|
||||
Map<Integer, AdvertRoundRecord> unBoughtRoundMap = CollectionUtils.isEmpty(roundIdSet) ? new HashMap<>()
|
||||
: allRecordList.stream().filter(x -> Objects.equals(x.getAdvertId(), advertId)
|
||||
&& Objects.equals(x.getVoucherDate(), voucherDate) && roundIdSet.contains(x.getRoundId()))
|
||||
.collect(Collectors.toMap(AdvertRoundRecord::getRoundId, Function.identity(),
|
||||
BinaryOperator.maxBy(Comparator.comparing(AdvertRoundRecord::getId))));
|
||||
|
||||
final Date date = new Date();
|
||||
// 当前最近的播放轮次
|
||||
final Integer minRoundId = advertRoundList.stream().min(Comparator.comparing(AdvertRound::getRoundId))
|
||||
.orElseThrow(() -> new ServiceException("当前播放轮次不存在!请联系客服", HttpStatus.ERROR)).getRoundId();
|
||||
// 设置当前档口在推广轮次中的数据详情
|
||||
rangeDTOList.forEach(x -> {
|
||||
// 只有播放轮才按照时间计算折扣价
|
||||
if (Objects.equals(x.getRoundId(), AdRoundType.PLAY_ROUND.getValue())) {
|
||||
// 根据当前日期与截止日期的占比修改推广价格
|
||||
final BigDecimal curStartPrice = BigDecimal.valueOf(calculateDurationDay(date, x.getEndTime(), Boolean.TRUE))
|
||||
.divide(BigDecimal.valueOf(x.getDurationDay()), 10, RoundingMode.DOWN).multiply(x.getStartPrice())
|
||||
.setScale(0, RoundingMode.DOWN);
|
||||
x.setStartPrice(curStartPrice);
|
||||
}
|
||||
// 已购买推广位轮次
|
||||
final AdvertRound boughtRound = boughtRoundMap.get(x.getRoundId());
|
||||
if (ObjectUtils.isNotEmpty(boughtRound) && ObjectUtils.isNotEmpty(boughtRound.getBiddingStatus())) {
|
||||
// 如果是最近的播放轮次,且当前时间在 晚上10:00:01 之后到 当天23:59:59 都显示 biddingTempStatus 字段
|
||||
x.setBiddingStatus(tenClockAfter && Objects.equals(x.getRoundId(), minRoundId) ? boughtRound.getBiddingTempStatus() : boughtRound.getBiddingStatus());
|
||||
x.setBiddingStatusName(AdBiddingStatus.of(boughtRound.getBiddingStatus()).getLabel());
|
||||
}
|
||||
// 未购买推广位轮次
|
||||
final AdvertRoundRecord unBought = unBoughtRoundMap.get(x.getRoundId());
|
||||
if (ObjectUtils.isNotEmpty(unBought)) {
|
||||
x.setBiddingStatus(unBought.getBiddingStatus());
|
||||
x.setBiddingStatusName(AdBiddingStatus.of(unBought.getBiddingStatus()).getLabel());
|
||||
}
|
||||
});
|
||||
return roundResDTO.setTimeRangeList(rangeDTOList);
|
||||
// 位置枚举
|
||||
} else {
|
||||
// 单纯的位置枚举 只展示一轮,主要用于:首页商品推广、下载竞价推广
|
||||
Integer minRoundId = advertRoundList.stream().min(Comparator.comparing(AdvertRound::getRoundId)).orElseThrow(() -> new ServiceException("当前播放轮次不存在!请联系客服", HttpStatus.ERROR)).getRoundId();
|
||||
// 找到roundId最小的播放轮列表
|
||||
List<AdvertRound> minRoundList = advertRoundList.stream().filter(x -> Objects.equals(x.getRoundId(), minRoundId)).collect(Collectors.toList());
|
||||
// 当前轮次所有的位置
|
||||
List<String> positionList = minRoundList.stream().map(AdvertRound::getPosition).collect(Collectors.toList());
|
||||
// 当前轮次已购买的位置
|
||||
final List<String> boughtPositionList = minRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)).map(AdvertRound::getPosition).collect(Collectors.toList());
|
||||
// 该轮次 剩下的未购买的位置
|
||||
positionList.removeAll(boughtPositionList);
|
||||
|
||||
Map<String, AdvertRoundRecord> unBoughtRecordMap = CollectionUtils.isEmpty(positionList) ? new HashMap<>()
|
||||
: allRecordList.stream().filter(x -> Objects.equals(x.getAdvertId(), advertId) && Objects.equals(x.getVoucherDate(), voucherDate)
|
||||
&& positionList.contains(x.getPosition()) && Objects.equals(x.getRoundId(), minRoundId)).collect(Collectors.toMap(AdvertRoundRecord::getPosition, Function.identity(),
|
||||
// 从unBoughtRecordList中取出每个位置最大createTime的数据,仅取一条
|
||||
BinaryOperator.maxBy(Comparator.comparing(AdvertRoundRecord::getCreateTime))));
|
||||
|
||||
List<AdRoundStoreResDTO.ADRSRoundPositionDTO> positionDTOList = minRoundList.stream().map(x -> {
|
||||
// 当前轮次有购买记录
|
||||
if (Objects.equals(x.getStoreId(), storeId)) {
|
||||
// 晚上10:00:01 之后到 当天23:59:59 都显示 biddingTempStatus 字段
|
||||
final Integer biddingStatus = tenClockAfter ? x.getBiddingTempStatus() : x.getBiddingStatus();
|
||||
return BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundPositionDTO.class).setBiddingStatus(biddingStatus)
|
||||
.setBiddingStatusName(AdBiddingStatus.of(biddingStatus).getLabel());
|
||||
}
|
||||
// 其它轮次有购买记录
|
||||
if (ObjectUtils.isNotEmpty(unBoughtRecordMap.get(x.getPosition()))) {
|
||||
return BeanUtil.toBean(unBoughtRecordMap.get(x.getPosition()), AdRoundStoreResDTO.ADRSRoundPositionDTO.class)
|
||||
.setBiddingStatusName(AdBiddingStatus.of(unBoughtRecordMap.get(x.getPosition()).getBiddingStatus()).getLabel())
|
||||
// 需要展示当前推广位置 最高的价格
|
||||
.setPayPrice(x.getPayPrice());
|
||||
}
|
||||
// 其它轮次没有购买轮次
|
||||
return BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundPositionDTO.class).setBiddingStatus(null);
|
||||
}).filter(ObjectUtils::isNotEmpty).collect(Collectors.toList());
|
||||
return roundResDTO.setPositionList(positionDTOList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 档口购买推广营销
|
||||
* 主要是两个场景:1. 某个广告位(advert_id)某个轮次(round_id)按照出价(pay_price)决定能否购买。[eg: A B C D E]
|
||||
|
|
@ -1202,87 +1059,6 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
return (int) start.until(end, ChronoUnit.DAYS) + (isContainToday ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前档口 已抢购推广位
|
||||
*
|
||||
* @param allRoundList 所有的推广
|
||||
* @param allRecordList 所有竞价失败的推广
|
||||
* @param storeId 档口ID
|
||||
* @param voucherDate 单据日期
|
||||
* @param tenClockAfter 是否是10点后
|
||||
* @return
|
||||
*/
|
||||
private List<AdRoundStoreResDTO.ADRSRoundRecordDTO> getStoreBoughtRecordList(List<AdvertRound> allRoundList, List<AdvertRoundRecord> allRecordList,
|
||||
Long storeId, Date voucherDate, boolean tenClockAfter) {
|
||||
// 按照advertId进行分组,取最小的roundId列表
|
||||
Map<Long, Optional<Integer>> minRoundIdMap = allRoundList.stream().collect(Collectors.groupingBy(AdvertRound::getAdvertId,
|
||||
Collectors.mapping(AdvertRound::getRoundId, Collectors.minBy(Comparator.comparing(Integer::intValue)))));
|
||||
// 最小的roundId列表
|
||||
List<Integer> roundIdList = minRoundIdMap.values().stream().filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
|
||||
// 筛选档口 所有的 已购买 推广位数据
|
||||
List<AdRoundStoreResDTO.ADRSRoundRecordDTO> boughtRoundList = allRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId))
|
||||
.map(x -> {
|
||||
// 如果是最近的播放轮次,且当前时间在 晚上10:00:01 之后到 当天23:59:59 都显示 biddingTempStatus 字段
|
||||
final Integer biddingStatus = tenClockAfter && roundIdList.contains(x.getRoundId()) ? x.getBiddingTempStatus() : x.getBiddingStatus();
|
||||
return BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setBiddingStatus(biddingStatus)
|
||||
.setBiddingStatusName(AdBiddingStatus.of(biddingStatus).getLabel())
|
||||
.setTypeName(AdType.of(x.getTypeId()).getLabel())
|
||||
// 如果是时间范围则不返回position
|
||||
.setPosition(Objects.equals(x.getShowType(), AdShowType.TIME_RANGE.getValue()) ? null : x.getPosition());
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
// showType 为 时间范围的 每一轮最高的出价map
|
||||
Map<Integer, BigDecimal> timeRangeRoundMaxPriceMap = allRoundList.stream()
|
||||
.filter(x -> Objects.equals(x.getShowType(), AdShowType.TIME_RANGE.getValue()))
|
||||
.filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice()))
|
||||
.collect(Collectors
|
||||
.groupingBy(AdvertRound::getRoundId, Collectors
|
||||
.mapping(AdvertRound::getPayPrice, Collectors.reducing(BigDecimal.ZERO, BigDecimal::max))));
|
||||
// showType 为 位置枚举的 每一个位置最高出价的 map
|
||||
Map<Long, BigDecimal> positionEnumMaxPriceMap = allRoundList.stream()
|
||||
.filter(x -> Objects.equals(x.getShowType(), AdShowType.POSITION_ENUM.getValue()))
|
||||
.filter(x -> ObjectUtils.isNotEmpty(x.getPayPrice()))
|
||||
.collect(Collectors.toMap(AdvertRound::getId, AdvertRound::getPayPrice));
|
||||
// 已购买的 时间范围播放轮次 的roundId列表
|
||||
final List<Integer> boughtTimeRangeRoundIdList = boughtRoundList.stream().filter(x -> Objects.equals(x.getShowType(), AdShowType.TIME_RANGE.getValue()))
|
||||
.map(AdRoundStoreResDTO.ADRSRoundRecordDTO::getRoundId).collect(Collectors.toList());
|
||||
// 已购买的 位置枚举 的 advertRoundId 列表
|
||||
final List<Long> boughtPositionAdvertRoundIdList = boughtRoundList.stream().filter(x -> Objects.equals(x.getShowType(), AdShowType.POSITION_ENUM.getValue()))
|
||||
.map(AdRoundStoreResDTO.ADRSRoundRecordDTO::getAdvertRoundId).collect(Collectors.toList());
|
||||
// 购买失败的 时间范围播放轮次的 列表
|
||||
Map<Integer, AdvertRoundRecord> unBoughtTimeRangeMap = allRecordList.stream()
|
||||
.filter(x -> Objects.equals(x.getShowType(), AdShowType.TIME_RANGE.getValue()))
|
||||
.filter(x -> !boughtTimeRangeRoundIdList.contains(x.getRoundId()))
|
||||
.filter(x -> Objects.equals(x.getVoucherDate(), voucherDate))
|
||||
.collect(Collectors.toMap(AdvertRoundRecord::getRoundId, Function.identity(),
|
||||
BinaryOperator.maxBy(Comparator.comparingLong(AdvertRoundRecord::getId))));
|
||||
// 购买失败的 位置枚举播放轮次的 列表
|
||||
Map<Long, AdvertRoundRecord> unBoughtPositionMap = allRecordList.stream()
|
||||
.filter(x -> Objects.equals(x.getShowType(), AdShowType.POSITION_ENUM.getValue()))
|
||||
.filter(x -> !boughtPositionAdvertRoundIdList.contains(x.getAdvertRoundId()))
|
||||
.filter(x -> Objects.equals(x.getVoucherDate(), voucherDate))
|
||||
.collect(Collectors.toMap(AdvertRoundRecord::getAdvertRoundId, Function.identity(),
|
||||
BinaryOperator.maxBy(Comparator.comparingLong(AdvertRoundRecord::getId))));
|
||||
if (MapUtils.isNotEmpty(unBoughtTimeRangeMap)) {
|
||||
unBoughtTimeRangeMap.forEach((roundId, record) -> {
|
||||
boughtRoundList.add(BeanUtil.toBean(record, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setPosition(null)
|
||||
.setTypeName(AdType.of(record.getTypeId()).getLabel())
|
||||
.setBiddingStatusName(AdBiddingStatus.of(record.getBiddingStatus()).getLabel()
|
||||
+ ",最新出价:" + timeRangeRoundMaxPriceMap.get(record.getRoundId())));
|
||||
});
|
||||
}
|
||||
if (MapUtils.isNotEmpty(unBoughtPositionMap)) {
|
||||
unBoughtPositionMap.forEach((advertRoundId, record) -> {
|
||||
boughtRoundList.add(BeanUtil.toBean(record, AdRoundStoreResDTO.ADRSRoundRecordDTO.class)
|
||||
.setTypeName(AdType.of(record.getTypeId()).getLabel())
|
||||
.setBiddingStatusName(AdBiddingStatus.of(record.getBiddingStatus()).getLabel()
|
||||
+ ",最新出价:" + positionEnumMaxPriceMap.get(record.getAdvertRoundId()))
|
||||
);
|
||||
});
|
||||
}
|
||||
return boughtRoundList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 购买人手机号中国部分用*号代替
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue