master:推广营销逻辑优化;
parent
9d7c2fcabb
commit
e1e5135a1f
|
|
@ -23,6 +23,8 @@ public class AdRoundTypeRoundBoughtResVO {
|
|||
private Long advertId;
|
||||
@ApiModelProperty(value = "广告轮次ID")
|
||||
private Integer roundId;
|
||||
@ApiModelProperty(value = "是否可购买")
|
||||
private Boolean canPurchased;
|
||||
@ApiModelProperty(value = "typeId")
|
||||
private Integer typeId;
|
||||
@ApiModelProperty(value = "广告位置 A B C D E")
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ public class AdRoundTypeRoundResVO {
|
|||
private Long advertId;
|
||||
@ApiModelProperty(value = "广告轮次ID")
|
||||
private Integer roundId;
|
||||
@ApiModelProperty(value = "是否可购买 true:可购买 false:不可购买")
|
||||
private Boolean canPurchased;
|
||||
@ApiModelProperty(value = "展示类型")
|
||||
private Integer showType;
|
||||
@ApiModelProperty(value = "广告位置 A B C D E")
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ public class XktTask {
|
|||
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).setStartPrice(advert.getStartPrice())
|
||||
.setSysIntercept(AdSysInterceptType.UN_INTERCEPT.getValue()).setShowType(advert.getShowType())
|
||||
.setDisplayType(advert.getDisplayType()).setDeadline(advert.getDeadline())
|
||||
.setDisplayType(advert.getDisplayType()).setDeadline(advert.getDeadline()).setBiddingStatus(AdBiddingStatus.UN_BIDDING.getValue())
|
||||
.setSymbol(Objects.equals(advert.getShowType(), AdShowType.POSITION_ENUM.getValue())
|
||||
// 如果是位置枚举的推广位,则需要精确到某一个position的推广位,反之,若是时间范围,则直接精确到播放轮次即可
|
||||
? advert.getBasicSymbol() + roundId + position : advert.getBasicSymbol() + roundId));
|
||||
|
|
@ -1689,7 +1689,7 @@ public class XktTask {
|
|||
.setSysIntercept(AdSysInterceptType.UN_INTERCEPT.getValue()).setShowType(advert.getShowType()).setDisplayType(advert.getDisplayType())
|
||||
.setStartTime(Date.from(startDate.atStartOfDay(ZoneId.systemDefault()).toInstant()))
|
||||
.setEndTime(Date.from(endDate.atStartOfDay(ZoneId.systemDefault()).toInstant()))
|
||||
.setDeadline(advert.getDeadline())
|
||||
.setDeadline(advert.getDeadline()).setBiddingStatus(AdBiddingStatus.UN_BIDDING.getValue())
|
||||
.setSymbol(Objects.equals(advert.getShowType(), AdShowType.POSITION_ENUM.getValue())
|
||||
// 如果是位置枚举的推广位,则需要精确到某一个position的推广位,反之,若是时间范围,则直接精确到播放轮次即可
|
||||
? advert.getBasicSymbol() + maxRoundId + position : advert.getBasicSymbol() + maxRoundId);
|
||||
|
|
|
|||
|
|
@ -97,9 +97,9 @@ CREATE TABLE `advert_round`
|
|||
`store_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '档口ID',
|
||||
`start_price` decimal(10, 2) UNSIGNED NOT NULL COMMENT '起始竞价价格',
|
||||
`pay_price` decimal(10, 2) UNSIGNED NULL DEFAULT NULL COMMENT '档口出价',
|
||||
`bidding_status` int UNSIGNED NULL DEFAULT NULL COMMENT '竞价状态 最初是:已出价 之后会变成 竞价成功',
|
||||
`bidding_temp_status` int UNSIGNED NULL DEFAULT NULL COMMENT '竞价成功',
|
||||
`reject_reason` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '审核驳回理由',
|
||||
`bidding_status` int UNSIGNED NULL DEFAULT NULL COMMENT '竞价状态 最初是:已出价 之后会变成 竞价成功',
|
||||
`pic_audit_status` int UNSIGNED NULL DEFAULT NULL COMMENT '图片审核状态(待审核、审核通过、审核驳回)',
|
||||
`pic_set_type` int UNSIGNED NULL DEFAULT NULL COMMENT '图片是否已设置',
|
||||
`pic_id` bigint UNSIGNED NULL DEFAULT NULL COMMENT '图片ID',
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ public class AdRoundTypeRoundBoughtResDTO {
|
|||
private Long advertRoundId;
|
||||
@ApiModelProperty(value = "广告ID")
|
||||
private Long advertId;
|
||||
@ApiModelProperty(value = "是否可购买")
|
||||
private Boolean canPurchased;
|
||||
@ApiModelProperty(value = "广告轮次ID")
|
||||
private Integer roundId;
|
||||
@ApiModelProperty(value = "typeId")
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ public class AdRoundTypeRoundResDTO {
|
|||
private Long advertId;
|
||||
@ApiModelProperty(value = "广告轮次ID")
|
||||
private Integer roundId;
|
||||
@ApiModelProperty(value = "是否可购买")
|
||||
private Boolean canPurchased;
|
||||
@ApiModelProperty(value = "展示类型")
|
||||
private Integer showType;
|
||||
@ApiModelProperty(value = "广告位置 A B C D E")
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import lombok.Getter;
|
|||
@AllArgsConstructor
|
||||
public enum AdBiddingStatus {
|
||||
|
||||
// 未出价
|
||||
UN_BIDDING(0, "未出价"),
|
||||
// 已出价
|
||||
BIDDING(1, "已出价"),
|
||||
// 竞价成功
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import com.ruoyi.xkt.service.IAssetService;
|
|||
import lombok.RequiredArgsConstructor;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.RandomUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -249,10 +248,6 @@ public class AdminAdvertRoundServiceImpl implements IAdminAdvertRoundService {
|
|||
if (ObjectUtils.isNotEmpty(interceptDTO.getStoreProdIdList())) {
|
||||
advertRound.setProdIdStr(StringUtils.join(interceptDTO.getStoreProdIdList(), ","));
|
||||
}
|
||||
// 如果是位置枚举,则设置一个很高的价格(100 - 200)范围,有其它档口愿意出更高价格拿下就随他去
|
||||
if (Objects.equals(advertRound.getShowType(), AdShowType.POSITION_ENUM.getValue())) {
|
||||
advertRound.setPayPrice(BigDecimal.valueOf(RandomUtils.nextLong(10, 20 + 1) * 10));
|
||||
}
|
||||
return this.advertRoundMapper.updateById(advertRound);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -221,13 +221,19 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
List<AdRoundTypeRoundResDTO> resList = new ArrayList<>();
|
||||
final Date date = new Date();
|
||||
advertRoundList.stream().collect(Collectors.groupingBy(AdvertRound::getRoundId))
|
||||
.forEach((roundId, list) -> {
|
||||
AdvertRound advertRound = list.get(0);
|
||||
.forEach((roundId, currentRoundList) -> {
|
||||
AdvertRound advertRound = currentRoundList.get(0);
|
||||
Integer durationDay = calculateDurationDay(advertRound.getStartTime(), advertRound.getEndTime(), Boolean.TRUE);
|
||||
AdRoundTypeRoundResDTO typeRoundResDTO = new AdRoundTypeRoundResDTO().setAdvertId(advertRound.getAdvertId()).setRoundId(advertRound.getRoundId())
|
||||
.setSymbol(advertRound.getSymbol()).setLaunchStatus(advertRound.getLaunchStatus()).setStartTime(advertRound.getStartTime())
|
||||
.setEndTime(advertRound.getEndTime()).setStartWeekDay(getDayOfWeek(advertRound.getStartTime())).setDurationDay(durationDay)
|
||||
.setEndWeekDay(getDayOfWeek(advertRound.getEndTime())).setShowType(advertRound.getShowType()).setPosition(advertRound.getPosition());
|
||||
.setCanPurchased(Boolean.TRUE).setEndWeekDay(getDayOfWeek(advertRound.getEndTime()))
|
||||
.setShowType(advertRound.getShowType()).setPosition(advertRound.getPosition());
|
||||
// 如果是播放论,并且是否全部为 BIDDING_SUCCESS,若是 则不可购买当前轮次(就算是当前档口购买的,biddingStatus也为2,也将标识置为false)
|
||||
if (Objects.equals(roundId, AdRoundType.PLAY_ROUND.getValue())
|
||||
&& currentRoundList.stream().allMatch(x -> Objects.equals(x.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue()))) {
|
||||
typeRoundResDTO.setCanPurchased(Boolean.FALSE);
|
||||
}
|
||||
// 如果是播放论,则播放开始时间展示为当天,因为有可能是播放的中间某一天
|
||||
if (Objects.equals(advertRound.getRoundId(), AdRoundType.PLAY_ROUND.getValue())) {
|
||||
Date tomorrow = Date.from(LocalDate.now().plusDays(1).atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||
|
|
@ -248,7 +254,7 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
typeRoundResDTO.setStartPrice(curStartPrice);
|
||||
}
|
||||
// 当前档口购买的轮次
|
||||
AdvertRound boughtRound = list.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)).findFirst().orElse(null);
|
||||
AdvertRound boughtRound = currentRoundList.stream().filter(x -> Objects.equals(x.getStoreId(), storeId)).findFirst().orElse(null);
|
||||
if (ObjectUtils.isNotEmpty(boughtRound)) {
|
||||
// 如果是最近的播放轮次,且当前时间在 晚上10:00:01 之后到 当天23:59:59 都显示 biddingTempStatus 字段
|
||||
Integer biddingStatus = tenClockAfter && Objects.equals(typeRoundResDTO.getRoundId(), minRoundId)
|
||||
|
|
@ -293,10 +299,15 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
boolean tenClockAfter = now.isAfter(LocalTime.of(22, 0, 0)) && now.isBefore(LocalTime.of(23, 59, 59));
|
||||
final Date date = new Date();
|
||||
List<AdRoundTypeRoundBoughtResDTO> resList = advertRoundList.stream().map(advertRound -> {
|
||||
AdRoundTypeRoundBoughtResDTO bought = new AdRoundTypeRoundBoughtResDTO().setTypeId(advertRound.getTypeId()).setAdvertRoundId(advertRound.getId())
|
||||
AdRoundTypeRoundBoughtResDTO boughtResDTO = new AdRoundTypeRoundBoughtResDTO().setTypeId(advertRound.getTypeId()).setAdvertRoundId(advertRound.getId())
|
||||
.setAdvertId(advertRound.getAdvertId()).setRoundId(advertRound.getRoundId()).setPosition(advertRound.getPosition())
|
||||
.setStartPrice(advertRound.getStartPrice()).setPayPrice(advertRound.getPayPrice()).setStoreId(storeId).setLaunchStatus(advertRound.getLaunchStatus())
|
||||
.setStartTime(advertRound.getStartTime()).setEndTime(advertRound.getEndTime()).setSymbol(advertRound.getSymbol());
|
||||
// 如果是播放论,并且是否全部为 BIDDING_SUCCESS,若是 则不可购买当前轮次(就算是当前档口购买的,biddingStatus也为2,也将标识置为false)
|
||||
if (Objects.equals(advertRound.getRoundId(), AdRoundType.PLAY_ROUND.getValue())
|
||||
&& Objects.equals(advertRound.getBiddingStatus(), AdBiddingStatus.BIDDING_SUCCESS.getValue())) {
|
||||
boughtResDTO.setCanPurchased(Boolean.FALSE);
|
||||
}
|
||||
// 如果当前位置没有档口购买,且为第一轮 则需按照剩余时间比例进行减价
|
||||
if (ObjectUtils.isEmpty(advertRound.getStoreId()) && Objects.equals(advertRound.getRoundId(), AdRoundType.PLAY_ROUND.getValue())) {
|
||||
Integer durationDay = calculateDurationDay(advertRound.getStartTime(), advertRound.getEndTime(), Boolean.TRUE);
|
||||
|
|
@ -304,15 +315,15 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
BigDecimal numerator = BigDecimal.valueOf(calculateDurationDay(date, advertRound.getEndTime(), Boolean.FALSE));
|
||||
BigDecimal curStartPrice = numerator.multiply(advertRound.getStartPrice())
|
||||
.divide(BigDecimal.valueOf(durationDay), 0, RoundingMode.HALF_UP);
|
||||
bought.setStartPrice(curStartPrice);
|
||||
boughtResDTO.setStartPrice(curStartPrice);
|
||||
}
|
||||
// 当前档口购买的推广位置
|
||||
if (Objects.equals(advertRound.getStoreId(), storeId)) {
|
||||
Integer biddingStatus = tenClockAfter ? advertRound.getBiddingTempStatus() : advertRound.getBiddingStatus();
|
||||
bought.setBiddingStatus(biddingStatus);
|
||||
bought.setBiddingStatusName(AdBiddingStatus.of(biddingStatus).getLabel());
|
||||
boughtResDTO.setBiddingStatus(biddingStatus);
|
||||
boughtResDTO.setBiddingStatusName(AdBiddingStatus.of(biddingStatus).getLabel());
|
||||
}
|
||||
return bought;
|
||||
return boughtResDTO;
|
||||
}).collect(Collectors.toList());
|
||||
// 档口未竞价成功的位置
|
||||
List<String> unBoughtPositionList = advertRoundList.stream().filter(x -> ObjectUtils.isNotEmpty(x.getStoreId()) && !Objects.equals(x.getStoreId(), storeId))
|
||||
|
|
@ -637,6 +648,7 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
}
|
||||
LambdaQueryWrapper<AdvertRound> queryWrapper = new LambdaQueryWrapper<AdvertRound>()
|
||||
.eq(AdvertRound::getAdvertId, createDTO.getAdvertId()).eq(AdvertRound::getRoundId, createDTO.getRoundId())
|
||||
.in(AdvertRound::getBiddingStatus, Arrays.asList(AdBiddingStatus.BIDDING.getValue(), AdBiddingStatus.UN_BIDDING.getValue()))
|
||||
.eq(AdvertRound::getDelFlag, Constants.UNDELETED).orderByAsc(AdvertRound::getPayPrice).last("LIMIT 1");
|
||||
// 如果是 时间范围 的广告位,则不查 系统拦截的数据;其实位置枚举的广告位也可不用查系统拦截的数据,主要是为了真实,给档口留个缝
|
||||
if (Objects.equals(createDTO.getShowType(), AdShowType.TIME_RANGE.getValue())) {
|
||||
|
|
@ -646,7 +658,11 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
|
|||
if (StringUtils.isNotBlank(createDTO.getPosition())) {
|
||||
queryWrapper.eq(AdvertRound::getPosition, createDTO.getPosition());
|
||||
}
|
||||
AdvertRound minPriceAdvert = Optional.ofNullable(this.advertRoundMapper.selectOne(queryWrapper)).orElseThrow(() -> new ServiceException("获取推广营销位置失败,请联系客服!", HttpStatus.ERROR));
|
||||
// 是否有可供购买的广告位
|
||||
AdvertRound minPriceAdvert = this.advertRoundMapper.selectOne(queryWrapper);
|
||||
if (ObjectUtils.isEmpty(minPriceAdvert)) {
|
||||
throw new ServiceException("当前推广位已售罄,请选购其它推广位噢!", HttpStatus.ERROR);
|
||||
}
|
||||
// 判断当前档口出价是否低于该推广位最低价格,若是,则提示:"已经有档口出价更高了噢,请重新出价!".
|
||||
if (createDTO.getPayPrice().compareTo(ObjectUtils.defaultIfNull(minPriceAdvert.getPayPrice(), BigDecimal.ZERO)) <= 0) {
|
||||
throw new ServiceException("已经有档口出价更高了噢,请重新出价!", HttpStatus.ERROR);
|
||||
|
|
|
|||
Loading…
Reference in New Issue