|
|
|
|
@ -5,6 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
|
|
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
|
|
|
|
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigCreateReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigPageReqVO;
|
|
|
|
|
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO;
|
|
|
|
|
@ -12,14 +13,13 @@ import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillCo
|
|
|
|
|
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO;
|
|
|
|
|
import cn.iocoder.yudao.module.promotion.dal.mysql.seckill.seckillconfig.SeckillConfigMapper;
|
|
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
|
|
|
|
|
|
|
import javax.annotation.Resource;
|
|
|
|
|
import java.time.LocalTime;
|
|
|
|
|
import java.util.Collection;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
|
|
|
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
|
|
|
|
@ -37,9 +37,10 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|
|
|
|
private SeckillConfigMapper seckillConfigMapper;
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public Long createSeckillConfig(SeckillConfigCreateReqVO createReqVO) {
|
|
|
|
|
// 校验时间段是否冲突
|
|
|
|
|
validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime());
|
|
|
|
|
validateSeckillConfigConflict(createReqVO.getStartTime(), createReqVO.getEndTime(), null);
|
|
|
|
|
|
|
|
|
|
// 插入
|
|
|
|
|
SeckillConfigDO seckillConfig = SeckillConfigConvert.INSTANCE.convert(createReqVO);
|
|
|
|
|
@ -49,18 +50,30 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void updateSeckillConfig(SeckillConfigUpdateReqVO updateReqVO) {
|
|
|
|
|
// 校验存在
|
|
|
|
|
validateSeckillConfigExists(updateReqVO.getId());
|
|
|
|
|
// 校验时间段是否冲突
|
|
|
|
|
validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime());
|
|
|
|
|
validateSeckillConfigConflict(updateReqVO.getStartTime(), updateReqVO.getEndTime(), updateReqVO.getId());
|
|
|
|
|
|
|
|
|
|
// 更新
|
|
|
|
|
SeckillConfigDO updateObj = SeckillConfigConvert.INSTANCE.convert(updateReqVO);
|
|
|
|
|
seckillConfigMapper.updateById(updateObj);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧; 更新状态不用那么多必须的参数,更新的时候需要校验时间段
|
|
|
|
|
@Override
|
|
|
|
|
public void updateSeckillConfigStatus(Long id, Integer status) {
|
|
|
|
|
// 校验秒杀时段是否存在
|
|
|
|
|
validateSeckillConfigExists(id);
|
|
|
|
|
|
|
|
|
|
// 更新状态
|
|
|
|
|
seckillConfigMapper.updateById(new SeckillConfigDO().setId(id).setStatus(status));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
|
|
public void deleteSeckillConfig(Long id) {
|
|
|
|
|
// 校验存在
|
|
|
|
|
validateSeckillConfigExists(id);
|
|
|
|
|
@ -81,39 +94,29 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|
|
|
|
* @param startTime 开始时间
|
|
|
|
|
* @param endTime 结束时间
|
|
|
|
|
*/
|
|
|
|
|
private void validateSeckillConfigConflict(String startTime, String endTime) {
|
|
|
|
|
private void validateSeckillConfigConflict(String startTime, String endTime, Long seckillConfigId) {
|
|
|
|
|
LocalTime startTime1 = LocalTime.parse(startTime);
|
|
|
|
|
LocalTime endTime1 = LocalTime.parse(endTime);
|
|
|
|
|
// TODO @puhui999: 这个可以用 validator 里的 assertTrue 去做哈;
|
|
|
|
|
// 检查选择的时间是否相等
|
|
|
|
|
if (startTime1.equals(endTime1)) {
|
|
|
|
|
throw exception(SECKILL_TIME_EQUAL);
|
|
|
|
|
}
|
|
|
|
|
// 检查开始时间是否在结束时间之前
|
|
|
|
|
if (startTime1.isAfter(endTime1)) {
|
|
|
|
|
throw exception(SECKILL_START_TIME_BEFORE_END_TIME);
|
|
|
|
|
}
|
|
|
|
|
// 查询出所有的时段配置
|
|
|
|
|
List<SeckillConfigDO> configDOs = seckillConfigMapper.selectList();
|
|
|
|
|
// 更新时排除自己
|
|
|
|
|
if (seckillConfigId != null) {
|
|
|
|
|
configDOs.removeIf(item -> ObjectUtil.equal(item.getId(), seckillConfigId));
|
|
|
|
|
}
|
|
|
|
|
// 过滤出重叠的时段 ids
|
|
|
|
|
// TODO @puhui999:感觉 findOne 就可以了?
|
|
|
|
|
Set<Long> ids = configDOs.stream().filter((config) -> {
|
|
|
|
|
boolean hasConflict = configDOs.stream().anyMatch(config -> {
|
|
|
|
|
LocalTime startTime2 = LocalTime.parse(config.getStartTime());
|
|
|
|
|
LocalTime endTime2 = LocalTime.parse(config.getEndTime());
|
|
|
|
|
// 判断时间是否重叠
|
|
|
|
|
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配置时段的开始时间之后 []
|
|
|
|
|
// todo @puhui999:LocalDateUtils 可以写个工具类?是否是有重叠的时间?感觉别的场景,可能也会有需要
|
|
|
|
|
return startTime1.isBefore(endTime2) && endTime1.isAfter(startTime2)
|
|
|
|
|
// 开始时间在已配置时段的开始时间之前 且 结束时间在已配置时段的开始时间之后 (] 或 ()
|
|
|
|
|
|| startTime1.isBefore(startTime2) && endTime1.isAfter(startTime2)
|
|
|
|
|
// 开始时间在已配置时段的结束时间之前 且 结束时间在已配值时段的结束时间之后 [) 或 ()
|
|
|
|
|
|| startTime1.isBefore(endTime2) && endTime1.isAfter(endTime2);
|
|
|
|
|
}).map(SeckillConfigDO::getId).collect(Collectors.toSet());
|
|
|
|
|
if (CollUtil.isNotEmpty(ids)) {
|
|
|
|
|
return LocalDateTimeUtils.checkTimeOverlap(startTime1, endTime1, startTime2, endTime2);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (hasConflict) {
|
|
|
|
|
throw exception(SECKILL_TIME_CONFLICTS);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public SeckillConfigDO getSeckillConfig(Long id) {
|
|
|
|
|
return seckillConfigMapper.selectById(id);
|
|
|
|
|
@ -148,23 +151,9 @@ public class SeckillConfigServiceImpl implements SeckillConfigService {
|
|
|
|
|
return seckillConfigMapper.selectPage(pageVO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO @puhui999:写个查询状态的; 尽可能通用哈
|
|
|
|
|
@Override
|
|
|
|
|
public List<SeckillConfigDO> getListAllSimple() {
|
|
|
|
|
return seckillConfigMapper.selectList(SeckillConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO @puhui999: 这个要不合并到更新操作里? 不单独有个操作咧;
|
|
|
|
|
@Override
|
|
|
|
|
public void updateSeckillConfigStatus(Long id, Integer status) {
|
|
|
|
|
// 校验秒杀时段是否存在
|
|
|
|
|
validateSeckillConfigExists(id);
|
|
|
|
|
|
|
|
|
|
SeckillConfigDO seckillConfigDO = new SeckillConfigDO();
|
|
|
|
|
seckillConfigDO.setId(id);
|
|
|
|
|
seckillConfigDO.setStatus(status);
|
|
|
|
|
// 更新状态
|
|
|
|
|
seckillConfigMapper.updateById(seckillConfigDO);
|
|
|
|
|
return seckillConfigMapper.selectListByStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|