mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-14 21:52:07 +08:00
广告管理service、controller单元测试完善
This commit is contained in:
-16
@@ -52,20 +52,4 @@ public class RabbitMqConstants {
|
|||||||
* 生产单导入死信路由键
|
* 生产单导入死信路由键
|
||||||
*/
|
*/
|
||||||
public static final String ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY = "order_import_dead_letter_routing_key";
|
public static final String ORDER_IMPORT_DEAD_LETTER_ROUTING_KEY = "order_import_dead_letter_routing_key";
|
||||||
|
|
||||||
/**
|
|
||||||
* 广告状态修改 延迟队列
|
|
||||||
*/
|
|
||||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE = "system_advertisement_update_delayed_queue";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 广告状态修改 延迟交换机
|
|
||||||
*/
|
|
||||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE = "system_advertisement_update_delayed_exchange";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 广告状态修改 延迟路由键
|
|
||||||
*/
|
|
||||||
public static final String SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY = "system_advertisement_update_delayed_routing_key";
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ public class RandomUtils {
|
|||||||
}
|
}
|
||||||
// 如果是 type、status 结尾的字段,返回 tinyint 范围
|
// 如果是 type、status 结尾的字段,返回 tinyint 范围
|
||||||
if (CharSequenceUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(),
|
if (CharSequenceUtil.endWithAnyIgnoreCase(attributeMetadata.getAttributeName(),
|
||||||
"type", "status", "category", "scope", "result")) {
|
"type", "status", "category", "scope", "result", "sort")) {
|
||||||
return RandomUtil.randomInt(0, TINYINT_MAX + 1);
|
return RandomUtil.randomInt(0, TINYINT_MAX + 1);
|
||||||
}
|
}
|
||||||
return RandomUtil.randomInt();
|
return RandomUtil.randomInt();
|
||||||
|
|||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
package com.cf.imes.module.system.config;
|
|
||||||
|
|
||||||
import org.springframework.amqp.core.Binding;
|
|
||||||
import org.springframework.amqp.core.BindingBuilder;
|
|
||||||
import org.springframework.amqp.core.CustomExchange;
|
|
||||||
import org.springframework.amqp.core.Queue;
|
|
||||||
import org.springframework.amqp.core.QueueBuilder;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE;
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE;
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Gqr
|
|
||||||
* @since 2025/5/13 11:42
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class ChenfengRabbitMQSystemConfiguration {
|
|
||||||
/**
|
|
||||||
* 广告状态修改 延迟队列
|
|
||||||
*/
|
|
||||||
// @Bean
|
|
||||||
// public Queue advertisementUpdateDelayedQueue(){
|
|
||||||
// return QueueBuilder.durable(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_QUEUE).build();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 广告状态修改 定义延迟交换机
|
|
||||||
// */
|
|
||||||
// @Bean
|
|
||||||
// public CustomExchange advertisementUpdateDelayExchange() {
|
|
||||||
// Map<String, Object> args = new HashMap<>();
|
|
||||||
// args.put("x-delayed-type", "direct");
|
|
||||||
// return new CustomExchange(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE, "x-delayed-message", true, false, args);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 广告状态修改 队列与交换机绑定
|
|
||||||
// */
|
|
||||||
// @Bean
|
|
||||||
// public Binding advertisementUpdateQueueABindingX(@Qualifier("advertisementUpdateDelayedQueue") Queue queue,
|
|
||||||
// @Qualifier("advertisementUpdateDelayExchange") CustomExchange delayedExchange){
|
|
||||||
// return BindingBuilder.bind(queue)
|
|
||||||
// .to(delayedExchange)
|
|
||||||
// .with(SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY)
|
|
||||||
// .noargs();
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
+2
-1
@@ -4,6 +4,7 @@ import com.cf.imes.framework.common.validation.InScope;
|
|||||||
import com.cf.imes.framework.common.validation.NumberValid;
|
import com.cf.imes.framework.common.validation.NumberValid;
|
||||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementPositionEnum;
|
import com.cf.imes.module.system.enums.advertisement.AdvertisementPositionEnum;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
@@ -30,7 +31,7 @@ public class AdvertisementSaveReqVO {
|
|||||||
|
|
||||||
|
|
||||||
@Schema(description = "广告位置,字典键值", example = "[1,2]")
|
@Schema(description = "广告位置,字典键值", example = "[1,2]")
|
||||||
@NotNull(message = "广告位置不能为空")
|
@NotEmpty(message = "广告位置不能为空")
|
||||||
@InScope(value = AdvertisementPositionEnum.class, desc = "广告位置")
|
@InScope(value = AdvertisementPositionEnum.class, desc = "广告位置")
|
||||||
private List<Integer> adPosition;
|
private List<Integer> adPosition;
|
||||||
|
|
||||||
|
|||||||
-8
@@ -1,7 +1,6 @@
|
|||||||
package com.cf.imes.module.system.dal.mysql.funds.advertisement;
|
package com.cf.imes.module.system.dal.mysql.funds.advertisement;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
||||||
import com.cf.imes.framework.common.pojo.PageResult;
|
import com.cf.imes.framework.common.pojo.PageResult;
|
||||||
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
import com.cf.imes.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
@@ -41,13 +40,6 @@ public interface AdvertisementMapper extends BaseMapperX<AdvertisementDO> {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default int updateAdStatus(Long id, Integer newStatus) {
|
|
||||||
return update(new LambdaUpdateWrapper<AdvertisementDO>()
|
|
||||||
.set(AdvertisementDO::getStatus, newStatus)
|
|
||||||
.eq(AdvertisementDO::getId, id)
|
|
||||||
.eq(AdvertisementDO::getDeleted, false));
|
|
||||||
}
|
|
||||||
|
|
||||||
default List<AdvertisementDO> selectList(LocalDateTime now, Integer status) {
|
default List<AdvertisementDO> selectList(LocalDateTime now, Integer status) {
|
||||||
return selectList(new LambdaQueryWrapperX<AdvertisementDO>()
|
return selectList(new LambdaQueryWrapperX<AdvertisementDO>()
|
||||||
.le(AdvertisementDO::getStartTime, now)
|
.le(AdvertisementDO::getStartTime, now)
|
||||||
|
|||||||
-83
@@ -1,83 +0,0 @@
|
|||||||
package com.cf.imes.module.system.mq.producer.advertisement;
|
|
||||||
|
|
||||||
import com.cf.imes.module.system.mq.message.advertisement.AdvertisementSendMessage;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronization;
|
|
||||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE;
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Advertisement 广告相关消息的 Producer
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class AdvertisementProducer {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送 {@link AdvertisementSendMessage} 消息
|
|
||||||
*
|
|
||||||
* @param adId 广告id
|
|
||||||
* @param action 类型
|
|
||||||
* @param triggerTime 到期时间
|
|
||||||
*/
|
|
||||||
|
|
||||||
public String sendAdvertisementSendMessage(Long adId, String action, LocalDate triggerTime) {
|
|
||||||
|
|
||||||
String messageId = UUID.randomUUID().toString();
|
|
||||||
|
|
||||||
|
|
||||||
long delay = Duration.between(LocalDateTime.now(), triggerTime).toMillis();
|
|
||||||
|
|
||||||
if (delay > 0) {
|
|
||||||
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
|
|
||||||
AdvertisementSendMessage message = new AdvertisementSendMessage(adId, messageId, action);
|
|
||||||
|
|
||||||
if (TransactionSynchronizationManager.isActualTransactionActive()) {
|
|
||||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
||||||
@Override
|
|
||||||
public void afterCommit() {
|
|
||||||
// 数据库操作全部完成发送消息
|
|
||||||
rabbitTemplate.convertAndSend(
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
|
||||||
message,
|
|
||||||
correlationData -> {
|
|
||||||
correlationData.getMessageProperties().setMessageId(messageId);
|
|
||||||
correlationData.getMessageProperties().setDelayLong(Long.valueOf(delay));
|
|
||||||
return correlationData;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// 数据库操作全部完成发送消息
|
|
||||||
rabbitTemplate.convertAndSend(
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
|
||||||
message,
|
|
||||||
correlationData -> {
|
|
||||||
correlationData.getMessageProperties().setMessageId(messageId);
|
|
||||||
correlationData.getMessageProperties().setDelayLong(Long.valueOf(delay));
|
|
||||||
return correlationData;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return messageId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-117
@@ -1,117 +0,0 @@
|
|||||||
package com.cf.imes.module.system.service.funds.advertisement;
|
|
||||||
|
|
||||||
import com.alibaba.nacos.common.utils.StringUtils;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
||||||
import com.cf.imes.module.system.dal.dataobject.funds.advertisement.AdvertisementDO;
|
|
||||||
import com.cf.imes.module.system.dal.dataobject.funds.advertisement.AdvertisementTaskDO;
|
|
||||||
import com.cf.imes.module.system.dal.mysql.funds.advertisement.AdvertisementMapper;
|
|
||||||
import com.cf.imes.module.system.dal.mysql.funds.advertisement.AdvertisementTaskMapper;
|
|
||||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
|
||||||
import com.cf.imes.module.system.enums.advertisement.MessageStatusEnum;
|
|
||||||
import com.cf.imes.module.system.mq.message.advertisement.AdvertisementSendMessage;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.context.request.RequestContextHolder;
|
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE;
|
|
||||||
import static com.cf.imes.framework.mq.rabbitmq.constant.RabbitMqConstants.SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 广告状态修改 Service 实现类
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
@Slf4j
|
|
||||||
public class AdvertisementCompensateTask {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private AdvertisementMapper advertisementMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private AdvertisementTaskMapper advertisementTaskMapper;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private RabbitTemplate rabbitTemplate;
|
|
||||||
|
|
||||||
|
|
||||||
//=== 补偿任务 ===//
|
|
||||||
// @Scheduled(cron = "0 0/30 * * * ?")
|
|
||||||
public void checkAdStatusConsistency() {
|
|
||||||
// 1. 检查应发布但未发布的广告
|
|
||||||
List<AdvertisementDO> unpublishedAds = advertisementMapper.selectList(LocalDate.now().atStartOfDay(), AdvertisementStatusEnum.UNPUBLISHED.getStatus());
|
|
||||||
unpublishedAds.forEach(ad -> {
|
|
||||||
updateAdStatus(ad, AdvertisementStatusEnum.PUBLISHED.getStatus());
|
|
||||||
rescheduleExpireMessage(ad);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. 检查应结束但未结束的广告
|
|
||||||
List<AdvertisementDO> publishedAds = advertisementMapper.selectList(
|
|
||||||
new QueryWrapper<AdvertisementDO>()
|
|
||||||
.le("end_time", LocalDateTime.now())
|
|
||||||
.eq("status", AdvertisementStatusEnum.PUBLISHED.getStatus())
|
|
||||||
);
|
|
||||||
publishedAds.forEach(ad -> updateAdStatus(ad, AdvertisementStatusEnum.ENDED.getStatus()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void rescheduleExpireMessage(AdvertisementDO ad) {
|
|
||||||
if (ad.getEndTime().isAfter(LocalDate.now())) {
|
|
||||||
String newMsgId = sendSingleMessage(ad.getId(), "expire", ad.getEndTime().atStartOfDay());
|
|
||||||
trackMessage(ad.getId(), newMsgId, AdvertisementStatusEnum.PUBLISHED.getStatus(), MessageStatusEnum.CANCELLED.getStatus());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAdStatus(AdvertisementDO ad, Integer newStatus) {
|
|
||||||
advertisementMapper.updateAdStatus(ad.getId(), newStatus);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送单个延迟消息
|
|
||||||
*/
|
|
||||||
private String sendSingleMessage(Long adId, String action, LocalDateTime triggerTime) {
|
|
||||||
String messageId = UUID.randomUUID().toString();
|
|
||||||
long delay = Duration.between(LocalDateTime.now(), triggerTime).toMillis();
|
|
||||||
|
|
||||||
|
|
||||||
if (delay > 0) {
|
|
||||||
RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true);
|
|
||||||
|
|
||||||
rabbitTemplate.convertAndSend(
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_EXCHANGE,
|
|
||||||
SYSTEM_ADVERTISEMENT_UPDATE_DELAYED_ROUTING_KEY,
|
|
||||||
new AdvertisementSendMessage(adId, messageId, action),
|
|
||||||
correlationData -> {
|
|
||||||
correlationData.getMessageProperties().setMessageId(messageId);
|
|
||||||
correlationData.getMessageProperties().setDelayLong(Long.valueOf(delay));
|
|
||||||
return correlationData;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return messageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 记录消息追踪
|
|
||||||
*/
|
|
||||||
private void trackMessage(Long adId, String messageId, Integer advertisementStatus, Integer messageStatus) {
|
|
||||||
if (StringUtils.isNotBlank(messageId)) {
|
|
||||||
advertisementTaskMapper.insert(new AdvertisementTaskDO()
|
|
||||||
.setAdvertisementId(adId)
|
|
||||||
.setMessageId(messageId)
|
|
||||||
.setMessageStatus(messageStatus)
|
|
||||||
.setAdvertisementStatus(advertisementStatus)
|
|
||||||
);
|
|
||||||
log.info("[trackMessage][adId({}) messageId({}) 记录消息追踪成功]", adId, messageId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+7
-14
@@ -14,7 +14,6 @@ import com.cf.imes.module.system.dal.mysql.funds.advertisement.AdvertisementMapp
|
|||||||
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@@ -38,9 +37,6 @@ import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
public class AdvertisementServiceImpl implements AdvertisementService{
|
public class AdvertisementServiceImpl implements AdvertisementService{
|
||||||
|
|
||||||
@Value("${chenfeng.info.name}")
|
|
||||||
private String SOFT_WARE_ID; // 获取软件标识-可修改
|
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private AdvertisementMapper advertisementMapper;
|
private AdvertisementMapper advertisementMapper;
|
||||||
|
|
||||||
@@ -49,7 +45,6 @@ public class AdvertisementServiceImpl implements AdvertisementService{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public Long create(AdvertisementSaveReqVO createReqVO) {
|
public Long create(AdvertisementSaveReqVO createReqVO) {
|
||||||
|
|
||||||
if (createReqVO.getStartTime().isAfter(createReqVO.getEndTime())) {
|
if (createReqVO.getStartTime().isAfter(createReqVO.getEndTime())) {
|
||||||
@@ -64,8 +59,7 @@ public class AdvertisementServiceImpl implements AdvertisementService{
|
|||||||
// 插入广告
|
// 插入广告
|
||||||
AdvertisementDO advertisementDO = BeanUtils.toBean(createReqVO, AdvertisementDO.class)
|
AdvertisementDO advertisementDO = BeanUtils.toBean(createReqVO, AdvertisementDO.class)
|
||||||
.setAdPosition(createReqVO.getAdPosition().stream().sorted().distinct().toList())
|
.setAdPosition(createReqVO.getAdPosition().stream().sorted().distinct().toList())
|
||||||
.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus())
|
.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus());
|
||||||
.setSoftwareId(SOFT_WARE_ID);
|
|
||||||
|
|
||||||
advertisementMapper.insert(advertisementDO);
|
advertisementMapper.insert(advertisementDO);
|
||||||
|
|
||||||
@@ -78,8 +72,11 @@ public class AdvertisementServiceImpl implements AdvertisementService{
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
|
||||||
public void update(AdvertisementSaveReqVO reqVO) {
|
public void update(AdvertisementSaveReqVO reqVO) {
|
||||||
|
if (reqVO.getStartTime().isAfter(reqVO.getEndTime())) {
|
||||||
|
throw exception(ADVERTISEMENT_TIME_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
Long id = reqVO.getId();
|
Long id = reqVO.getId();
|
||||||
// 确认广告是否存在
|
// 确认广告是否存在
|
||||||
AdvertisementDO advertisementDO = validateAdvertisementExists(id);
|
AdvertisementDO advertisementDO = validateAdvertisementExists(id);
|
||||||
@@ -94,18 +91,14 @@ public class AdvertisementServiceImpl implements AdvertisementService{
|
|||||||
|
|
||||||
AssertUtils.empty(aDo, ADVERTISEMENT_NAME_IS_EXIST);
|
AssertUtils.empty(aDo, ADVERTISEMENT_NAME_IS_EXIST);
|
||||||
|
|
||||||
if (reqVO.getStartTime().isAfter(reqVO.getEndTime())) {
|
|
||||||
throw exception(ADVERTISEMENT_TIME_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新内容
|
// 更新内容
|
||||||
advertisementDO.setAdName(reqVO.getAdName())
|
advertisementDO.setAdName(reqVO.getAdName())
|
||||||
.setAdImagePath(reqVO.getAdImagePath())
|
.setAdImagePath(reqVO.getAdImagePath())
|
||||||
.setStartTime(reqVO.getStartTime())
|
.setStartTime(reqVO.getStartTime())
|
||||||
.setEndTime(reqVO.getEndTime())
|
.setEndTime(reqVO.getEndTime())
|
||||||
.setAdPosition(reqVO.getAdPosition().stream().sorted().distinct().toList())
|
.setAdPosition(reqVO.getAdPosition().stream().sorted().distinct().toList())
|
||||||
.setSort(ObjectUtil.isNull(reqVO.getSort()) ? advertisementDO.getSort() : reqVO.getSort())
|
.setSort(ObjectUtil.defaultIfNull(reqVO.getSort(), advertisementDO.getSort()))
|
||||||
.setAdRedirectUrl(StringUtils.isEmpty(reqVO.getAdRedirectUrl()) ? advertisementDO.getAdRedirectUrl() : reqVO.getAdRedirectUrl());
|
.setAdRedirectUrl(StringUtils.defaultIfEmpty(reqVO.getAdRedirectUrl(), advertisementDO.getAdRedirectUrl()));
|
||||||
advertisementMapper.updateById(advertisementDO);
|
advertisementMapper.updateById(advertisementDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@
|
|||||||
ad_redirect_url
|
ad_redirect_url
|
||||||
from advertisement
|
from advertisement
|
||||||
where deleted = false
|
where deleted = false
|
||||||
and find_in_set (#{adPosition}, ad_position)
|
and CONCAT(',', ad_position, ',') like concat('%,', #{adPosition}, ',%')
|
||||||
and status = #{status}
|
and status = #{status}
|
||||||
and start_time <= #{now}
|
and start_time <= #{now}
|
||||||
and end_time >= #{now}
|
and end_time >= #{now}
|
||||||
|
|||||||
+201
@@ -0,0 +1,201 @@
|
|||||||
|
package com.cf.imes.module.system.controller.admin.funds.advertisement;
|
||||||
|
|
||||||
|
import com.cf.imes.framework.common.pojo.PageResult;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementPageReqVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementRePublishReqVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementRespVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementSaveReqVO;
|
||||||
|
import com.cf.imes.module.system.service.funds.advertisement.AdvertisementService;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gqr
|
||||||
|
* @since 2025/10/28 15:05
|
||||||
|
*/
|
||||||
|
@WebMvcTest(controllers = AdvertisementController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
|
||||||
|
public class AdvertisementControllerTest {
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
private AdvertisementService advertisementService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCreateAdvertisement() throws Exception {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setAdName("测试广告");
|
||||||
|
reqVO.setAdPosition(List.of(1));
|
||||||
|
reqVO.setAdImagePath("test.jpg");
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
reqVO.setStartTime(now);
|
||||||
|
reqVO.setEndTime(now.plusDays(1));
|
||||||
|
|
||||||
|
when(advertisementService.create(any())).thenReturn(101L);
|
||||||
|
|
||||||
|
mockMvc.perform(put("/system/ad")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(reqVO)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(101));
|
||||||
|
|
||||||
|
verify(advertisementService).create(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUpdateAdvertisement() throws Exception {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setId(1L);
|
||||||
|
reqVO.setAdName("测试更新广告");
|
||||||
|
reqVO.setAdPosition(List.of(1));
|
||||||
|
reqVO.setAdImagePath("test.jpg");
|
||||||
|
LocalDate now = LocalDate.now();
|
||||||
|
reqVO.setStartTime(now);
|
||||||
|
reqVO.setEndTime(now.plusDays(1));
|
||||||
|
|
||||||
|
doNothing().when(advertisementService).update(any());
|
||||||
|
|
||||||
|
mockMvc.perform(post("/system/ad")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(reqVO)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(advertisementService).update(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUploadAdImage() throws Exception {
|
||||||
|
MockMultipartFile file = new MockMultipartFile("file", "ad.png", "image/png", "test data".getBytes());
|
||||||
|
when(advertisementService.uploadAdImage(any())).thenReturn("https://cdn.example.com/ad.png");
|
||||||
|
|
||||||
|
mockMvc.perform(multipart("/system/ad/image")
|
||||||
|
.file(file).contentType(MediaType.MULTIPART_FORM_DATA))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value("https://cdn.example.com/ad.png"));
|
||||||
|
|
||||||
|
verify(advertisementService).uploadAdImage(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testDeleteAdvertisement() throws Exception {
|
||||||
|
mockMvc.perform(delete("/system/ad/{id}", 1L))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(advertisementService).delete(1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetAdvertisement() throws Exception {
|
||||||
|
AdvertisementRespVO respVO = new AdvertisementRespVO();
|
||||||
|
respVO.setId(1L);
|
||||||
|
respVO.setAdName("首页广告");
|
||||||
|
|
||||||
|
when(advertisementService.get(1L)).thenReturn(respVO);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/system/ad/{id}", 1L))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data.id").value(1L))
|
||||||
|
.andExpect(jsonPath("$.data.adName").value("首页广告"));
|
||||||
|
|
||||||
|
verify(advertisementService).get(1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetAdvertisementPage() throws Exception {
|
||||||
|
AdvertisementPageReqVO reqVO = new AdvertisementPageReqVO();
|
||||||
|
PageResult<AdvertisementRespVO> mockPage = new PageResult<>();
|
||||||
|
mockPage.setTotal(1L);
|
||||||
|
mockPage.setList(List.of(new AdvertisementRespVO().setId(1L).setAdName("分页广告")));
|
||||||
|
when(advertisementService.getPage(any())).thenReturn(mockPage);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/system/ad/page")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(reqVO)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data.list[0].id").value(1L))
|
||||||
|
.andExpect(jsonPath("$.data.list[0].adName").value("分页广告"));
|
||||||
|
|
||||||
|
verify(advertisementService, times(1)).getPage(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testGetAdvertisementByPosition() throws Exception {
|
||||||
|
AdvertisementRespVO respVO = new AdvertisementRespVO();
|
||||||
|
respVO.setId(1L);
|
||||||
|
respVO.setAdName("首页banner");
|
||||||
|
|
||||||
|
when(advertisementService.getAdvertisementByPosition(1))
|
||||||
|
.thenReturn(Collections.singletonList(respVO));
|
||||||
|
|
||||||
|
mockMvc.perform(get("/system/ad/position/page")
|
||||||
|
.param("adPosition", "1"))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data[0].id").value(1L))
|
||||||
|
.andExpect(jsonPath("$.data[0].adName").value("首页banner"));
|
||||||
|
|
||||||
|
verify(advertisementService).getAdvertisementByPosition(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPublish() throws Exception {
|
||||||
|
mockMvc.perform(post("/system/ad/publish/{id}", 1L))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(advertisementService).publish(1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testEndPublish() throws Exception {
|
||||||
|
mockMvc.perform(post("/system/ad/endPublish/{id}", 1L))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(advertisementService).endPublish(1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testRePublish() throws Exception {
|
||||||
|
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
|
||||||
|
reqVO.setId(1L);
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
|
||||||
|
mockMvc.perform(post("/system/ad/republish")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(objectMapper.writeValueAsString(reqVO)))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.data").value(true));
|
||||||
|
|
||||||
|
verify(advertisementService).republish(any());
|
||||||
|
}
|
||||||
|
}
|
||||||
+368
@@ -0,0 +1,368 @@
|
|||||||
|
package com.cf.imes.module.system.service.funds.advertisement;
|
||||||
|
|
||||||
|
import com.cf.imes.framework.common.pojo.PageResult;
|
||||||
|
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
|
||||||
|
import com.cf.imes.module.infra.api.file.FileApi;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementPageReqVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementRePublishReqVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementRespVO;
|
||||||
|
import com.cf.imes.module.system.controller.admin.funds.advertisement.vo.AdvertisementSaveReqVO;
|
||||||
|
import com.cf.imes.module.system.dal.dataobject.funds.advertisement.AdvertisementDO;
|
||||||
|
import com.cf.imes.module.system.dal.mysql.funds.advertisement.AdvertisementMapper;
|
||||||
|
import com.cf.imes.module.system.enums.advertisement.AdvertisementStatusEnum;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
|
import org.junit.jupiter.api.Order;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
|
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_IMAGE_EMPTY_ERROR;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_IMAGE_UPLOAD_FAIL;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_NAME_IS_EXIST;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_NO_DELETE;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_NO_EXIST;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_STATUS_ENDTIME_EXPIRED;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_TIME_ERROR;
|
||||||
|
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ADVERTISEMENT_UPDATE_STATUS_ERROR;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gqr
|
||||||
|
* @since 2025/10/28 10:15
|
||||||
|
*/
|
||||||
|
@Import(AdvertisementServiceImpl.class)
|
||||||
|
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||||
|
public class AdvertisementServiceImplTest extends BaseDbAndRedisUnitTest {
|
||||||
|
@Resource
|
||||||
|
private AdvertisementService advertisementService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AdvertisementMapper advertisementMapper;
|
||||||
|
|
||||||
|
@MockitoBean
|
||||||
|
private FileApi fileApi;
|
||||||
|
|
||||||
|
private static AdvertisementDO insertedOne;
|
||||||
|
|
||||||
|
private static Long insertTwoId;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(1)
|
||||||
|
void testCreate_whenStartTimeAfterEndTime_shouldThrow() {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setStartTime(LocalDate.now().plusDays(1));
|
||||||
|
reqVO.setEndTime(LocalDate.now());
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.create(reqVO), ADVERTISEMENT_TIME_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(2)
|
||||||
|
void testCreate_whenAdNameExists() {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
reqVO.setAdName("TestAd");
|
||||||
|
|
||||||
|
AdvertisementDO existing = randomPojo(AdvertisementDO.class, o -> o.setAdName("TestAd"));
|
||||||
|
advertisementMapper.insert(existing);
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.create(reqVO), ADVERTISEMENT_NAME_IS_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(3)
|
||||||
|
void testCreate_success() {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
reqVO.setAdName("Ad-CREATE-1");
|
||||||
|
reqVO.setAdPosition(List.of(3, 1, 3));
|
||||||
|
reqVO.setAdImagePath("https://example.com/image.png");
|
||||||
|
|
||||||
|
Long id = advertisementService.create(reqVO);
|
||||||
|
|
||||||
|
insertedOne = advertisementMapper.selectById(id);
|
||||||
|
|
||||||
|
// 验证id
|
||||||
|
assertEquals(insertedOne.getId(), id);
|
||||||
|
// 验证 adPosition 去重排序
|
||||||
|
assertEquals(List.of(1, 3), insertedOne.getAdPosition());
|
||||||
|
// 验证状态
|
||||||
|
assertEquals(AdvertisementStatusEnum.UNPUBLISHED.getStatus(), insertedOne.getStatus());
|
||||||
|
// 验证名称
|
||||||
|
assertEquals("Ad-CREATE-1", insertedOne.getAdName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(4)
|
||||||
|
void testUpdate_whenStartTimeAfterEndTime() {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setStartTime(LocalDate.now().plusDays(1));
|
||||||
|
reqVO.setEndTime(LocalDate.now());
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.update(reqVO), ADVERTISEMENT_TIME_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
void testUpdate_adExist(){
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setId(123L);
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
assertServiceException(() -> advertisementService.update(reqVO), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(5)
|
||||||
|
void testUpdate_whenAdNameExists() {
|
||||||
|
AdvertisementSaveReqVO reqVO = new AdvertisementSaveReqVO();
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
reqVO.setAdName("Ad-CREATE-2");
|
||||||
|
reqVO.setAdPosition(List.of(3, 1, 3));
|
||||||
|
reqVO.setAdImagePath("https://example.com/image.png");
|
||||||
|
|
||||||
|
insertTwoId = advertisementService.create(reqVO);
|
||||||
|
|
||||||
|
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
|
||||||
|
updateReqVO.setId(insertedOne.getId());
|
||||||
|
updateReqVO.setStartTime(LocalDate.now());
|
||||||
|
updateReqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
updateReqVO.setAdName("Ad-CREATE-2");
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.update(updateReqVO), ADVERTISEMENT_NAME_IS_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(6)
|
||||||
|
void testUpdate_success() {
|
||||||
|
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
|
||||||
|
updateReqVO.setId(insertedOne.getId());
|
||||||
|
updateReqVO.setStartTime(LocalDate.now());
|
||||||
|
updateReqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
updateReqVO.setAdName("Ad-UPDATE-1");
|
||||||
|
updateReqVO.setAdPosition(List.of(1,3));
|
||||||
|
updateReqVO.setAdImagePath("https://example.com/image.jpg");
|
||||||
|
|
||||||
|
advertisementService.update(updateReqVO);
|
||||||
|
|
||||||
|
AdvertisementDO db = advertisementMapper.selectById(insertedOne.getId());
|
||||||
|
assertEquals(db.getAdName(), "Ad-UPDATE-1");
|
||||||
|
assertEquals(db.getAdPosition(), List.of(1,3));
|
||||||
|
assertEquals(db.getAdImagePath(), "https://example.com/image.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(7)
|
||||||
|
void testDelete_notExist() {
|
||||||
|
assertServiceException(() -> advertisementService.delete(123L), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(8)
|
||||||
|
void testPublish_notExist(){
|
||||||
|
assertServiceException(() -> advertisementService.publish(123L), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(9)
|
||||||
|
void testUpdate_endTime_success() {
|
||||||
|
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
|
||||||
|
updateReqVO.setId(insertTwoId);
|
||||||
|
updateReqVO.setStartTime(LocalDate.now().minusDays(5));
|
||||||
|
updateReqVO.setEndTime(LocalDate.now().minusDays(4));
|
||||||
|
updateReqVO.setAdName("Ad-UPDATE-2");
|
||||||
|
updateReqVO.setAdPosition(List.of(2));
|
||||||
|
|
||||||
|
assertDoesNotThrow(() -> advertisementService.update(updateReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(10)
|
||||||
|
void testPublish_endtime_expired() {
|
||||||
|
assertServiceException(() -> advertisementService.publish(insertTwoId), ADVERTISEMENT_STATUS_ENDTIME_EXPIRED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(11)
|
||||||
|
void testPublish_success() {
|
||||||
|
advertisementService.publish(insertedOne.getId());
|
||||||
|
|
||||||
|
AdvertisementDO db = advertisementMapper.selectById(insertedOne.getId());
|
||||||
|
assertEquals(db.getStatus(), AdvertisementStatusEnum.PUBLISHED.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(12)
|
||||||
|
void testUpdate_published() {
|
||||||
|
AdvertisementSaveReqVO updateReqVO = new AdvertisementSaveReqVO();
|
||||||
|
updateReqVO.setId(insertedOne.getId());
|
||||||
|
updateReqVO.setStartTime(LocalDate.now());
|
||||||
|
updateReqVO.setEndTime(LocalDate.now());
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.update(updateReqVO), ADVERTISEMENT_UPDATE_STATUS_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(13)
|
||||||
|
void testDelete_published() {
|
||||||
|
assertServiceException(() -> advertisementService.delete(insertedOne.getId()), ADVERTISEMENT_NO_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(14)
|
||||||
|
void testEndPublish_notExist() {
|
||||||
|
assertServiceException(() -> advertisementService.endPublish(null), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(15)
|
||||||
|
void testGet_notExist() {
|
||||||
|
assertServiceException(() -> advertisementService.get(123L), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(16)
|
||||||
|
void testGet() {
|
||||||
|
assertNotNull(advertisementService.get(insertedOne.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(17)
|
||||||
|
void testGetByPosition() {
|
||||||
|
List<AdvertisementRespVO> advertisementRespVOS = advertisementService.getAdvertisementByPosition(1);
|
||||||
|
assertEquals(1, advertisementRespVOS.size());
|
||||||
|
|
||||||
|
|
||||||
|
advertisementRespVOS = advertisementService.getAdvertisementByPosition(2);
|
||||||
|
assertEquals(0, advertisementRespVOS.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(18)
|
||||||
|
void testEndPublish() {
|
||||||
|
advertisementService.endPublish(insertTwoId);
|
||||||
|
|
||||||
|
AdvertisementDO db = advertisementMapper.selectById(insertTwoId);
|
||||||
|
assertEquals(db.getStatus(), AdvertisementStatusEnum.ENDED.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(19)
|
||||||
|
void testGetPage(){
|
||||||
|
AdvertisementPageReqVO pageReqVO = new AdvertisementPageReqVO();
|
||||||
|
pageReqVO.setStatus(AdvertisementStatusEnum.PUBLISHED.getStatus());
|
||||||
|
pageReqVO.setAdName("Ad-UPDATE-1");
|
||||||
|
|
||||||
|
PageResult<AdvertisementRespVO> page = advertisementService.getPage(pageReqVO);
|
||||||
|
assertEquals(1, page.getTotal());
|
||||||
|
|
||||||
|
pageReqVO.setStatus(AdvertisementStatusEnum.ENDED.getStatus());
|
||||||
|
pageReqVO.setAdName("Ad-UPDATE-2");
|
||||||
|
page = advertisementService.getPage(pageReqVO);
|
||||||
|
assertEquals(1, page.getTotal());
|
||||||
|
|
||||||
|
pageReqVO.setStatus(AdvertisementStatusEnum.UNPUBLISHED.getStatus());
|
||||||
|
page = advertisementService.getPage(pageReqVO);
|
||||||
|
assertEquals(0, page.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(20)
|
||||||
|
void testDelete_success() {
|
||||||
|
advertisementService.delete(insertTwoId);
|
||||||
|
AdvertisementDO db = advertisementMapper.selectById(insertTwoId);
|
||||||
|
assertNull(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(21)
|
||||||
|
void testRepublish_notExist() {
|
||||||
|
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
|
||||||
|
reqVO.setId(null);
|
||||||
|
assertServiceException(() -> advertisementService.republish(reqVO), ADVERTISEMENT_NO_EXIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(22)
|
||||||
|
void testRepublish_time_error() {
|
||||||
|
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
|
||||||
|
reqVO.setId(insertedOne.getId());
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().minusDays(1));
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.republish(reqVO), ADVERTISEMENT_TIME_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Order(23)
|
||||||
|
void testRepublish_success() {
|
||||||
|
AdvertisementRePublishReqVO reqVO = new AdvertisementRePublishReqVO();
|
||||||
|
reqVO.setId(insertedOne.getId());
|
||||||
|
reqVO.setStartTime(LocalDate.now());
|
||||||
|
reqVO.setEndTime(LocalDate.now().plusDays(1));
|
||||||
|
|
||||||
|
advertisementService.republish(reqVO);
|
||||||
|
assertEquals(AdvertisementStatusEnum.PUBLISHED.getStatus(), advertisementMapper.selectById(insertedOne.getId()).getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUploadAdImage_success() throws IOException {
|
||||||
|
// 模拟文件
|
||||||
|
MultipartFile file = mock(MultipartFile.class);
|
||||||
|
when(file.isEmpty()).thenReturn(false);
|
||||||
|
when(file.getBytes()).thenReturn("test".getBytes());
|
||||||
|
|
||||||
|
// 模拟 fileApi 返回路径
|
||||||
|
when(fileApi.createFile(any(byte[].class))).thenReturn("/path/to/file.jpg");
|
||||||
|
|
||||||
|
String result = advertisementService.uploadAdImage(file);
|
||||||
|
|
||||||
|
assertEquals("/path/to/file.jpg", result);
|
||||||
|
verify(fileApi, times(1)).createFile(any(byte[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUploadAdImage_emptyFile() {
|
||||||
|
MultipartFile file = mock(MultipartFile.class);
|
||||||
|
when(file.isEmpty()).thenReturn(true);
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.uploadAdImage(file), ADVERTISEMENT_IMAGE_EMPTY_ERROR);
|
||||||
|
|
||||||
|
verify(fileApi, never()).createFile(any(byte[].class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testUploadAdImage_ioException() throws IOException {
|
||||||
|
MultipartFile file = mock(MultipartFile.class);
|
||||||
|
// 模拟非空文件
|
||||||
|
when(file.isEmpty()).thenReturn(false);
|
||||||
|
|
||||||
|
// 模拟 getBytes() 抛出 IOException
|
||||||
|
when(file.getBytes()).thenThrow(new IOException("io error"));
|
||||||
|
|
||||||
|
assertServiceException(() -> advertisementService.uploadAdImage(file), ADVERTISEMENT_IMAGE_UPLOAD_FAIL);
|
||||||
|
|
||||||
|
verify(fileApi, never()).createFile(any(byte[].class));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -731,3 +731,22 @@ CREATE TABLE IF NOT EXISTS "gift_money_details" (
|
|||||||
"deleted" BIT NOT NULL DEFAULT FALSE COMMENT '是否删除:0否 1是',
|
"deleted" BIT NOT NULL DEFAULT FALSE COMMENT '是否删除:0否 1是',
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT '赠送金规则明细表(base表)';
|
) COMMENT '赠送金规则明细表(base表)';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "advertisement" (
|
||||||
|
"id" BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY COMMENT '主键,根据ID号规则生成',
|
||||||
|
"ad_name" VARCHAR(32) NOT NULL COMMENT '广告名称',
|
||||||
|
"software_id" VARCHAR(32) NOT NULL DEFAULT '1' COMMENT '软件id,不同软件的标识',
|
||||||
|
"ad_position" VARCHAR(64) NOT NULL COMMENT '广告位置,0首页工作台轮播 1系统管理余额查询轮播 2基础配置资金查询轮播(多选)',
|
||||||
|
"ad_image_path" VARCHAR(255) NOT NULL COMMENT '广告图片路径',
|
||||||
|
"start_time" DATE NOT NULL COMMENT '投放开始时间',
|
||||||
|
"end_time" DATE NOT NULL COMMENT '投放结束时间',
|
||||||
|
"ad_redirect_url" VARCHAR(255) DEFAULT NULL COMMENT '广告跳转链接',
|
||||||
|
"sort" SMALLINT DEFAULT 0 COMMENT '顺序',
|
||||||
|
"status" TINYINT DEFAULT 0 NOT NULL COMMENT '广告状态,0未发布 1已发布 2已结束',
|
||||||
|
"creator" VARCHAR(64) DEFAULT NULL COMMENT '创建者/操作人',
|
||||||
|
"create_time" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间/操作时间',
|
||||||
|
"updater" VARCHAR(64) DEFAULT NULL COMMENT '更新者',
|
||||||
|
"update_time" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '更新时间',
|
||||||
|
"deleted" BIT DEFAULT FALSE NOT NULL COMMENT '是否删除,0否1是',
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '广告表 advertisement';
|
||||||
|
|||||||
Reference in New Issue
Block a user