mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-14 10:11:53 +08:00
Merge remote-tracking branch 'origin/master' into feature/auth
# Conflicts: # yudao-dependencies/pom.xml
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BARGAIN_ACTIVITY_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 砍价活动 Api 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
public class BargainActivityApiImpl implements BargainActivityApi {
|
||||
|
||||
@Resource
|
||||
private BargainActivityService bargainActivityService;
|
||||
|
||||
@Override
|
||||
public void updateBargainActivityStock(Long activityId, Integer count) {
|
||||
// TODO @puhui999:可以整个实现到 bargainActivityService 中
|
||||
// 查询砍价活动
|
||||
BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId);
|
||||
if (activity == null) {
|
||||
throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
|
||||
}
|
||||
|
||||
// 更新砍价库存
|
||||
// TODO @puhui999:考虑下并发更新问题
|
||||
BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO();
|
||||
reqVO.setId(activityId);
|
||||
reqVO.setStock(activity.getStock() - count);
|
||||
bargainActivityService.updateBargainActivity(reqVO);
|
||||
}
|
||||
|
||||
}
|
@@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.promotion.api.combination;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -43,12 +43,19 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO) {
|
||||
if (null == reqDTO.getStartTime()) {
|
||||
recordService.updateCombinationRecordStatusByUserIdAndOrderId(reqDTO);
|
||||
} else {
|
||||
recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(reqDTO);
|
||||
}
|
||||
public void updateRecordStatusToSuccess(Long userId, Long orderId) {
|
||||
recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRecordStatusToFailed(Long userId, Long orderId) {
|
||||
recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.FAILED.getStatus(), userId, orderId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime) {
|
||||
recordService.updateRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordStatusEnum.IN_PROGRESS.getStatus(),
|
||||
userId, orderId, startTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,84 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_UPDATE_STOCK_FAIL;
|
||||
|
||||
/**
|
||||
* 秒杀活动接口 Api 接口实现类
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
@Service
|
||||
public class SeckillActivityApiImpl implements SeckillActivityApi {
|
||||
|
||||
@Resource
|
||||
private SeckillActivityService activityService;
|
||||
|
||||
// TODO @puhui:建议这块弄到 activityService 实现哈;
|
||||
// TODO @puhui:这个方法,要考虑事务性
|
||||
@Override
|
||||
public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
|
||||
// TODO @puhui999:长方法,最好有 1.1 1.2 2.1 这种步骤哈;
|
||||
SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId());
|
||||
if (seckillActivity.getStock() < updateStockReqDTO.getCount()) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
// 获取活动商品
|
||||
// TODO @puhui999:在一个方法里,dos 和 dolist 最好保持一致,要么用 s,要么用 list 哈;
|
||||
List<SeckillProductDO> productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId());
|
||||
// TODO @puhui999:这个是不是搞成 CollectionUtils.convertMultiMap()
|
||||
List<SeckillActivityUpdateStockReqDTO.Item> items = updateStockReqDTO.getItems();
|
||||
Map<Long, List<Long>> map = new HashMap<>();
|
||||
items.forEach(item -> {
|
||||
if (map.containsKey(item.getSpuId())) {
|
||||
List<Long> skuIds = map.get(item.getSpuId());
|
||||
skuIds.add(item.getSkuId());
|
||||
map.put(item.getSpuId(), skuIds);
|
||||
} else {
|
||||
List<Long> list = new ArrayList<>();
|
||||
list.add(item.getSkuId());
|
||||
map.put(item.getSpuId(), list);
|
||||
}
|
||||
});
|
||||
// 过滤出购买的商品
|
||||
// TODO @puhui999:productDOList 可以简化成 productList;一般来说,do 之类不用带着哈,在变量里;
|
||||
List<SeckillProductDO> productDOList = CollectionUtils.filterList(productDOs, item -> map.get(item.getSpuId()).contains(item.getSkuId()));
|
||||
Map<Long, SeckillActivityUpdateStockReqDTO.Item> productDOMap = CollectionUtils.convertMap(items, SeckillActivityUpdateStockReqDTO.Item::getSkuId, p -> p);
|
||||
// 检查活动商品库存是否充足
|
||||
// TODO @puhui999:避免 b 这种无业务含义的变量;
|
||||
boolean b = CollectionUtils.anyMatch(productDOList, item -> {
|
||||
SeckillActivityUpdateStockReqDTO.Item item1 = productDOMap.get(item.getSkuId());
|
||||
return (item.getStock() < item1.getCount()) || (item.getStock() - item1.getCount()) < 0;
|
||||
});
|
||||
if (b) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
// TODO @puhui999:类似 doList,应该和下面的 update 逻辑粘的更紧密一点;so 在空行的时候,应该挪到 74 之后里去;甚至更合理,应该是 79 之后;说白了,逻辑要分块,每个模块涉及的代码要紧密在一起;
|
||||
List<SeckillProductDO> doList = CollectionUtils.convertList(productDOList, item -> {
|
||||
item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount());
|
||||
return item;
|
||||
});
|
||||
|
||||
// 更新活动库存
|
||||
// TODO @puhui999:考虑下并发更新
|
||||
seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount());
|
||||
seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount());
|
||||
activityService.updateSeckillActivity(seckillActivity);
|
||||
// 更新活动商品库存
|
||||
activityService.updateSeckillActivityProductList(doList);
|
||||
}
|
||||
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.promotion.controller.app.combination;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordRespVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO;
|
||||
@@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.validation.constraints.Max;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
@@ -52,14 +52,13 @@ public class AppCombinationRecordController {
|
||||
@RequestParam(value = "activityId", required = false) Long activityId,
|
||||
@RequestParam("status") Integer status,
|
||||
@RequestParam(value = "count", defaultValue = "20") @Max(20) Integer count) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
List<AppCombinationRecordRespVO> list = new ArrayList<>();
|
||||
for (int i = 1; i <= count; i++) {
|
||||
AppCombinationRecordRespVO record = new AppCombinationRecordRespVO();
|
||||
record.setId((long) i);
|
||||
record.setNickname("用户" + i);
|
||||
record.setAvatar("头像" + i);
|
||||
record.setExpireTime(LocalDateTime.ofInstant(new Date().toInstant(), zoneId));
|
||||
record.setExpireTime(LocalDateTime.now());
|
||||
record.setUserSize(10);
|
||||
record.setUserCount(i);
|
||||
record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
|
||||
@@ -74,14 +73,13 @@ public class AppCombinationRecordController {
|
||||
@Operation(summary = "获得拼团记录明细")
|
||||
@Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024")
|
||||
public CommonResult<AppCombinationRecordDetailRespVO> getCombinationRecordDetail(@RequestParam("id") Long id) {
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
AppCombinationRecordDetailRespVO detail = new AppCombinationRecordDetailRespVO();
|
||||
// 团长
|
||||
AppCombinationRecordRespVO headRecord = new AppCombinationRecordRespVO();
|
||||
headRecord.setId(1L);
|
||||
headRecord.setNickname("用户" + 1);
|
||||
headRecord.setAvatar("头像" + 1);
|
||||
headRecord.setExpireTime((LocalDateTime.ofInstant(DateUtils.addTime(Duration.ofDays(1)).toInstant(), zoneId)));
|
||||
headRecord.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(1)));
|
||||
headRecord.setUserSize(10);
|
||||
headRecord.setUserCount(3);
|
||||
headRecord.setStatus(1);
|
||||
@@ -96,7 +94,7 @@ public class AppCombinationRecordController {
|
||||
record.setId((long) i);
|
||||
record.setNickname("用户" + i);
|
||||
record.setAvatar("头像" + i);
|
||||
record.setExpireTime(LocalDateTime.ofInstant(new Date().toInstant(), zoneId));
|
||||
record.setExpireTime(LocalDateTime.now());
|
||||
record.setUserSize(10);
|
||||
record.setUserCount(i);
|
||||
record.setStatus(1);
|
||||
|
@@ -9,6 +9,7 @@ import lombok.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO 芋艿:把字段的顺序,和 do 顺序对齐下
|
||||
/**
|
||||
* 拼团记录 DO
|
||||
*
|
||||
@@ -27,34 +28,28 @@ import java.time.LocalDateTime;
|
||||
@AllArgsConstructor
|
||||
public class CombinationRecordDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号,主键自增
|
||||
*/
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 拼团活动编号
|
||||
*
|
||||
* 关联 {@link CombinationActivityDO#getId()}
|
||||
*/
|
||||
private Long activityId;
|
||||
/**
|
||||
* 拼团商品单价
|
||||
*
|
||||
* 冗余 {@link CombinationProductDO#getCombinationPrice()}
|
||||
*/
|
||||
private Integer combinationPrice;
|
||||
/**
|
||||
* SPU 编号
|
||||
*/
|
||||
private Long spuId;
|
||||
/**
|
||||
* SKU 编号
|
||||
*/
|
||||
private Long skuId;
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 订单编号
|
||||
*/
|
||||
private Long orderId;
|
||||
/**
|
||||
* 团长编号
|
||||
*
|
||||
* 关联 {@link CombinationRecordDO#getId()}
|
||||
*/
|
||||
private Long headId;
|
||||
/**
|
||||
* 商品名字
|
||||
*/
|
||||
@@ -64,9 +59,14 @@ public class CombinationRecordDO extends BaseDO {
|
||||
*/
|
||||
private String picUrl;
|
||||
/**
|
||||
* 拼团商品单价
|
||||
* SKU 编号
|
||||
*/
|
||||
private Integer combinationPrice;
|
||||
private Long skuId;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 用户昵称
|
||||
*/
|
||||
@@ -75,6 +75,13 @@ public class CombinationRecordDO extends BaseDO {
|
||||
* 用户头像
|
||||
*/
|
||||
private String avatar;
|
||||
|
||||
/**
|
||||
* 团长编号
|
||||
*
|
||||
* 关联 {@link CombinationRecordDO#getId()}
|
||||
*/
|
||||
private Long headId;
|
||||
/**
|
||||
* 开团状态
|
||||
*
|
||||
@@ -82,23 +89,9 @@ public class CombinationRecordDO extends BaseDO {
|
||||
*/
|
||||
private Integer status;
|
||||
/**
|
||||
* 是否虚拟成团
|
||||
* 订单编号
|
||||
*/
|
||||
private Boolean virtualGroup;
|
||||
/**
|
||||
* 过期时间,单位:小时
|
||||
*
|
||||
* 关联 {@link CombinationActivityDO#getLimitDuration()}
|
||||
*/
|
||||
private Integer expireTime;
|
||||
/**
|
||||
* 开始时间 (订单付款后开始的时间)
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
/**
|
||||
* 结束时间(成团时间/失败时间)
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
private Long orderId;
|
||||
/**
|
||||
* 开团需要人数
|
||||
*
|
||||
@@ -109,5 +102,24 @@ public class CombinationRecordDO extends BaseDO {
|
||||
* 已加入拼团人数
|
||||
*/
|
||||
private Integer userCount;
|
||||
/**
|
||||
* 是否虚拟成团
|
||||
*/
|
||||
private Boolean virtualGroup;
|
||||
|
||||
/**
|
||||
* 过期时间
|
||||
*
|
||||
* 基于 {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算
|
||||
*/
|
||||
private LocalDateTime expireTime;
|
||||
/**
|
||||
* 开始时间 (订单付款后开始的时间)
|
||||
*/
|
||||
private LocalDateTime startTime;
|
||||
/**
|
||||
* 结束时间(成团时间/失败时间)
|
||||
*/
|
||||
private LocalDateTime endTime;
|
||||
|
||||
}
|
||||
|
@@ -1,9 +1,9 @@
|
||||
package cn.iocoder.yudao.module.promotion.service.combination;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -16,9 +16,11 @@ public interface CombinationRecordService {
|
||||
/**
|
||||
* 更新拼团状态
|
||||
*
|
||||
* @param reqDTO 请求 DTO
|
||||
* @param status 状态
|
||||
* @param userId 用户编号
|
||||
* @param orderId 订单编号
|
||||
*/
|
||||
void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO);
|
||||
void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId);
|
||||
|
||||
/**
|
||||
* 创建拼团记录
|
||||
@@ -30,9 +32,12 @@ public interface CombinationRecordService {
|
||||
/**
|
||||
* 更新拼团状态和开始时间
|
||||
*
|
||||
* @param reqDTO 请求 DTO
|
||||
* @param status 状态
|
||||
* @param userId 用户编号
|
||||
* @param orderId 订单编号
|
||||
* @param startTime 开始时间
|
||||
*/
|
||||
void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO);
|
||||
void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime);
|
||||
|
||||
/**
|
||||
* 获得拼团状态
|
||||
|
@@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.combination;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO;
|
||||
import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
|
||||
@@ -21,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
|
||||
// TODO 芋艿:等拼团记录做完,完整 review 下
|
||||
|
||||
/**
|
||||
* 拼团记录 Service 实现类
|
||||
*
|
||||
@@ -38,27 +38,27 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) {
|
||||
public void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId) {
|
||||
// 校验拼团是否存在
|
||||
CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
|
||||
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
|
||||
|
||||
// 更新状态
|
||||
recordDO.setStatus(reqDTO.getStatus());
|
||||
recordDO.setStatus(status);
|
||||
recordMapper.updateById(recordDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) {
|
||||
CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId());
|
||||
public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime) {
|
||||
CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId);
|
||||
// 更新状态
|
||||
recordDO.setStatus(reqDTO.getStatus());
|
||||
recordDO.setStatus(status);
|
||||
// 更新开始时间
|
||||
recordDO.setStartTime(reqDTO.getStartTime());
|
||||
recordDO.setStartTime(startTime);
|
||||
recordMapper.updateById(recordDO);
|
||||
|
||||
// 更新拼团参入人数
|
||||
List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus());
|
||||
List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status);
|
||||
if (CollUtil.isNotEmpty(recordDOs)) {
|
||||
recordDOs.forEach(item -> {
|
||||
item.setUserCount(recordDOs.size());
|
||||
@@ -115,8 +115,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
|
||||
// 2. 创建拼团记录
|
||||
CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
|
||||
record.setVirtualGroup(false);
|
||||
// TODO @puhui999:过期时间,应该是 Date 哈;
|
||||
record.setExpireTime(activity.getLimitDuration());
|
||||
record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));
|
||||
record.setUserSize(activity.getUserSize());
|
||||
recordMapper.insert(record);
|
||||
}
|
||||
|
@@ -33,6 +33,20 @@ public interface SeckillActivityService {
|
||||
*/
|
||||
void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 更新秒杀活动
|
||||
*
|
||||
* @param activityDO 秒杀活动
|
||||
*/
|
||||
void updateSeckillActivity(SeckillActivityDO activityDO);
|
||||
|
||||
/**
|
||||
* 更新秒杀活动商品
|
||||
*
|
||||
* @param productList 活动商品列表
|
||||
*/
|
||||
void updateSeckillActivityProductList(List<SeckillProductDO> productList);
|
||||
|
||||
/**
|
||||
* 关闭秒杀活动
|
||||
*
|
||||
|
@@ -79,8 +79,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
* 1. 校验秒杀时段是否存在
|
||||
* 2. 秒杀商品是否参加其它活动
|
||||
*
|
||||
* @param configIds 秒杀时段数组
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param configIds 秒杀时段数组
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param activityId 秒杀活动编号
|
||||
*/
|
||||
private void validateProductConflict(List<Long> configIds, Long spuId, Long activityId) {
|
||||
@@ -92,15 +92,9 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
if (activityId != null) { // 排除自己
|
||||
activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId));
|
||||
}
|
||||
// TODO @puhui999:一个 spu,参与两个活动应该没关系,关键是活动时间不充能重叠;
|
||||
// 2.2 过滤出所有 spuId 有交集的活动,判断是否存在重叠
|
||||
List<SeckillActivityDO> activityDOs1 = filterList(activityList, s -> ObjectUtil.equal(s.getSpuId(), spuId));
|
||||
if (isNotEmpty(activityDOs1)) {
|
||||
throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
// 2.3 过滤出所有 configIds 有交集的活动,判断是否存在重叠
|
||||
List<SeckillActivityDO> activityDOs2 = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds));
|
||||
if (isNotEmpty(activityDOs2)) {
|
||||
// 2.2 过滤出所有 configIds 有交集的活动,判断是否存在重叠
|
||||
List<SeckillActivityDO> conflictActivityList = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds));
|
||||
if (isNotEmpty(conflictActivityList)) {
|
||||
throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS);
|
||||
}
|
||||
}
|
||||
@@ -108,7 +102,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
/**
|
||||
* 校验秒杀商品是否都存在
|
||||
*
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param products 秒杀商品
|
||||
*/
|
||||
private void validateProductExists(Long spuId, List<SeckillProductBaseVO> products) {
|
||||
@@ -150,11 +144,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSeckillActivity(SeckillActivityDO activityDO) {
|
||||
seckillActivityMapper.updateById(activityDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateSeckillActivityProductList(List<SeckillProductDO> productList) {
|
||||
seckillProductMapper.updateBatch(productList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新秒杀商品
|
||||
*
|
||||
* @param activity 秒杀活动
|
||||
* @param products 该活动的最新商品配置
|
||||
* @param products 该活动的最新商品配置
|
||||
*/
|
||||
private void updateSeckillProduct(SeckillActivityDO activity, List<SeckillProductBaseVO> products) {
|
||||
// 第一步,对比新老数据,获得添加、修改、删除的列表
|
||||
|
@@ -1,18 +1,9 @@
|
||||
package cn.iocoder.yudao.module.promotion.util;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||
|
||||
/**
|
||||
* 活动工具类
|
||||
@@ -31,21 +22,4 @@ public class PromotionUtils {
|
||||
return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验商品 sku 是否都存在
|
||||
*
|
||||
* @param skus 数据库中的商品 skus
|
||||
* @param products 需要校验的商品
|
||||
* @param func 获取需要校验的商品的 skuId
|
||||
*/
|
||||
public static <T> void validateProductSkuAllExists(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) {
|
||||
// 校验 sku 个数是否一致
|
||||
Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func);
|
||||
Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId);
|
||||
// 校验 skuId 是否存在
|
||||
if (anyMatch(skuIdsSet, s -> !skuIdsSet1.contains(s))) {
|
||||
throw exception(SKU_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user