diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertController.java index cd7784f84..4e03af80e 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertController.java @@ -6,10 +6,7 @@ import com.ruoyi.common.core.controller.XktBaseController; 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.advert.AdvertCreateVO; -import com.ruoyi.web.controller.xkt.vo.advert.AdvertPageVO; -import com.ruoyi.web.controller.xkt.vo.advert.AdvertResVO; -import com.ruoyi.web.controller.xkt.vo.advert.AdvertUpdateVO; +import com.ruoyi.web.controller.xkt.vo.advert.*; import com.ruoyi.xkt.dto.advert.AdvertCreateDTO; import com.ruoyi.xkt.dto.advert.AdvertPageDTO; import com.ruoyi.xkt.dto.advert.AdvertResDTO; @@ -21,6 +18,8 @@ import lombok.RequiredArgsConstructor; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; +import java.util.List; + /** * 管理员管理推广营销Controller * @@ -30,7 +29,7 @@ import org.springframework.web.bind.annotation.*; @Api(tags = "推广营销") @RestController @RequiredArgsConstructor -@RequestMapping("/rest/v1/adverts") +@RequestMapping("/rest/v1/ads") public class AdvertController extends XktBaseController { final IAdvertService advertService; @@ -84,5 +83,14 @@ public class AdvertController extends XktBaseController { return R.ok(advertService.offline(advertId)); } + /** + * 档口营销推广初始化数据 + */ + @ApiOperation(value = "档口营销推广初始化数据", httpMethod = "GET", response = R.class) + @GetMapping(value = "/platform-list") + public R> getPlatformList() { + return R.ok(BeanUtil.copyToList(advertService.getPlatformList(), AdvertPlatformResVO.class)); + } + } 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/AdvertRoundPlayController.java new file mode 100644 index 000000000..4ee5885ca --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/AdvertRoundPlayController.java @@ -0,0 +1,72 @@ +package com.ruoyi.web.controller.xkt; + +import cn.hutool.core.bean.BeanUtil; +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 io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +/** + * 推广营销轮次投放Controller + * + * @author ruoyi + * @date 2025-03-26 + */ +@Api(tags = "推广营销轮次投放") +@RestController +@RequiredArgsConstructor +@RequestMapping("/rest/v1/ad-round-plays") +public class AdvertRoundPlayController extends XktBaseController { + + final IAdvertRoundPlayService adPlayService; + + + /** + * 档口购买推广营销 + */ + @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))); + } + + + + /** + * 根据类型查询当前档口的推广营销数据 + */ + @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)); + } + + + + + + // TODO 获取最受欢迎推广位8个,固定不动了 + // TODO 获取最受欢迎推广位8个,固定不动了 + + + + + + + + + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertCreateVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertCreateVO.java index 9bbb33bef..976a1637d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertCreateVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertCreateVO.java @@ -41,7 +41,7 @@ public class AdvertCreateVO { private Integer playInterval; @NotNull(message = "播放轮次不能为空!") @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @NotNull(message = "播放数量不能为空!") @ApiModelProperty(value = "播放数量") private Integer playNum; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertPlatformResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertPlatformResVO.java new file mode 100644 index 000000000..174e96760 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertPlatformResVO.java @@ -0,0 +1,53 @@ +package com.ruoyi.web.controller.xkt.vo.advert; + +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("推广营销返回分组数据") +@Data +@Accessors(chain = true) +public class AdvertPlatformResVO { + + @ApiModelProperty(value = "平台ID") + private Integer platformId; + @ApiModelProperty(value = "平台名称") + private String platformName; + @ApiModelProperty(value = "tabList") + private List tabList; + + @Data + @ApiModel(value = "平台下tab") + @Accessors(chain = true) + public static class APTabVO { + @ApiModelProperty(value = "tabId") + private Integer tabId; + @ApiModelProperty(value = "tabName") + private String tabName; + @ApiModelProperty(value = "类型列表") + List typeList; + } + + @Data + @ApiModel(value = "tab下type") + @Accessors(chain = true) + public static class APTypeVO { + @ApiModelProperty("广告ID") + private Long advertId; + @ApiModelProperty(value = "typeId") + private Integer typeId; + @ApiModelProperty(value = "typeName") + private String typeName; + @ApiModelProperty(value = "示例url") + private String demoUrl; + } + +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertResVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertResVO.java index 97af93555..12422d3b3 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertResVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertResVO.java @@ -16,7 +16,7 @@ import java.util.Date; * @version v1.0 * @date 2025/3/27 15:12 */ -@ApiModel("创建推广营销") +@ApiModel("推广营销返回数据") @Data @Accessors(chain = true) public class AdvertResVO { @@ -34,7 +34,7 @@ public class AdvertResVO { @ApiModelProperty(value = "播放间隔") private Integer playInterval; @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @ApiModelProperty(value = "播放数量") private Integer playNum; @ApiModelProperty(value = "推广状态") diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertUpdateVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertUpdateVO.java index 4ad460f3f..4900514ef 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertUpdateVO.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advert/AdvertUpdateVO.java @@ -44,7 +44,7 @@ public class AdvertUpdateVO { private Integer playInterval; @NotNull(message = "播放轮次不能为空!") @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @NotNull(message = "播放数量不能为空!") @ApiModelProperty(value = "播放数量") private Integer playNum; diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java new file mode 100644 index 000000000..b94943803 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreCreateVO.java @@ -0,0 +1,38 @@ +package com.ruoyi.web.controller.xkt.vo.advertRoundPlay; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.experimental.Accessors; + +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) +public class AdPlayStoreCreateVO { + + @NotNull(message = "广告ID不能为空!") + @ApiModelProperty(value = "广告ID") + private Long advertId; + @NotNull(message = "广告轮次ID不能为空!") + @ApiModelProperty(value = "广告轮次ID") + private Long advertRoundId; + @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; + +} 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/advertRoundPlay/AdPlayStoreResVO.java new file mode 100644 index 000000000..54134acb9 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/xkt/vo/advertRoundPlay/AdPlayStoreResVO.java @@ -0,0 +1,18 @@ +package com.ruoyi.web.controller.xkt.vo.advertRoundPlay; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("当前类型档口营销推广数据") +@Data +@Accessors(chain = true) +public class AdPlayStoreResVO { + + +} 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 5e5cdd232..38e077269 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 @@ -219,4 +219,5 @@ public class Constants */ public static final Long TOPMOST_PRODUCT_CATEGORY_ID = 1L; + } diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailySaleController.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java similarity index 86% rename from ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailySaleController.java rename to ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java index 28e887cdb..96dea6d84 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailySaleController.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/controller/DailyTaskController.java @@ -18,8 +18,8 @@ import java.io.IOException; */ @RequiredArgsConstructor @RestController -@RequestMapping("/rest/v1/daily-sale") -public class DailySaleController extends BaseController { +@RequestMapping("/rest/v1/daily-task") +public class DailyTaskController extends BaseController { final XktTask task; @@ -65,4 +65,10 @@ public class DailySaleController extends BaseController { return R.ok(); } + @PostMapping("/advert-round") + public R dailyRound(SysJob sysJob) { + task.dailyAdvertRound(); + 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 083ab3085..f31b8bc0a 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 @@ -29,6 +29,7 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.time.LocalDate; import java.time.ZoneId; +import java.time.temporal.ChronoUnit; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @@ -60,6 +61,8 @@ public class XktTask { final StoreProductCategoryAttributeMapper cateAttrMapper; final StoreProductStatisticsMapper prodStatMapper; final EsClientWrapper esClientWrapper; + final AdvertMapper advertMapper; + final AdvertRoundMapper advertRoundMapper; /** * 每晚1点同步档口销售数据 @@ -290,6 +293,93 @@ public class XktTask { this.storeProdMapper.updateById(storeProdList); } + /** + * 每晚定时任务更新推广的播放轮次,这个要次日凌晨更新 + */ + @Transactional + 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)) { + return; + } + // 正在投放 或 待投放列表 + List advertRoundList = this.advertRoundMapper.selectList(new LambdaQueryWrapper() + .eq(AdvertRound::getDelFlag, Constants.UNDELETED) + .in(AdvertRound::getLaunchStatus, + Arrays.asList(AdLaunchStatus.UN_LAUNCH.getValue(), AdLaunchStatus.LAUNCHING.getValue()))); + // 投放轮次按照advertId进行分组 + Map> advertRoundMap = advertRoundList.stream().collect(Collectors.groupingBy(AdvertRound::getAdvertId)); + // 待更新或待新增的推广轮次列表 + List updateList = new ArrayList<>(); + advertList.forEach(advert -> { + List roundList = advertRoundMap.get(advert.getId()); + // 如果没有 投放中 或 待投放的推广轮次,则 一次性创建所有的轮次 + if (CollectionUtils.isEmpty(roundList)) { + // 播放的轮次 + for (int i = 0; i < advert.getPlayRound(); i++) { + // 如果i = 0 则表明从未创建过推广位,直接新建所有 + final Integer launchStatus = i == 0 ? AdLaunchStatus.LAUNCHING.getValue() : AdLaunchStatus.UN_LAUNCH.getValue(); + final LocalDate now = i == 0 ? LocalDate.now() : LocalDate.now().plusDays((long) advert.getPlayInterval() * i); + // 间隔时间 + 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)))); + } + } + } else { + // 判断当天是否为播放轮次最小结束时间的下一天 最小结束时间为:yyyy-MM-dd格式 + final Date compareDate = java.sql.Date.valueOf(LocalDate.now().minusDays(1)); + final Date minEndTime = roundList.stream().min(Comparator.comparing(AdvertRound::getEndTime)).get().getEndTime(); + if (Objects.equals(minEndTime, compareDate)) { + // 将播放轮次为1的推广轮置为:已过期 + roundList.stream().filter(x -> Objects.equals(x.getRoundId(), AdRoundType.PLAY_ROUND.getValue())).forEach(x -> x.setLaunchStatus(AdLaunchStatus.EXPIRED.getValue())); + // 将播放轮次 大于 1 的推广轮 依次减1 + roundList.stream().filter(x -> x.getRoundId() > AdRoundType.PLAY_ROUND.getValue()).forEach(x -> x.setRoundId(x.getRoundId() - 1)); + // 将播放轮次为1 且 投放状态为:待投放的 置为投放中 + roundList.stream().filter(x -> Objects.equals(x.getRoundId(), AdRoundType.PLAY_ROUND.getValue()) + && Objects.equals(x.getLaunchStatus(), AdLaunchStatus.UN_LAUNCH.getValue())).forEach(x -> x.setLaunchStatus(AdLaunchStatus.LAUNCHING.getValue())); + updateList.addAll(roundList); + // 如果播放轮次有更新,则需重新判断 + int diff = advert.getPlayRound() - roundList.stream().mapToInt(AdvertRound::getRoundId).max().getAsInt(); + // 当前最大轮次 + int maxRoundId = roundList.stream().mapToInt(AdvertRound::getRoundId).max().getAsInt(); + // diff < 0 代表轮次有减少,则不新增播放轮, diff == 0 则代表播放轮次不增不减,不做调整 + if (diff > 0) { + // 最大轮次的结束时间 + final LocalDate maxEndTime = roundList.stream().max(Comparator.comparing(AdvertRound::getEndTime)) + .map(round -> round.getEndTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate()) + .orElseThrow(() -> new ServiceException("获取推广轮次最大结束时间失败", HttpStatus.ERROR)); + LocalDate maxEndTimeNextDay = maxEndTime.plusDays(1); + // 根据轮次差来判断当前需要补多少播放轮 + for (int j = 0; j < diff; j++) { + // 推广轮次 + 1 + maxRoundId += 1; + final LocalDate startDate = j == 0 ? maxEndTimeNextDay : maxEndTimeNextDay.plusDays((long) advert.getPlayInterval() * j); + // 间隔时间 + final LocalDate endDate = startDate.plusDays(advert.getPlayInterval() - 1); + // 每一轮的播放数量 + for (int i = 0; i < advert.getPlayNum(); i++) { + // 生成最新的下一轮推广位 + updateList.add(new AdvertRound().setAdvertId(advert.getId()).setRoundId(maxRoundId).setLaunchStatus(AdLaunchStatus.UN_LAUNCH.getValue()) + .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)))); + } + } + } + } + } + }); + if (CollectionUtils.isNotEmpty(updateList)) { + this.advertRoundMapper.insertOrUpdate(updateList); + } + } + /** * 给商品打风格标签 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 3e9db5340..0dbd8ffcd 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/Advert.java @@ -56,7 +56,7 @@ public class Advert extends XktBaseEntity { /** * 播放轮次 */ - private Integer playTimes; + private Integer playRound; /** * 播放数量 */ @@ -73,6 +73,10 @@ public class Advert extends XktBaseEntity { * 推广图片大小 */ private String picSize; + /** + * 如果是播放商品,或者图及商品 最多可容纳的商品数量 + */ + private Integer prodMaxNum; /** * 推广折扣类型(现金、直接打折) */ diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java new file mode 100644 index 000000000..34584c671 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRound.java @@ -0,0 +1,106 @@ +package com.ruoyi.xkt.domain; + +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 + * + * @author liujiang + * @date 2025-05-03 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +public class AdvertRound extends XktBaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 广告轮次位置ID + */ + @TableId + private Long id; + /** + * 广告ID + */ + private Long advertId; + /** + * 轮次ID + */ + private Integer roundId; + /** + * 投放状态 + */ + private Integer launchStatus; + /** + * 投放开始时间 + */ + private Date startTime; + /** + * 投放结束时间 + */ + private Date endTime; + /** + * 广告位置 A B C D E... 对应advert中的playNum + */ + private String position; + + + + + + + + + + + + + + + + /** + * 推广档口ID + */ + private Long storeId; + /** + * 推广档口出价 + */ + private BigDecimal payPrice; + /** + * 竞价状态 + */ + private Integer biddingStatus; + /** + * 图片审核状态 + */ + private Integer picAuditStatus; + /** + * 图片是否设置 0 未设置 1已设置 + */ + private Integer picSet; + /** + * 推广图ID 对应sysFile.id + */ + private Long picId; + /** + * 如果是推广商品,或者图及商品,则这里存放的是商品ID或者商品ID列表 eg: 1 或 1,2,3等 + */ + private String prodIdStr; + /** + * 图片设计(自主设计、平台设计) + */ + private Integer picDesignType; + /** + * 系统拦截 + */ + private Integer sysIntercept; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java new file mode 100644 index 000000000..1a7c7e2dc --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/domain/AdvertRoundPlay.java @@ -0,0 +1,77 @@ +package com.ruoyi.xkt.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.ruoyi.common.core.domain.XktBaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; + +/** + * 广告营销每一轮播放 advert_round_play + * + * @author liujiang + * @date 2025-05-03 + */ +@EqualsAndHashCode(callSuper = true) +@Data +public class AdvertRoundPlay extends XktBaseEntity { + + private static final long serialVersionUID = 1L; + + /** + * 广告轮次播放ID + */ + @TableId + private Long id; + /** + * 广告ID + */ + private Long advertId; + /** + * 广告轮次ID + */ + private Long advertRoundId; + + + + + + /** + * 推广档口ID + */ + private Long storeId; + /** + * 推广档口出价 + */ + private BigDecimal payPrice; + /** + * 竞价状态 + */ + private Integer biddingStatus; + /** + * 图片审核状态 + */ + private Integer picAuditStatus; + /** + * 图片是否设置 0 未设置 1已设置 + */ + private Integer picSet; + /** + * 推广图ID 对应sysFile.id + */ + private Long picId; + /** + * 如果是推广商品,或者图及商品,则这里存放的是商品ID或者商品ID列表 eg: 1 或 1,2,3等 + */ + private String prodIdStr; + /** + * 图片设计(自主设计、平台设计) + */ + private Integer picDesignType; + /** + * 系统拦截 + */ + private Integer sysIntercept; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertCreateDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertCreateDTO.java index 52f8fccc9..621a569ea 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertCreateDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertCreateDTO.java @@ -34,7 +34,7 @@ public class AdvertCreateDTO { @ApiModelProperty(value = "播放间隔") private Integer playInterval; @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @ApiModelProperty(value = "播放数量") private Integer playNum; @ApiModelProperty(value = "推广范例图片") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatTabDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatTabDTO.java new file mode 100644 index 000000000..046642ce9 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatTabDTO.java @@ -0,0 +1,22 @@ +package com.ruoyi.xkt.dto.advert; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("推广营销平台与tab数据") +@Data +@Accessors(chain = true) +public class AdvertPlatTabDTO { + + private Integer platformId; + private Integer tabId; + private Integer typeId; + private Long advertId; + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatformResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatformResDTO.java new file mode 100644 index 000000000..2163c7b82 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertPlatformResDTO.java @@ -0,0 +1,53 @@ +package com.ruoyi.xkt.dto.advert; + +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("推广营销返回分组数据") +@Data +@Accessors(chain = true) +public class AdvertPlatformResDTO { + + @ApiModelProperty(value = "平台ID") + private Integer platformId; + @ApiModelProperty(value = "平台名称") + private String platformName; + @ApiModelProperty(value = "tabList") + private List tabList; + + @Data + @ApiModel(value = "平台下tab") + @Accessors(chain = true) + public static class APTabDTO { + @ApiModelProperty(value = "tabId") + private Integer tabId; + @ApiModelProperty(value = "tabName") + private String tabName; + @ApiModelProperty(value = "类型列表") + List typeList; + } + + @Data + @ApiModel(value = "tab下type") + @Accessors(chain = true) + public static class APTypeDTO { + @ApiModelProperty("广告ID") + private Long advertId; + @ApiModelProperty(value = "typeId") + private Integer typeId; + @ApiModelProperty(value = "typeName") + private String typeName; + @ApiModelProperty(value = "示例url") + private String demoUrl; + } + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertResDTO.java index 969042c5a..791526aff 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertResDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertResDTO.java @@ -32,7 +32,7 @@ public class AdvertResDTO { @ApiModelProperty(value = "播放间隔") private Integer playInterval; @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @ApiModelProperty(value = "播放数量") private Integer playNum; @ApiModelProperty(value = "推广状态") diff --git a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertUpdateDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertUpdateDTO.java index eb6cb59a5..bbb30a4e1 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertUpdateDTO.java +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advert/AdvertUpdateDTO.java @@ -36,7 +36,7 @@ public class AdvertUpdateDTO { @ApiModelProperty(value = "播放间隔") private Integer playInterval; @ApiModelProperty(value = "播放轮次") - private Integer playTimes; + private Integer playRound; @ApiModelProperty(value = "播放数量") private Integer playNum; @ApiModelProperty(value = "推广范例图片") 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 new file mode 100644 index 000000000..85b2be69d --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreCreateDTO.java @@ -0,0 +1,33 @@ +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/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java new file mode 100644 index 000000000..e2d2bea88 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/dto/advertRoundPlay/AdPlayStoreResDTO.java @@ -0,0 +1,18 @@ +package com.ruoyi.xkt.dto.advertRoundPlay; + +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author liujiang + * @version v1.0 + * @date 2025/3/27 15:12 + */ +@ApiModel("当前类型档口营销推广数据") +@Data +@Accessors(chain = true) +public class AdPlayStoreResDTO { + + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java new file mode 100644 index 000000000..49e31bd50 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdBiddingStatus.java @@ -0,0 +1,35 @@ +package com.ruoyi.xkt.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 推广营销竞价状态 + * @author liujiang + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum AdBiddingStatus { + + // 已出价 + BIDDING(1, "已出价"), + // 竞价失败 + BIDDING_FAIL(2, "竞价失败"), + // 竞价成功 + BIDDING_SUCCESS(3, "竞价成功"), + + ; + + private final Integer value; + private final String label; + + public static AdBiddingStatus of(Integer value) { + for (AdBiddingStatus e : AdBiddingStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + return null; + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdDesignType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDesignType.java new file mode 100644 index 000000000..841645b2b --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDesignType.java @@ -0,0 +1,37 @@ +package com.ruoyi.xkt.enums; + +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 推广营销图片设计类型 + * @author liujiang + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum AdDesignType { + + // 自主设计 + STORE_DESIGN(1, "自主设计"), + // 平台设计 + SYS_DESIGN(2, "平台设计"); + + + + ; + + private final Integer value; + private final String label; + + public static AdDesignType of(Integer value) { + for (AdDesignType e : AdDesignType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + throw new ServiceException("推广营销图片设计类型不存在!", HttpStatus.ERROR); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdDiscountType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDiscountType.java index 848944bcc..27f303c6e 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdDiscountType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDiscountType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -29,6 +31,6 @@ public enum AdDiscountType { return e; } } - return null; + throw new ServiceException("推广营销折扣类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdDisplayType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDisplayType.java index 05a9811cb..1b6113299 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdDisplayType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdDisplayType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -32,6 +34,6 @@ public enum AdDisplayType { return e; } } - return null; + throw new ServiceException("推广营销展示类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdLaunchStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdLaunchStatus.java new file mode 100644 index 000000000..e37efcb7c --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdLaunchStatus.java @@ -0,0 +1,40 @@ +package com.ruoyi.xkt.enums; + +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 推广营销每一轮播放状态 + * @author liujiang + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum AdLaunchStatus { + + // 投放中 + LAUNCHING(1, "投放中"), + // 待投放 + UN_LAUNCH(2, "待投放"), + // 已过期 + EXPIRED(3, "已过期"), + // 已退订 + CANCEL(4, "已退订"), + + + ; + + private final Integer value; + private final String label; + + public static AdLaunchStatus of(Integer value) { + for (AdLaunchStatus e : AdLaunchStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + throw new ServiceException("营销推广投放状态不存在!", HttpStatus.ERROR); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdOnlineStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdOnlineStatus.java index ee3328a82..ebf28f47b 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdOnlineStatus.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdOnlineStatus.java @@ -1,10 +1,12 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; /** - * 推广营销类型 + * 推广营销上线类型 * * @author liujiang * @date 2025-04-02 23:42 @@ -30,6 +32,6 @@ public enum AdOnlineStatus { return e; } } - return null; + throw new ServiceException("营销推广上线状态不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdPicAuditStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdPicAuditStatus.java new file mode 100644 index 000000000..68f86bc94 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdPicAuditStatus.java @@ -0,0 +1,39 @@ +package com.ruoyi.xkt.enums; + +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 推广营销图片审核状态 + * @author liujiang + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum AdPicAuditStatus { + + // 待审核 + UN_AUDIT(1, "待审核"), + // 审核通过 + AUDIT_PASS(2, "审核通过"), + // 审核驳回 + AUDIT_REJECTED(3, "审核驳回"), + + + + ; + + private final Integer value; + private final String label; + + public static AdPicAuditStatus of(Integer value) { + for (AdPicAuditStatus e : AdPicAuditStatus.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + throw new ServiceException("营销推广图片审核类型不存在!", HttpStatus.ERROR); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdPlatformType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdPlatformType.java index 55f1ab361..0db4ce6ca 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdPlatformType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdPlatformType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -26,6 +28,6 @@ public enum AdPlatformType { return e; } } - return null; + throw new ServiceException("推广营销平台类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdRoundType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdRoundType.java new file mode 100644 index 000000000..043807dc8 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdRoundType.java @@ -0,0 +1,40 @@ +package com.ruoyi.xkt.enums; + +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 推广营销竞价状态 + * @author liujiang + * @date 2025-04-02 23:42 + */ +@Getter +@AllArgsConstructor +public enum AdRoundType { + + // 播放轮 + PLAY_ROUND(1, "播放轮"), + // 第二轮 + SECOND_ROUND(2, "第二轮"), + // 第三轮 + THIRD_ROUND(3, "第三轮"), + // 第四轮 + FOURTH_ROUND(4, "第四轮"), + + + ; + + private final Integer value; + private final String label; + + public static AdRoundType of(Integer value) { + for (AdRoundType e : AdRoundType.values()) { + if (e.getValue().equals(value)) { + return e; + } + } + throw new ServiceException("营销推广播放轮次不存在!", HttpStatus.ERROR); + } +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdTab.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdTab.java index 06c9d56c6..8d13ac6df 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdTab.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdTab.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -38,6 +40,6 @@ public enum AdTab { return e; } } - return null; + throw new ServiceException("推广营销TAB不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java index f5d14ba48..55833cf59 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/AdType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -13,80 +15,80 @@ import lombok.Getter; public enum AdType { // 顶部横向大图 - PC_HOME_TOP_LEFT_BANNER(1, "顶部横向大图"), + PC_HOME_TOP_LEFT_BANNER(1, "顶部横向大图", "/url"), // 顶部纵向小图 - PC_HOME_TOP_RIGHT_BANNER(2, "顶部纵向小图"), + PC_HOME_TOP_RIGHT_BANNER(2, "顶部纵向小图", "/url"), // 人气榜左侧大图 - PC_HOME_POP_LEFT_BANNER(3, "人气榜左大图"), + PC_HOME_POP_LEFT_BANNER(3, "人气榜左大图", "/url"), // 人气榜中上侧 - PC_HOME_POP_MID_TOP(4, "人气榜中上侧"), + PC_HOME_POP_MID_TOP(4, "人气榜中上侧", "/url"), // 人气榜中下侧 - PC_HOME_POP_MID_BOTTOM(5, "人气榜中下侧"), + PC_HOME_POP_MID_BOTTOM(5, "人气榜中下侧", "/url"), // 人气榜右上侧 - PC_HOME_POP_RIGHT_TOP(6, "人气榜右上侧"), + PC_HOME_POP_RIGHT_TOP(6, "人气榜右上侧", "/url"), // 人气榜右下侧 - PC_HOME_POP_RIGHT_BOTTOM(7, "人气榜右下侧"), + PC_HOME_POP_RIGHT_BOTTOM(7, "人气榜右下侧", "/url"), // 首页档口横幅 - PC_HOME_SINGLE_BANNER(8, "首页档口横幅"), + PC_HOME_SINGLE_BANNER(8, "首页档口横幅", "/url"), // 首页商品列表 - PC_HOME_PRODUCT_LIST(9, "首页商品列表"), + PC_HOME_PRODUCT_LIST(9, "首页商品列表", "/url"), // 首页两侧固定挂耳 - PC_HOME_FIXED_EAR(10, "首页两侧固定挂耳"), + PC_HOME_FIXED_EAR(10, "首页两侧固定挂耳", "/url"), // 首页搜索框下名称 - PC_HOME_SEARCH_DOWN_NAME(11, "首页搜索框下名称"), + PC_HOME_SEARCH_DOWN_NAME(11, "首页搜索框下名称", "/url"), // 首页搜索框商品 - PC_HOME_SEARCH_PRODUCT(12, "首页搜索框商品"), + PC_HOME_SEARCH_PRODUCT(12, "首页搜索框商品", "/url"), // 首页搜索框档口 - PC_HOME_SEARCH_STORE(13, "首页搜索框档口"), + PC_HOME_SEARCH_STORE(13, "首页搜索框档口", "/url"), // 首页以图搜款商品 - PC_HOME_PIC_SEARCH_PRODUCT(14, "首页以图搜款商品"), + PC_HOME_PIC_SEARCH_PRODUCT(14, "首页以图搜款商品", "/url"), // 新品馆顶部横向大图 - PC_NEW_PROD_TOP_LEFT_BANNER(30, "新品馆顶部横向大图"), + PC_NEW_PROD_TOP_LEFT_BANNER(30, "新品馆顶部横向大图", "/url"), // 新品馆顶部纵向大图 - PC_NEW_PROD_TOP_RIGHT(31, "新品馆顶部纵向大图"), + PC_NEW_PROD_TOP_RIGHT(31, "新品馆顶部纵向大图", "/url"), // 新品馆品牌榜 - PC_NEW_PROD_BRAND_BANNER(32, "新品馆品牌榜"), + PC_NEW_PROD_BRAND_BANNER(32, "新品馆品牌榜", "/url"), // 新品馆热卖榜左大图 - PC_NEW_PROD_HOT_LEFT_BANNER(33, "新品馆热卖榜左大图"), + PC_NEW_PROD_HOT_LEFT_BANNER(33, "新品馆热卖榜左大图", "/url"), // 新品馆热卖榜右推广商品 - PC_NEW_PROD_HOT_RIGHT_PRODUCT(34, "新品馆热卖榜右推广商品"), + PC_NEW_PROD_HOT_RIGHT_PRODUCT(34, "新品馆热卖榜右推广商品", "/url"), // 新品馆横幅 - PC_NEW_PROD_SINGLE_BANNER(35, "新品馆横幅"), + PC_NEW_PROD_SINGLE_BANNER(35, "新品馆横幅", "/url"), // 新品馆商品列表 - PC_NEW_PROD_PRODUCT_LIST(36, "新品馆商品列表"), + PC_NEW_PROD_PRODUCT_LIST(36, "新品馆商品列表", "/url"), // PC搜索结果 - PC_SEARCH_RESULT(40, "PC搜索结果"), + PC_SEARCH_RESULT(40, "PC搜索结果", "/url"), // PC用户中心 - PC_USER_CENTER(41, "PC用户中心"), + PC_USER_CENTER(41, "PC用户中心", "/url"), // PC下载页 - PC_DOWNLOAD(42, "PC下载页"), + PC_DOWNLOAD(42, "PC下载页", "/url"), // APP首页顶部轮播图 - APP_HOME_TOP_BANNER(50, "APP首页顶部轮播图"), + APP_HOME_TOP_BANNER(50, "APP首页顶部轮播图", "/url"), // APP首页推荐商品区 - APP_HOME_RECOMMEND_PRODUCT(51, "APP首页推荐商品区"), + APP_HOME_RECOMMEND_PRODUCT(51, "APP首页推荐商品区", "/url"), // APP首页热卖推荐 - APP_HOME_HOT_RECOMMEND(52, "APP首页热卖推荐"), + APP_HOME_HOT_RECOMMEND(52, "APP首页热卖推荐", "/url"), // APP首页人气榜 - APP_HOME_POP_RECOMMEND(53, "APP首页人气榜"), + APP_HOME_POP_RECOMMEND(53, "APP首页人气榜", "/url"), // APP首页新品榜 - APP_HOME_NEW_PROD_RECOMMEND(54, "APP首页新品榜"), + APP_HOME_NEW_PROD_RECOMMEND(54, "APP首页新品榜", "/url"), // APP搜索结果 - APP_SEARCH_RESULT(55, "APP搜索结果"), + APP_SEARCH_RESULT(55, "APP搜索结果", "/url"), // APP分类页轮播图 - APP_CATEGORY_TOP_BANNER(70, "APP分类页轮播图"), + APP_CATEGORY_TOP_BANNER(70, "APP分类页轮播图", "/url"), // APP个人中心猜你喜欢 - APP_USER_CENTER_GUESS_YOU_LIKE(71, "APP个人中心猜你喜欢"), + APP_USER_CENTER_GUESS_YOU_LIKE(71, "APP个人中心猜你喜欢", "/url"), // 以图搜款结果推广商品 - PIC_SEARCH_RESULT_PRODUCT(80, "以图搜款结果推广商品"), + PIC_SEARCH_RESULT_PRODUCT(80, "以图搜款结果推广商品", "/url"), @@ -94,6 +96,7 @@ public enum AdType { private final Integer value; private final String label; + private final String demoUrl; public static AdType of(Integer value) { for (AdType e : AdType.values()) { @@ -101,6 +104,6 @@ public enum AdType { return e; } } - return null; + throw new ServiceException("营销推广推广类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/StorageType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/StorageType.java index 11a9f9545..ac565690a 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/StorageType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/StorageType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -24,6 +26,6 @@ public enum StorageType { return e; } } - return null; + throw new ServiceException("档口入库类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/StoreStatus.java b/xkt/src/main/java/com/ruoyi/xkt/enums/StoreStatus.java index 7d1794dc9..d7fba03db 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/StoreStatus.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/StoreStatus.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -31,6 +33,6 @@ public enum StoreStatus { return e; } } - return null; + throw new ServiceException("档口状态类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/enums/StoreTagType.java b/xkt/src/main/java/com/ruoyi/xkt/enums/StoreTagType.java index b82ba744c..4fef0c518 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/enums/StoreTagType.java +++ b/xkt/src/main/java/com/ruoyi/xkt/enums/StoreTagType.java @@ -1,5 +1,7 @@ package com.ruoyi.xkt.enums; +import com.ruoyi.common.constant.HttpStatus; +import com.ruoyi.common.exception.ServiceException; import lombok.AllArgsConstructor; import lombok.Getter; @@ -44,6 +46,6 @@ public enum StoreTagType { return e; } } - return null; + throw new ServiceException("档口标签类型不存在!", HttpStatus.ERROR); } } diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertMapper.java index 9b7d30856..42ee84084 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertMapper.java @@ -2,8 +2,7 @@ package com.ruoyi.xkt.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.ruoyi.xkt.domain.Advert; -import com.ruoyi.xkt.dto.advert.AdvertPageDTO; -import com.ruoyi.xkt.dto.advert.AdvertResDTO; +import com.ruoyi.xkt.dto.advert.AdvertPlatTabDTO; import org.springframework.stereotype.Repository; import java.util.List; @@ -17,11 +16,6 @@ import java.util.List; @Repository public interface AdvertMapper extends BaseMapper { - /** - * 查询推广营销分页列表 - * @param pageDTO 查询入参 - * @return - */ -// List selectAdvertPage(AdvertPageDTO pageDTO); + List selectPlatTabList(); } diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java new file mode 100644 index 000000000..365314c53 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundMapper.java @@ -0,0 +1,16 @@ +package com.ruoyi.xkt.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.ruoyi.xkt.domain.AdvertRound; +import org.springframework.stereotype.Repository; + +/** + * 推广营销轮次Mapper接口 + * + * @author ruoyi + * @date 2025-03-26 + */ +@Repository +public interface AdvertRoundMapper extends BaseMapper { + +} diff --git a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java new file mode 100644 index 000000000..9398f4541 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertRoundPlayMapper.java @@ -0,0 +1,16 @@ +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/AdvertStoreFileMapper.java b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertStoreFileMapper.java index e3ee20aa3..9e4db49be 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertStoreFileMapper.java +++ b/xkt/src/main/java/com/ruoyi/xkt/mapper/AdvertStoreFileMapper.java @@ -5,7 +5,7 @@ import com.ruoyi.xkt.domain.AdvertStoreFile; import org.springframework.stereotype.Repository; /** - * 推广营销Mapper接口 + * 推广营销档口上传的推广图 Mapper接口 * * @author ruoyi * @date 2025-03-26 diff --git a/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java new file mode 100644 index 000000000..433ea3409 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertRoundPlayService.java @@ -0,0 +1,31 @@ +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/IAdvertService.java b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertService.java index 8928acf52..084413382 100644 --- a/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertService.java +++ b/xkt/src/main/java/com/ruoyi/xkt/service/IAdvertService.java @@ -1,10 +1,9 @@ package com.ruoyi.xkt.service; import com.ruoyi.common.core.page.Page; -import com.ruoyi.xkt.dto.advert.AdvertCreateDTO; -import com.ruoyi.xkt.dto.advert.AdvertPageDTO; -import com.ruoyi.xkt.dto.advert.AdvertResDTO; -import com.ruoyi.xkt.dto.advert.AdvertUpdateDTO; +import com.ruoyi.xkt.dto.advert.*; + +import java.util.List; /** * 推广营销Service接口 @@ -54,4 +53,11 @@ public interface IAdvertService { */ Integer offline(Long advertId); + /** + * 获取初始化平台列表 + * + * @return List + */ + List getPlatformList(); + } 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 new file mode 100644 index 000000000..eca04c871 --- /dev/null +++ b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertRoundPlayServiceImpl.java @@ -0,0 +1,83 @@ +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/AdvertServiceImpl.java b/xkt/src/main/java/com/ruoyi/xkt/service/impl/AdvertServiceImpl.java index c2751021c..4bde5cd4c 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 @@ -12,12 +12,11 @@ import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.xkt.domain.Advert; import com.ruoyi.xkt.domain.SysFile; -import com.ruoyi.xkt.dto.advert.AdvertCreateDTO; -import com.ruoyi.xkt.dto.advert.AdvertPageDTO; -import com.ruoyi.xkt.dto.advert.AdvertResDTO; -import com.ruoyi.xkt.dto.advert.AdvertUpdateDTO; -import com.ruoyi.xkt.dto.storeCustomer.StoreCusPageResDTO; +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.xkt.mapper.AdvertMapper; import com.ruoyi.xkt.mapper.SysFileMapper; import com.ruoyi.xkt.service.IAdvertService; @@ -27,9 +26,11 @@ import org.apache.commons.lang3.ObjectUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Optional; +import java.util.stream.Collectors; /** * 推广营销Service业务层处理 @@ -173,6 +174,39 @@ public class AdvertServiceImpl implements IAdvertService { return this.advertMapper.updateById(advert); } + /** + * 获取初始化平台列表 + * + * @return List + */ + @Override + @Transactional(readOnly = true) + public List getPlatformList() { + List list = this.advertMapper.selectPlatTabList(); + if (CollectionUtils.isEmpty(list)) { + return null; + } + // 所有的推广平台 + List platformList = new ArrayList<>(); + list.stream().collect(Collectors + .groupingBy(AdvertPlatTabDTO::getPlatformId, Collectors + .groupingBy(AdvertPlatTabDTO::getTabId))) + .forEach((platformId, tabMap) -> { + // 平台下所有的tab + List tabList = new ArrayList<>(); + tabMap.forEach((tabId, typeList) -> tabList.add(new AdvertPlatformResDTO.APTabDTO() + .setTabId(tabId).setTabName(AdTab.of(tabId).getLabel()) + // tab下所有的推广类型 + .setTypeList(typeList.stream().map(type -> new AdvertPlatformResDTO.APTypeDTO() + .setAdvertId(type.getAdvertId()).setTypeId(type.getTypeId()).setTypeName(AdType.of(type.getTypeId()).getLabel()) + .setDemoUrl(AdType.of(type.getTypeId()).getDemoUrl())).collect(Collectors.toList())))); + platformList.add(new AdvertPlatformResDTO().setPlatformId(platformId) + .setPlatformName(AdPlatformType.of(platformId).getLabel()) + .setTabList(tabList)); + }); + return platformList; + } + /** * 校验当前是否是超级管理员操作 */ diff --git a/xkt/src/main/resources/mapper/AdvertMapper.xml b/xkt/src/main/resources/mapper/AdvertMapper.xml index 96df3a827..baeddf9ac 100644 --- a/xkt/src/main/resources/mapper/AdvertMapper.xml +++ b/xkt/src/main/resources/mapper/AdvertMapper.xml @@ -4,5 +4,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> + \ No newline at end of file