master:档口推广营销调整;

pull/1121/head
liujiang 2025-05-12 20:13:46 +08:00
parent 335bb04dee
commit 94adb2cb70
12 changed files with 251 additions and 15 deletions

View File

@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit;
@Api(tags = "通用")
@Slf4j
@RestController
@RequestMapping("/common")
@RequestMapping("/rest/v1/common")
public class CommonController {
@Autowired
private OSSClientWrapper ossClient;

View File

@ -7,6 +7,7 @@ import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.page.Page;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.web.controller.xkt.vo.advertRound.*;
import com.ruoyi.xkt.dto.advertRound.AdRoundLatestDTO;
import com.ruoyi.xkt.dto.advertRound.AdRoundStoreCreateDTO;
import com.ruoyi.xkt.dto.advertRound.AdvertRoundStorePageDTO;
import com.ruoyi.xkt.dto.advertRound.AdvertRoundStorePageResDTO;
@ -53,6 +54,15 @@ public class AdvertRoundController extends XktBaseController {
return R.ok(BeanUtil.toBean(advertRoundService.getStoreAdInfo(storeId, advertId, showType), AdRoundStoreResVO.class));
}
/**
*
*/
@ApiOperation(value = "获取当前最新的出价及设置的商品", httpMethod = "POST", response = R.class)
@PostMapping(value = "/latest")
public R<AdRoundLatestResVO> getLatestInfo(@Validated @RequestBody AdRoundLatestVO latestVO) {
return R.ok(BeanUtil.toBean(advertRoundService.getLatestInfo(BeanUtil.toBean(latestVO, AdRoundLatestDTO.class)), AdRoundLatestResVO.class));
}
/**
* 广广
*/

View File

@ -0,0 +1,40 @@
package com.ruoyi.web.controller.xkt.vo.advertRound;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("获取当前推广位最新的出价及商品信息")
@Data
@Accessors(chain = true)
public class AdRoundLatestResVO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "档口负责人名称")
private String storeOwnerName;
@ApiModelProperty(value = "最高价格")
private BigDecimal payPrice;
@ApiModelProperty(value = "档口设置的商品")
private List<ARLProdVO> prodList;
@Data
@ApiModel(value = "档口设置的商品")
@Accessors(chain = true)
public static class ARLProdVO {
@ApiModelProperty("档口商品ID")
private Long storeProdId;
@ApiModelProperty(value = "商品货号")
private String prodArtNum;
}
}

View File

@ -0,0 +1,37 @@
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.NotNull;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("获取该推广位最新的购买价格及设置的商品")
@Data
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AdRoundLatestVO {
@NotNull(message = "档口ID不能为空!")
@ApiModelProperty(value = "档口ID")
private Long storeId;
@NotNull(message = "广告类型ID不能为空!")
@ApiModelProperty(value = "广告类型ID")
private Long advertId;
@NotNull(message = "播放轮次ID不能为空!")
@ApiModelProperty(value = "播放轮次ID")
private Integer roundId;
@NotNull(message = "展示类型不能为空!")
@ApiModelProperty(value = "展示类型 时间范围 位置枚举")
private Integer showType;
@ApiModelProperty(value = "位置 A B C D E")
private String position;
}

View File

@ -1,7 +1,6 @@
package com.ruoyi.web.controller.xkt.vo.advertRound;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.xkt.dto.advertRound.AdRoundStoreResDTO;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;

View File

@ -0,0 +1,33 @@
package com.ruoyi.xkt.dto.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.NotNull;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("获取该推广位最新的购买价格及设置的商品")
@Data
@Accessors(chain = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class AdRoundLatestDTO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "广告类型ID")
private Long advertId;
@ApiModelProperty(value = "播放轮次ID")
private Integer roundId;
@ApiModelProperty(value = "展示类型 时间范围 位置枚举")
private Integer showType;
@ApiModelProperty(value = "位置 A B C D E")
private String position;
}

View File

@ -0,0 +1,40 @@
package com.ruoyi.xkt.dto.advertRound;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
import java.util.List;
/**
* @author liujiang
* @version v1.0
* @date 2025/3/27 15:12
*/
@ApiModel("获取当前推广位最新的出价及商品信息")
@Data
@Accessors(chain = true)
public class AdRoundLatestResDTO {
@ApiModelProperty(value = "档口ID")
private Long storeId;
@ApiModelProperty(value = "档口负责人名称")
private String storeOwnerName;
@ApiModelProperty(value = "最高价格")
private BigDecimal payPrice;
@ApiModelProperty(value = "档口设置的商品")
private List<ARLProdDTO> prodList;
@Data
@ApiModel(value = "档口设置的商品")
@Accessors(chain = true)
public static class ARLProdDTO {
@ApiModelProperty("档口商品ID")
private Long storeProdId;
@ApiModelProperty(value = "商品货号")
private String prodArtNum;
}
}

View File

@ -57,10 +57,6 @@ public class AdRoundStoreResDTO {
private Integer biddingStatus;
@ApiModelProperty(value = "出价状态名称")
private String biddingStatusName;
// @ApiModelProperty(value = "竞价状态")
// private Integer biddingTempStatus;
// @ApiModelProperty(value = "竞价状态名称22点 后 显示这个)")
// private String biddingTempStatusName;
}
@Data
@ -90,10 +86,6 @@ public class AdRoundStoreResDTO {
private Integer biddingStatus;
@ApiModelProperty(value = "出价状态名称")
private String biddingStatusName;
// @ApiModelProperty(value = "竞价状态")
// private Integer biddingTempStatus;
// @ApiModelProperty(value = "竞价状态名称22点 后 显示这个)")
// private String biddingTempStatusName;
@ApiModelProperty(value = "对象锁符号")
private String symbol;
}

View File

@ -6,6 +6,7 @@ import com.ruoyi.xkt.dto.advertRound.AdvertRoundStorePageDTO;
import com.ruoyi.xkt.dto.advertRound.AdvertRoundStorePageResDTO;
import org.apache.ibatis.annotations.Param;
import java.math.BigDecimal;
import java.util.List;
/**
@ -38,6 +39,7 @@ public interface AdvertRoundMapper extends BaseMapper<AdvertRound> {
/**
* null
*
* @param advertRoundId advertRoundId
*/
Integer updateAttrNull(Long advertRoundId);
@ -49,5 +51,21 @@ public interface AdvertRoundMapper extends BaseMapper<AdvertRound> {
*/
List<Long> selectMostPopulars();
/**
* 广
*
* @param advertId 广ID
* @param roundId ID
* @return BigDecimal
*/
BigDecimal selectMaxPayPrice(@Param("advertId") Long advertId, @Param("roundId") Integer roundId);
/**
*
* @param storeId ID
* @return
*/
String getStoreOwnerName(Long storeId);
}

View File

@ -93,5 +93,13 @@ public interface IAdvertRoundService {
* @return List<AdRoundPopularResDTO>
*/
List<AdRoundPopularResDTO> getMostPopulars();
/**
* 广
*
* @param latestDTO
* @return
*/
AdRoundLatestResDTO getLatestInfo(AdRoundLatestDTO latestDTO);
}

View File

@ -191,7 +191,6 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
boolean tenClockAfter = now.isAfter(LocalTime.of(22, 0, 1)) && 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)
@ -203,12 +202,10 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
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)) {
@ -511,6 +508,48 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
return list;
}
/**
* 广
*
* @param latestDTO
* @return AdRoundLatestResDTO
*/
@Override
@Transactional(readOnly = true)
public AdRoundLatestResDTO getLatestInfo(AdRoundLatestDTO latestDTO) {
AdvertRound advertRound;
AdRoundLatestResDTO latestInfo = new AdRoundLatestResDTO();
// 时间范围类型
if (Objects.equals(latestDTO.getShowType(), AdShowType.TIME_RANGE.getValue())) {
advertRound = this.advertRoundMapper.selectOne(new LambdaQueryWrapper<AdvertRound>()
.eq(AdvertRound::getAdvertId, latestDTO.getAdvertId()).eq(AdvertRound::getRoundId, latestDTO.getRoundId())
.eq(AdvertRound::getDelFlag, Constants.UNDELETED).orderByDesc(AdvertRound::getPayPrice, AdvertRound::getCreateTime)
.last("LIMIT 1"));
// 有人竞拍情况,才获取该位置的档口负责人名称
if (ObjectUtils.isNotEmpty(advertRound)) {
latestInfo.setStoreOwnerName(this.advertRoundMapper.getStoreOwnerName(advertRound.getStoreId()));
}
return latestInfo.setStoreId(advertRound.getStoreId()).setPayPrice(advertRound.getPayPrice());
} else {
Optional.ofNullable(latestDTO.getPosition()).orElseThrow(() -> new ServiceException("位置枚举类型position必传", HttpStatus.ERROR));
advertRound = Optional.ofNullable(this.advertRoundMapper.selectOne(new LambdaQueryWrapper<AdvertRound>()
.eq(AdvertRound::getAdvertId, latestDTO.getAdvertId()).eq(AdvertRound::getRoundId, latestDTO.getRoundId())
.eq(AdvertRound::getPosition, latestDTO.getPosition()).eq(AdvertRound::getDelFlag, Constants.UNDELETED)))
.orElseThrow(() -> new ServiceException("推广位不存在!", HttpStatus.ERROR));
latestInfo.setPayPrice(advertRound.getPayPrice());
}
// 如果当前档口购买该推广位,且设置商品不为空,则返回设置的商品信息
if (Objects.equals(advertRound.getStoreId(), latestDTO.getStoreId()) && StringUtils.isNotBlank(advertRound.getProdIdStr())) {
List<StoreProduct> storeProdList = Optional.ofNullable(this.storeProdMapper.selectList(new LambdaQueryWrapper<StoreProduct>()
.eq(StoreProduct::getId, Arrays.stream(advertRound.getProdIdStr().split(",")))
.eq(StoreProduct::getDelFlag, Constants.UNDELETED).eq(StoreProduct::getStoreId, advertRound.getStoreId())))
.orElseThrow(() -> new ServiceException("档口商品不存在!", HttpStatus.ERROR));
latestInfo.setProdList(storeProdList.stream().map(x -> new AdRoundLatestResDTO.ARLProdDTO()
.setStoreProdId(x.getId()).setProdArtNum(x.getProdArtNum())).collect(Collectors.toList()));
}
return latestInfo;
}
/**
* 广
*
@ -662,7 +701,7 @@ public class AdvertRoundServiceImpl implements IAdvertRoundService {
final Integer biddingStatus = tenClockAfter && roundIdList.contains(x.getRoundId()) ? x.getBiddingTempStatus() : x.getBiddingStatus();
return BeanUtil.toBean(x, AdRoundStoreResDTO.ADRSRoundRecordDTO.class).setBiddingStatus(biddingStatus)
.setBiddingStatusName(Objects.requireNonNull(AdBiddingStatus.of(biddingStatus)).getLabel())
.setAdvertRoundId(x.getId()).setTypeName(AdType.of(x.getTypeId()).getLabel())
.setTypeName(AdType.of(x.getTypeId()).getLabel())
// 如果是时间范围则不返回position
.setPosition(Objects.equals(x.getShowType(), AdShowType.TIME_RANGE.getValue()) ? null : x.getPosition());
})

View File

@ -89,6 +89,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LIMIT 8
</select>
<select id="selectMaxPayPrice">
SELECT
MAX(IFNULL( pay_price, 0 )) AS pay_price
FROM
advert_round
WHERE
advert_id = #{advertId}
AND round_id = #{roundId}
</select>
<select id="getStoreOwnerName">
SELECT DISTINCT
u.nick_name
FROM
store s
JOIN sys_user u ON s.user_id = u.user_id
WHERE
s.id = #{storeId}
AND s.del_flag = 0
</select>
</mapper>