mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-08-10 08:11:52 +08:00
mall+order: 完善部分 TODO 提到的问题
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.combination;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@@ -10,14 +10,15 @@ import javax.annotation.Resource;
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
public class CombinationApiImpl implements CombinationApi {
|
||||
@Service
|
||||
public class CombinationActivityApiImpl implements CombinationActivityApi {
|
||||
|
||||
@Resource
|
||||
private CombinationActivityService activityService;
|
||||
|
||||
@Override
|
||||
public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) {
|
||||
activityService.validateCombination(reqDTO);
|
||||
public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) {
|
||||
activityService.validateCombination(activityId, userId, skuId, count);
|
||||
}
|
||||
|
||||
}
|
@@ -1,15 +1,12 @@
|
||||
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.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;
|
||||
|
||||
/**
|
||||
* 拼团活动 API 实现类
|
||||
@@ -32,16 +29,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
|
||||
return CombinationRecordStatusEnum.isSuccess(recordService.getCombinationRecord(userId, orderId).getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId) {
|
||||
return CombinationActivityConvert.INSTANCE.convert(recordService.getRecordListByUserIdAndActivityId(userId, activityId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {
|
||||
recordService.validateCombinationLimitCount(activityId, count, sumCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRecordStatusToSuccess(Long userId, Long orderId) {
|
||||
recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId);
|
||||
|
@@ -1,6 +1,5 @@
|
||||
package cn.iocoder.yudao.module.promotion.api.seckill;
|
||||
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi {
|
||||
private SeckillActivityService activityService;
|
||||
|
||||
@Override
|
||||
public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
|
||||
activityService.updateSeckillStock(updateStockReqDTO);
|
||||
public void updateSeckillStock(Long activityId, Long skuId, Integer count) {
|
||||
activityService.updateSeckillStock(activityId, skuId, count);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.convert.combination;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
|
||||
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||
@@ -92,6 +94,19 @@ public interface CombinationActivityConvert {
|
||||
|
||||
CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO);
|
||||
|
||||
default CombinationRecordDO convert1(CombinationRecordCreateReqDTO reqDTO, CombinationActivityDO activity, MemberUserRespDTO user,
|
||||
ProductSpuRespDTO spu, ProductSkuRespDTO sku) {
|
||||
CombinationRecordDO record = convert(reqDTO);
|
||||
record.setVirtualGroup(false);
|
||||
record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));
|
||||
record.setUserSize(activity.getUserSize());
|
||||
record.setNickname(user.getNickname());
|
||||
record.setAvatar(user.getAvatar());
|
||||
record.setSpuName(spu.getName());
|
||||
record.setPicUrl(sku.getPicUrl());
|
||||
return record;
|
||||
}
|
||||
|
||||
List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean);
|
||||
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> {
|
||||
default int updateActivityStock(Long id, int count) {
|
||||
return update(null, new LambdaUpdateWrapper<BargainActivityDO>()
|
||||
.eq(BargainActivityDO::getId, id)
|
||||
.gt(BargainActivityDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈
|
||||
.gt(BargainActivityDO::getStock, count)
|
||||
.setSql("stock = stock - " + count));
|
||||
}
|
||||
|
||||
|
@@ -34,7 +34,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> {
|
||||
default int updateActivityStock(Long id, int count) {
|
||||
return update(null, new LambdaUpdateWrapper<SeckillProductDO>()
|
||||
.eq(SeckillProductDO::getId, id)
|
||||
.gt(SeckillProductDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈
|
||||
.gt(SeckillProductDO::getStock, count)
|
||||
.setSql("stock = stock - " + count));
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.promotion.service.combination;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
|
||||
@@ -74,10 +73,13 @@ public interface CombinationActivityService {
|
||||
List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds);
|
||||
|
||||
/**
|
||||
* 更新拼图活动库存
|
||||
* 校验是否满足拼团条件
|
||||
*
|
||||
* @param reqDTO 请求
|
||||
* @param activityId 活动编号
|
||||
* @param userId 用户编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量
|
||||
*/
|
||||
void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO);
|
||||
void validateCombination(Long activityId, Long userId, Long skuId, Integer count);
|
||||
|
||||
}
|
||||
|
@@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO;
|
||||
@@ -33,7 +32,6 @@ import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;
|
||||
import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*;
|
||||
@@ -85,7 +83,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
|
||||
/**
|
||||
* 校验拼团商品参与的活动是否存在冲突
|
||||
*
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param activityId 拼团活动编号
|
||||
*/
|
||||
private void validateProductConflict(Long spuId, Long activityId) {
|
||||
@@ -104,7 +102,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
|
||||
/**
|
||||
* 校验拼团商品是否都存在
|
||||
*
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param spuId 商品 SPU 编号
|
||||
* @param products 拼团商品
|
||||
*/
|
||||
private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) {
|
||||
@@ -149,7 +147,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
|
||||
* 更新拼团商品
|
||||
*
|
||||
* @param activity 拼团活动
|
||||
* @param products 该活动的最新商品配置
|
||||
* @param products 该活动的最新商品配置
|
||||
*/
|
||||
private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) {
|
||||
// 第一步,对比新老数据,获得添加、修改、删除的列表
|
||||
@@ -214,35 +212,34 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) {
|
||||
public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) {
|
||||
// 1.1 校验拼团活动是否存在
|
||||
CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId());
|
||||
CombinationActivityDO activity = validateCombinationActivityExists(activityId);
|
||||
// 1.2 校验活动是否开启
|
||||
if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
|
||||
throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE);
|
||||
}
|
||||
// 1.3 校验是否超出单次限购数量
|
||||
if (activity.getSingleLimitCount() < reqDTO.getCount()) {
|
||||
if (activity.getSingleLimitCount() < count) {
|
||||
throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
|
||||
}
|
||||
|
||||
// 2. 校验是否超出总限购数量
|
||||
// TODO @puhui999:userId 应该接口传递哈;要保证 service 无状态
|
||||
List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId(
|
||||
getLoginUserId(), reqDTO.getActivityId());
|
||||
// TODO @puhui999:最好 if true return;减少括号层数
|
||||
if (CollUtil.isNotEmpty(recordList)) {
|
||||
// 过滤出拼团成功的
|
||||
// TODO @puhui999:count 要不存一个在 record 里?
|
||||
List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId,
|
||||
item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));
|
||||
Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList,
|
||||
CombinationRecordDO::getOrderId,
|
||||
item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);
|
||||
if (activity.getTotalLimitCount() < countSum) {
|
||||
throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
|
||||
}
|
||||
List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId(userId, activityId);
|
||||
if (CollUtil.isEmpty(recordList)) {
|
||||
return;
|
||||
}
|
||||
// 过滤出拼团成功的
|
||||
// TODO @puhui999:count 要不存一个在 record 里?
|
||||
List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId,
|
||||
item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus()));
|
||||
Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList,
|
||||
CombinationRecordDO::getOrderId,
|
||||
item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds);
|
||||
if (activity.getTotalLimitCount() < countSum) {
|
||||
throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -57,14 +57,4 @@ public interface CombinationRecordService {
|
||||
*/
|
||||
List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId);
|
||||
|
||||
/**
|
||||
* 验证组合限制数
|
||||
* 校验是否满足限购要求
|
||||
*
|
||||
* @param count 本次购买数量
|
||||
* @param sumCount 已购买数量合计
|
||||
* @param activityId 活动编号
|
||||
*/
|
||||
void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount);
|
||||
|
||||
}
|
||||
|
@@ -128,19 +128,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
|
||||
}
|
||||
|
||||
// 2. 创建拼团记录
|
||||
// TODO @puhui999:可以把 user、spu、sku 一起放 convert 里哈;
|
||||
CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO);
|
||||
record.setVirtualGroup(false);
|
||||
record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration()));
|
||||
record.setUserSize(activity.getUserSize());
|
||||
MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId());
|
||||
record.setNickname(user.getNickname());
|
||||
record.setAvatar(user.getAvatar());
|
||||
ProductSpuRespDTO spu = productSpuApi.getSpu(record.getSpuId());
|
||||
record.setSpuName(spu.getName());
|
||||
ProductSkuRespDTO sku = productSkuApi.getSku(record.getSkuId());
|
||||
record.setPicUrl(sku.getPicUrl());
|
||||
recordMapper.insert(record);
|
||||
ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId());
|
||||
ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId());
|
||||
recordMapper.insert(CombinationActivityConvert.INSTANCE.convert1(reqDTO, activity, user, spu, sku));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,20 +144,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
|
||||
return recordMapper.selectListByUserIdAndActivityId(userId, activityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) {
|
||||
// 1.1 校验拼团活动
|
||||
CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId);
|
||||
// 校验是否达到限购总限购标准
|
||||
if ((sumCount + count) > activity.getTotalLimitCount()) {
|
||||
throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED);
|
||||
}
|
||||
// 单次购买是否达到限购标准
|
||||
if (count > activity.getSingleLimitCount()) {
|
||||
throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* APP 端获取开团记录
|
||||
*
|
||||
|
@@ -1,7 +1,6 @@
|
||||
package cn.iocoder.yudao.module.promotion.service.seckill;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
|
||||
@@ -37,9 +36,11 @@ public interface SeckillActivityService {
|
||||
/**
|
||||
* 更新秒杀库存
|
||||
*
|
||||
* @param updateStockReqDTO 更新信息
|
||||
* @param activityId 活动编号
|
||||
* @param skuId sku 编号
|
||||
* @param count 数量
|
||||
*/
|
||||
void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO);
|
||||
void updateSeckillStock(Long activityId, Long skuId, Integer count);
|
||||
|
||||
/**
|
||||
* 关闭秒杀活动
|
||||
|
@@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||
import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
|
||||
import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi;
|
||||
import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO;
|
||||
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO;
|
||||
import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO;
|
||||
@@ -147,32 +146,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
|
||||
public void updateSeckillStock(Long activityId, Long skuId, Integer count) {
|
||||
// 1、校验秒杀活动是否存在
|
||||
SeckillActivityDO seckillActivity = getSeckillActivity(updateStockReqDTO.getActivityId());
|
||||
SeckillActivityDO seckillActivity = getSeckillActivity(activityId);
|
||||
// 1.1、校验库存是否充足
|
||||
if (seckillActivity.getTotalStock() < updateStockReqDTO.getCount()) {
|
||||
if (seckillActivity.getTotalStock() < count) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
|
||||
// 2、获取活动商品
|
||||
List<SeckillProductDO> products = getSeckillProductListByActivityId(updateStockReqDTO.getActivityId());
|
||||
List<SeckillProductDO> products = getSeckillProductListByActivityId(activityId);
|
||||
// 2.1、过滤出购买的商品
|
||||
SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(updateStockReqDTO.getItem().getSkuId(), item.getSkuId()));
|
||||
SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(skuId, item.getSkuId()));
|
||||
// 2.2、检查活动商品库存是否充足
|
||||
boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < updateStockReqDTO.getItem().getCount()) || (product.getStock() - updateStockReqDTO.getItem().getCount()) < 0);
|
||||
boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < count) || (product.getStock() - count) < 0);
|
||||
if (isSufficient) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
|
||||
// 3、更新活动商品库存
|
||||
int updateCount = seckillProductMapper.updateActivityStock(product.getId(), updateStockReqDTO.getItem().getCount());
|
||||
int updateCount = seckillProductMapper.updateActivityStock(product.getId(), count);
|
||||
if (updateCount == 0) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
|
||||
// 4、更新活动库存
|
||||
updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), updateStockReqDTO.getCount());
|
||||
updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), count);
|
||||
if (updateCount == 0) {
|
||||
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||
}
|
||||
|
Reference in New Issue
Block a user