mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 23:31:52 +08:00
营销活动+订单:完善大部分 TODO 提到的问题
This commit is contained in:
parent
2591ab5d36
commit
0e8755972c
@ -0,0 +1,18 @@
|
|||||||
|
package cn.iocoder.yudao.module.promotion.api.bargain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 砍价活动 Api 接口
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
public interface BargainActivityApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新砍价活动库存
|
||||||
|
*
|
||||||
|
* @param activityId 砍价活动编号
|
||||||
|
* @param count 购买数量
|
||||||
|
*/
|
||||||
|
void updateBargainActivityStock(Long activityId, Integer count);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package cn.iocoder.yudao.module.promotion.api.seckill;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 秒杀活动 API 接口
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
public interface SeckillActivityApi {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新秒杀库存
|
||||||
|
*
|
||||||
|
* @param updateStockReqDTO 请求
|
||||||
|
*/
|
||||||
|
void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
package cn.iocoder.yudao.module.promotion.api.seckill.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新秒杀库存 request DTO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class SeckillActivityUpdateStockReqDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动编号
|
||||||
|
*/
|
||||||
|
private Long activityId;
|
||||||
|
/**
|
||||||
|
* 总购买数量
|
||||||
|
*/
|
||||||
|
private Integer count;
|
||||||
|
/**
|
||||||
|
* 活动商品
|
||||||
|
*/
|
||||||
|
private List<Item> items;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Item {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPU 编号
|
||||||
|
*/
|
||||||
|
private Long spuId;
|
||||||
|
/**
|
||||||
|
* SKU 编号
|
||||||
|
*/
|
||||||
|
private Long skuId;
|
||||||
|
/**
|
||||||
|
* 购买数量
|
||||||
|
*/
|
||||||
|
private Integer count;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -55,6 +55,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改");
|
ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1013008003, "秒杀活动已关闭,不能修改");
|
||||||
ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
|
ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除");
|
||||||
ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
|
ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭");
|
||||||
|
ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "更新秒杀活动库存失败,原因秒杀库存不足");
|
||||||
|
|
||||||
// ========== 秒杀时段 1013009000 ==========
|
// ========== 秒杀时段 1013009000 ==========
|
||||||
ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
|
ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在");
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
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) {
|
||||||
|
// 查询砍价活动
|
||||||
|
BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId);
|
||||||
|
if (activity == null) {
|
||||||
|
throw exception(BARGAIN_ACTIVITY_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新砍价库存
|
||||||
|
BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO();
|
||||||
|
reqVO.setId(activityId);
|
||||||
|
reqVO.setStock(activity.getStock() - count);
|
||||||
|
bargainActivityService.updateBargainActivity(reqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
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;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) {
|
||||||
|
SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId());
|
||||||
|
if (seckillActivity.getStock() < updateStockReqDTO.getCount()) {
|
||||||
|
throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL);
|
||||||
|
}
|
||||||
|
// 获取活动商品
|
||||||
|
List<SeckillProductDO> productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 过滤出购买的商品
|
||||||
|
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);
|
||||||
|
// 检查活动商品库存是否充足
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
List<SeckillProductDO> doList = CollectionUtils.convertList(productDOList, item -> {
|
||||||
|
item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount());
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新活动库存
|
||||||
|
seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount());
|
||||||
|
seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount());
|
||||||
|
activityService.updateSeckillActivity(seckillActivity);
|
||||||
|
// 更新活动商品库存
|
||||||
|
activityService.updateSeckillActivityProductByList(doList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -33,6 +33,20 @@ public interface SeckillActivityService {
|
|||||||
*/
|
*/
|
||||||
void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO);
|
void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新秒杀活动
|
||||||
|
*
|
||||||
|
* @param activityDO 秒杀活动
|
||||||
|
*/
|
||||||
|
void updateSeckillActivity(SeckillActivityDO activityDO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新秒杀活动商品
|
||||||
|
*
|
||||||
|
* @param productDOList 活动商品列表
|
||||||
|
*/
|
||||||
|
void updateSeckillActivityProductByList(List<SeckillProductDO> productDOList);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 关闭秒杀活动
|
* 关闭秒杀活动
|
||||||
*
|
*
|
||||||
|
@ -144,6 +144,16 @@ public class SeckillActivityServiceImpl implements SeckillActivityService {
|
|||||||
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
updateSeckillProduct(updateObj, updateReqVO.getProducts());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSeckillActivity(SeckillActivityDO activityDO) {
|
||||||
|
seckillActivityMapper.updateById(activityDO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateSeckillActivityProductByList(List<SeckillProductDO> productDOList) {
|
||||||
|
seckillProductMapper.updateBatch(productDOList);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新秒杀商品
|
* 更新秒杀商品
|
||||||
*
|
*
|
||||||
|
@ -82,6 +82,11 @@
|
|||||||
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
<artifactId>yudao-spring-boot-starter-mybatis</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
<artifactId>yudao-spring-boot-starter-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- Test 测试相关 -->
|
<!-- Test 测试相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.boot</groupId>
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||||
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
|
||||||
|
|
||||||
@Tag(name = "管理后台 - 交易订单")
|
@Tag(name = "管理后台 - 交易订单")
|
||||||
@RestController
|
@RestController
|
||||||
@ -67,6 +68,9 @@ public class TradeOrderController {
|
|||||||
public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
|
public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) {
|
||||||
// 查询订单
|
// 查询订单
|
||||||
TradeOrderDO order = tradeOrderQueryService.getOrder(id);
|
TradeOrderDO order = tradeOrderQueryService.getOrder(id);
|
||||||
|
if (order == null) {
|
||||||
|
return success(null, ORDER_NOT_FOUND.getMsg());
|
||||||
|
}
|
||||||
// 查询订单项
|
// 查询订单项
|
||||||
List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id);
|
List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id);
|
||||||
// orderLog
|
// orderLog
|
||||||
|
@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
|
||||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
|
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi;
|
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
|
import cn.iocoder.yudao.module.trade.controller.app.order.vo.*;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
|
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
|
import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO;
|
||||||
@ -34,6 +33,7 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
|
||||||
|
|
||||||
@Tag(name = "用户 App - 交易订单")
|
@Tag(name = "用户 App - 交易订单")
|
||||||
@RestController
|
@RestController
|
||||||
@ -83,7 +83,7 @@ public class AppTradeOrderController {
|
|||||||
// 查询订单
|
// 查询订单
|
||||||
TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id);
|
TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id);
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
return success(null);
|
return success(null, ORDER_NOT_FOUND.getMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询订单项
|
// 查询订单项
|
||||||
|
@ -56,6 +56,10 @@ public class AppTradeOrderSettlementReqVO {
|
|||||||
@Schema(description = "拼团团长编号", example = "2048")
|
@Schema(description = "拼团团长编号", example = "2048")
|
||||||
private Long combinationHeadId;
|
private Long combinationHeadId;
|
||||||
|
|
||||||
|
// ========== 砍价活动相关字段 ==========
|
||||||
|
@Schema(description = "砍价活动编号", example = "123")
|
||||||
|
private Long bargainActivityId;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "用户 App - 商品项")
|
@Schema(description = "用户 App - 商品项")
|
||||||
@Valid
|
@Valid
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.module.trade.dal.redis.no;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DatePattern;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单序号的 Redis DAO
|
||||||
|
*
|
||||||
|
* @author HUIHUI
|
||||||
|
*/
|
||||||
|
@Repository
|
||||||
|
public class TradeOrderNoRedisDAO {
|
||||||
|
public static final String TRADE_ORDER_NO_PREFIX = "O";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成序号
|
||||||
|
*
|
||||||
|
* @param prefix 前缀
|
||||||
|
* @return 序号
|
||||||
|
*/
|
||||||
|
public String generate(String prefix) {
|
||||||
|
String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN);
|
||||||
|
Long no = stringRedisTemplate.opsForValue().increment(noPrefix);
|
||||||
|
return noPrefix + no;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order;
|
|||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
@ -25,11 +24,14 @@ import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
|
|||||||
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
import cn.iocoder.yudao.module.product.api.comment.ProductCommentApi;
|
||||||
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
|
||||||
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.bargain.BargainActivityApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.bargain.BargainRecordApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO;
|
||||||
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
import cn.iocoder.yudao.module.promotion.api.coupon.CouponApi;
|
||||||
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
import cn.iocoder.yudao.module.promotion.api.coupon.dto.CouponUseReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi;
|
||||||
|
import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO;
|
||||||
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderDeliveryReqVO;
|
||||||
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO;
|
import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderRemarkReqVO;
|
||||||
@ -45,6 +47,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
|
|||||||
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
|
||||||
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
|
import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
|
||||||
|
import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO;
|
||||||
import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
|
import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants;
|
||||||
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
|
||||||
import cn.iocoder.yudao.module.trade.enums.order.*;
|
import cn.iocoder.yudao.module.trade.enums.order.*;
|
||||||
@ -70,7 +73,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
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.common.util.collection.CollectionUtils.*;
|
||||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_NOT_FOUND;
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_EQUAL;
|
||||||
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_PAID;
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_UPDATE_PRICE_FAIL_PAID;
|
||||||
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*;
|
||||||
|
|
||||||
@ -88,6 +91,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
private TradeOrderMapper tradeOrderMapper;
|
private TradeOrderMapper tradeOrderMapper;
|
||||||
@Resource
|
@Resource
|
||||||
private TradeOrderItemMapper tradeOrderItemMapper;
|
private TradeOrderItemMapper tradeOrderItemMapper;
|
||||||
|
@Resource
|
||||||
|
private TradeOrderNoRedisDAO orderNoRedisDAO;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CartService cartService;
|
private CartService cartService;
|
||||||
@ -111,6 +116,10 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
@Resource
|
@Resource
|
||||||
private BargainRecordApi bargainRecordApi;
|
private BargainRecordApi bargainRecordApi;
|
||||||
@Resource
|
@Resource
|
||||||
|
private SeckillActivityApi seckillActivityApi;
|
||||||
|
@Resource
|
||||||
|
private BargainActivityApi bargainActivityApi;
|
||||||
|
@Resource
|
||||||
private MemberUserApi memberUserApi;
|
private MemberUserApi memberUserApi;
|
||||||
@Resource
|
@Resource
|
||||||
private MemberLevelApi memberLevelApi;
|
private MemberLevelApi memberLevelApi;
|
||||||
@ -189,6 +198,19 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
// TODO @puhui999:这个逻辑,先抽个小方法;未来要通过设计模式,把这些拼团之类的逻辑,抽象出去
|
// TODO @puhui999:这个逻辑,先抽个小方法;未来要通过设计模式,把这些拼团之类的逻辑,抽象出去
|
||||||
// 拼团
|
// 拼团
|
||||||
if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
|
if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) {
|
||||||
|
createCombinationRecord(userId, createReqVO, orderItems, order);
|
||||||
|
}
|
||||||
|
// 3.2 秒杀的特殊逻辑
|
||||||
|
if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
|
||||||
|
|
||||||
|
}
|
||||||
|
// 3.3 砍价的特殊逻辑
|
||||||
|
|
||||||
|
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createCombinationRecord(Long userId, AppTradeOrderCreateReqVO createReqVO, List<TradeOrderItemDO> orderItems, TradeOrderDO order) {
|
||||||
MemberUserRespDTO user = memberUserApi.getUser(userId);
|
MemberUserRespDTO user = memberUserApi.getUser(userId);
|
||||||
List<CombinationRecordRespDTO> recordRespDTOS = combinationRecordApi.getRecordListByUserIdAndActivityId(userId, createReqVO.getCombinationActivityId());
|
List<CombinationRecordRespDTO> recordRespDTOS = combinationRecordApi.getRecordListByUserIdAndActivityId(userId, createReqVO.getCombinationActivityId());
|
||||||
// TODO 拼团一次应该只能选择一种规格的商品
|
// TODO 拼团一次应该只能选择一种规格的商品
|
||||||
@ -203,16 +225,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
|
|
||||||
combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItemDO, createReqVO, user));
|
combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(order, orderItemDO, createReqVO, user));
|
||||||
}
|
}
|
||||||
// 3.2 秒杀的特殊逻辑
|
|
||||||
// TODO 秒杀扣减库存是下单就扣除还是等待订单支付成功再扣除
|
|
||||||
if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), order.getType())) {
|
|
||||||
|
|
||||||
}
|
|
||||||
// 3.3 砍价的特殊逻辑
|
|
||||||
|
|
||||||
// TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来!
|
|
||||||
return order;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO @puhui999:订单超时,自动取消;
|
// TODO @puhui999:订单超时,自动取消;
|
||||||
|
|
||||||
@ -240,8 +252,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
address = validateAddress(userId, createReqVO.getAddressId());
|
address = validateAddress(userId, createReqVO.getAddressId());
|
||||||
}
|
}
|
||||||
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address);
|
TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address);
|
||||||
|
String no = orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX);
|
||||||
order.setType(validateActivity(createReqVO));
|
order.setType(validateActivity(createReqVO));
|
||||||
order.setNo(IdUtil.getSnowflakeNextId() + ""); // TODO @puhui999: 参考支付订单,的 no 生成哈;
|
order.setNo(no);
|
||||||
order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
|
order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus());
|
||||||
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
|
order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus());
|
||||||
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum));
|
||||||
@ -293,19 +306,23 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO,
|
||||||
TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems,
|
TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems,
|
||||||
TradePriceCalculateRespBO calculateRespBO) {
|
TradePriceCalculateRespBO calculateRespBO) {
|
||||||
// 下单时扣减商品库存
|
Integer count = getSumValue(orderItems, TradeOrderItemDO::getCount, Integer::sum);
|
||||||
// TODO @puhui999:扣库存,需要前置;
|
|
||||||
// 1)如果是秒杀商品:额外扣减秒杀的库存;
|
// 1)如果是秒杀商品:额外扣减秒杀的库存;
|
||||||
// 2)如果是拼团活动:额外扣减拼团的库存;
|
if (Objects.equals(TradeOrderTypeEnum.SECKILL.getType(), tradeOrderDO.getType())) {
|
||||||
// 3)如果是砍价活动:额外扣减砍价的库存;
|
SeckillActivityUpdateStockReqDTO updateStockReqDTO = new SeckillActivityUpdateStockReqDTO();
|
||||||
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
|
updateStockReqDTO.setActivityId(createReqVO.getSeckillActivityId());
|
||||||
|
updateStockReqDTO.setCount(count);
|
||||||
// 删除购物车商品
|
updateStockReqDTO.setItems(CollectionUtils.convertList(orderItems, item -> {
|
||||||
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
SeckillActivityUpdateStockReqDTO.Item item1 = new SeckillActivityUpdateStockReqDTO.Item();
|
||||||
if (CollUtil.isNotEmpty(cartIds)) {
|
item1.setSpuId(item.getSpuId());
|
||||||
cartService.deleteCart(userId, cartIds);
|
item1.setSkuId(item.getSkuId());
|
||||||
|
item1.setCount(item.getCount());
|
||||||
|
return item1;
|
||||||
|
}));
|
||||||
|
seckillActivityApi.updateSeckillStock(updateStockReqDTO);
|
||||||
}
|
}
|
||||||
|
// 2)如果是砍价活动:额外扣减砍价的库存;
|
||||||
|
bargainActivityApi.updateBargainActivityStock(createReqVO.getBargainActivityId(), count);
|
||||||
// 扣减积分 TODO 芋艿:待实现,需要前置;
|
// 扣减积分 TODO 芋艿:待实现,需要前置;
|
||||||
// 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣
|
// 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣
|
||||||
|
|
||||||
@ -315,6 +332,15 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
.setOrderId(tradeOrderDO.getId()));
|
.setOrderId(tradeOrderDO.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 下单时扣减商品库存
|
||||||
|
productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems));
|
||||||
|
|
||||||
|
// 删除购物车商品
|
||||||
|
Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId);
|
||||||
|
if (CollUtil.isNotEmpty(cartIds)) {
|
||||||
|
cartService.deleteCart(userId, cartIds);
|
||||||
|
}
|
||||||
|
|
||||||
// 生成预支付
|
// 生成预支付
|
||||||
createPayOrder(tradeOrderDO, orderItems, calculateRespBO);
|
createPayOrder(tradeOrderDO, orderItems, calculateRespBO);
|
||||||
|
|
||||||
@ -464,11 +490,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
*/
|
*/
|
||||||
private TradeOrderDO validateOrderDeliverable(Long id) {
|
private TradeOrderDO validateOrderDeliverable(Long id) {
|
||||||
TradeOrderDO order = validateOrderExists(id);
|
TradeOrderDO order = validateOrderExists(id);
|
||||||
// 校验订单是否是待发货状态
|
|
||||||
// TODO @puhui999:已经发货,可以重新发货,修改信息;
|
|
||||||
if (!TradeOrderStatusEnum.isUndelivered(order.getStatus())) {
|
|
||||||
throw exception(ORDER_DELIVERY_FAIL_STATUS_NOT_UNDELIVERED);
|
|
||||||
}
|
|
||||||
// 校验订单是否退款
|
// 校验订单是否退款
|
||||||
if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
|
if (ObjectUtil.notEqual(TradeOrderRefundStatusEnum.NONE.getStatus(), order.getRefundStatus())) {
|
||||||
throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
|
throw exception(ORDER_DELIVERY_FAIL_REFUND_STATUS_NOT_NONE);
|
||||||
@ -540,14 +561,25 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
|
|||||||
if (order.getPayStatus()) {
|
if (order.getPayStatus()) {
|
||||||
throw exception(ORDER_UPDATE_PRICE_FAIL_PAID);
|
throw exception(ORDER_UPDATE_PRICE_FAIL_PAID);
|
||||||
}
|
}
|
||||||
// TODO @puhui999:如果改价,需要校验下是否真的变化;
|
if (ObjectUtil.equal(order.getAdjustPrice(), reqVO.getAdjustPrice())) {
|
||||||
|
throw exception(ORDER_UPDATE_PRICE_FAIL_EQUAL);
|
||||||
|
}
|
||||||
|
|
||||||
// 更新
|
List<TradeOrderItemDO> itemDOs = tradeOrderItemMapper.selectListByOrderId(order.getId());
|
||||||
// TODO @puhui999:TradeOrderItemDO 需要做 adjustPrice 的分摊;另外,支付订单那的价格,需要 update 下;
|
// TradeOrderItemDO 需要做 adjustPrice 的分摊
|
||||||
|
int price = reqVO.getAdjustPrice() / itemDOs.size();
|
||||||
|
itemDOs.forEach(item -> {
|
||||||
|
item.setAdjustPrice(price);
|
||||||
|
});
|
||||||
|
// 更新 TradeOrderItem
|
||||||
|
tradeOrderItemMapper.updateBatch(itemDOs);
|
||||||
|
// 更新订单
|
||||||
TradeOrderDO update = TradeOrderConvert.INSTANCE.convert(reqVO);
|
TradeOrderDO update = TradeOrderConvert.INSTANCE.convert(reqVO);
|
||||||
update.setPayPrice(update.getPayPrice() + update.getAdjustPrice());
|
update.setPayPrice(update.getPayPrice() + update.getAdjustPrice());
|
||||||
// TODO @芋艿:改价时,赠送的积分,要不要做改动???
|
// TODO @芋艿:改价时,赠送的积分,要不要做改动???
|
||||||
tradeOrderMapper.updateById(update);
|
tradeOrderMapper.updateById(update);
|
||||||
|
// 更新支付订单
|
||||||
|
payOrderApi.updatePayOrderPriceById(order.getPayOrderId(), update.getPayPrice());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -29,4 +29,11 @@ public interface PayOrderApi {
|
|||||||
*/
|
*/
|
||||||
PayOrderRespDTO getOrder(Long id);
|
PayOrderRespDTO getOrder(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新支付订单价格
|
||||||
|
*
|
||||||
|
* @param payOrderId 支付单编号
|
||||||
|
* @param payPrice 支付单价格
|
||||||
|
*/
|
||||||
|
void updatePayOrderPriceById(Long payOrderId, Integer payPrice);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}");
|
ErrorCode ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1007002004, "发起支付报错,错误码:{},错误提示:{}");
|
||||||
ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款");
|
ErrorCode ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1007002005, "支付订单退款失败,原因:状态不是已支付或已退款");
|
||||||
ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1007002006, "支付订单调价失败,原因:支付订单已付款,不能调价");
|
ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1007002006, "支付订单调价失败,原因:支付订单已付款,不能调价");
|
||||||
|
ErrorCode ORDER_UPDATE_PRICE_FAIL_EQUAL = new ErrorCode(1007002007, "支付订单调价失败,原因:价格没有变化");
|
||||||
|
|
||||||
// ========== ORDER 模块(拓展单) 1007003000 ==========
|
// ========== ORDER 模块(拓展单) 1007003000 ==========
|
||||||
ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在");
|
ErrorCode ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1007003000, "支付交易拓展单不存在");
|
||||||
|
@ -31,4 +31,10 @@ public class PayOrderApiImpl implements PayOrderApi {
|
|||||||
return PayOrderConvert.INSTANCE.convert2(order);
|
return PayOrderConvert.INSTANCE.convert2(order);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) {
|
||||||
|
payOrderService.updatePayOrderPriceById(payOrderId, payPrice);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -98,6 +98,14 @@ public interface PayOrderService {
|
|||||||
*/
|
*/
|
||||||
void updateOrderRefundPrice(Long id, Integer incrRefundPrice);
|
void updateOrderRefundPrice(Long id, Integer incrRefundPrice);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新支付订单价格
|
||||||
|
*
|
||||||
|
* @param payOrderId 支付单编号
|
||||||
|
* @param payPrice 支付单价格
|
||||||
|
*/
|
||||||
|
void updatePayOrderPriceById(Long payOrderId, Integer payPrice);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得支付订单
|
* 获得支付订单
|
||||||
*
|
*
|
||||||
|
@ -410,6 +410,17 @@ public class PayOrderServiceImpl implements PayOrderService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePayOrderPriceById(Long payOrderId, Integer payPrice) {
|
||||||
|
PayOrderDO order = orderMapper.selectById(payOrderId);
|
||||||
|
if (order == null) {
|
||||||
|
throw exception(ORDER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
order.setPrice(payPrice);
|
||||||
|
orderMapper.updateById(order);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PayOrderExtensionDO getOrderExtension(Long id) {
|
public PayOrderExtensionDO getOrderExtension(Long id) {
|
||||||
return orderExtensionMapper.selectById(id);
|
return orderExtensionMapper.selectById(id);
|
||||||
|
Loading…
Reference in New Issue
Block a user