mirror of
https://gitee.com/youlaitech/youlai-mall.git
synced 2024-12-23 05:00:25 +08:00
feat:订单支付流程完成和验证,添加日志
This commit is contained in:
parent
382fc87127
commit
5aec657f19
@ -1,5 +1,6 @@
|
|||||||
package com.youlai.mall.oms.controller.app;
|
package com.youlai.mall.oms.controller.app;
|
||||||
|
|
||||||
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||||
import com.youlai.common.result.Result;
|
import com.youlai.common.result.Result;
|
||||||
import com.youlai.mall.oms.pojo.vo.CartVO;
|
import com.youlai.mall.oms.pojo.vo.CartVO;
|
||||||
import com.youlai.mall.oms.service.ICartService;
|
import com.youlai.mall.oms.service.ICartService;
|
||||||
@ -27,30 +28,27 @@ public class CartController {
|
|||||||
|
|
||||||
@ApiOperation(value = "查询购物车")
|
@ApiOperation(value = "查询购物车")
|
||||||
@GetMapping
|
@GetMapping
|
||||||
|
@ApiOperationSupport(order = 1)
|
||||||
public Result getCart() {
|
public Result getCart() {
|
||||||
CartVO cart = cartService.getCart();
|
CartVO cart = cartService.getCart();
|
||||||
return Result.success(cart);
|
return Result.success(cart);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation(value = "全选/全不选 购物车商品")
|
@ApiOperation(value = "删除购物车")
|
||||||
@ApiImplicitParam(name = "checked", value = "全选/全不选", required = true, paramType = "param", dataType = "Boolean")
|
|
||||||
@PatchMapping("/_check")
|
|
||||||
public Result check(boolean checked) {
|
|
||||||
boolean result = cartService.checkAll(checked);
|
|
||||||
return Result.judge(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ApiOperation(value = "清空购物车")
|
|
||||||
@DeleteMapping
|
@DeleteMapping
|
||||||
|
@ApiOperationSupport(order = 2)
|
||||||
public Result deleteCart() {
|
public Result deleteCart() {
|
||||||
boolean result = cartService.deleteCart();
|
boolean result = cartService.deleteCart();
|
||||||
return Result.judge(result);
|
return Result.judge(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "添加购物车商品")
|
@ApiOperation(value = "添加购物车商品")
|
||||||
@ApiImplicitParam(name = "skuId", value = "SKU ID", required = true, paramType = "param", dataType = "Long")
|
@ApiImplicitParam(name = "skuId", value = "SKU ID", required = true, paramType = "param", dataType = "Long")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
|
@ApiOperationSupport(order = 3)
|
||||||
public Result addCartItem(@RequestParam Long skuId) {
|
public Result addCartItem(@RequestParam Long skuId) {
|
||||||
cartService.addCartItem(skuId);
|
cartService.addCartItem(skuId);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@ -58,20 +56,30 @@ public class CartController {
|
|||||||
|
|
||||||
@ApiOperation(value = "更新购物车商品")
|
@ApiOperation(value = "更新购物车商品")
|
||||||
@PutMapping("/skuId/{skuId}")
|
@PutMapping("/skuId/{skuId}")
|
||||||
|
@ApiOperationSupport(order = 4)
|
||||||
public Result updateCartItem(@PathVariable Long skuId,@RequestBody CartVO.CartItem cartItem) {
|
public Result updateCartItem(@PathVariable Long skuId,@RequestBody CartVO.CartItem cartItem) {
|
||||||
cartItem.setSkuId(skuId);
|
cartItem.setSkuId(skuId);
|
||||||
boolean result = cartService.updateCartItem(cartItem);
|
boolean result = cartService.updateCartItem(cartItem);
|
||||||
return Result.judge(result);
|
return Result.judge(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ApiOperation(value = "删除购物车商品")
|
@ApiOperation(value = "删除购物车商品")
|
||||||
@ApiImplicitParam(name = "skuId", value = "SKU ID", required = true, paramType = "param", dataType = "Long")
|
@ApiImplicitParam(name = "skuId", value = "SKU ID", required = true, paramType = "param", dataType = "Long")
|
||||||
@DeleteMapping("/skuId/{skuId}")
|
@DeleteMapping("/skuId/{skuId}")
|
||||||
|
@ApiOperationSupport(order = 5)
|
||||||
public Result removeCartItem(@PathVariable Long skuId) {
|
public Result removeCartItem(@PathVariable Long skuId) {
|
||||||
boolean result = cartService.removeCartItem(skuId);
|
boolean result = cartService.removeCartItem(skuId);
|
||||||
return Result.judge(result);
|
return Result.judge(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "全选/全不选购物车商品")
|
||||||
|
@ApiImplicitParam(name = "checked", value = "全选/全不选", required = true, paramType = "param", dataType = "Boolean")
|
||||||
|
@PatchMapping("/_check")
|
||||||
|
@ApiOperationSupport(order = 6)
|
||||||
|
public Result check(boolean checked) {
|
||||||
|
boolean result = cartService.checkAll(checked);
|
||||||
|
return Result.judge(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,9 +31,17 @@ import java.util.List;
|
|||||||
public class OrderController {
|
public class OrderController {
|
||||||
|
|
||||||
private IOrderService orderService;
|
private IOrderService orderService;
|
||||||
|
|
||||||
private IOrderPayService orderPayService;
|
private IOrderPayService orderPayService;
|
||||||
|
|
||||||
|
|
||||||
|
@ApiOperation("订单列表")
|
||||||
|
@GetMapping
|
||||||
|
@ApiImplicitParam(name = "status", value = "订单状态", required = true, defaultValue = "0")
|
||||||
|
public Result<List<OrderListVO>> list(Integer status) {
|
||||||
|
List<OrderListVO> orderList = orderService.list(status);
|
||||||
|
return Result.success(orderList);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation( "订单确认")
|
@ApiOperation( "订单确认")
|
||||||
@ApiImplicitParam(name = "orderConfirm",value = "确认订单信息",required = true, paramType = "body", dataType = "OrderConfirmDTO")
|
@ApiImplicitParam(name = "orderConfirm",value = "确认订单信息",required = true, paramType = "body", dataType = "OrderConfirmDTO")
|
||||||
@PostMapping("/_confirm")
|
@PostMapping("/_confirm")
|
||||||
@ -69,12 +77,5 @@ public class OrderController {
|
|||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("订单列表")
|
|
||||||
@GetMapping
|
|
||||||
public Result<List<OrderListVO>> list(
|
|
||||||
@ApiParam(name = "status", value = "订单状态", required = true, defaultValue = "0")
|
|
||||||
@RequestParam(value = "status", defaultValue = "0") Integer status) {
|
|
||||||
List<OrderListVO> orderList = orderService.list(status);
|
|
||||||
return Result.success(orderList);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -32,17 +32,18 @@ public class OmsListener {
|
|||||||
*/
|
*/
|
||||||
@RabbitListener(queues = "order.close.queue")
|
@RabbitListener(queues = "order.close.queue")
|
||||||
public void closeOrder(String orderToken, Message message, Channel channel) {
|
public void closeOrder(String orderToken, Message message, Channel channel) {
|
||||||
|
log.info("=======================订单超时未支付,开始系统自动关闭订单=======================");
|
||||||
try {
|
try {
|
||||||
if (orderService.closeOrder(orderToken)) {
|
if (orderService.closeOrder(orderToken)) {
|
||||||
// 如果关单成功,释放库存
|
log.info("=======================关闭订单成功,开始释放已锁定的库存=======================");
|
||||||
skuFeignService.unlockStock(orderToken);
|
skuFeignService.unlockStock(orderToken);
|
||||||
} else {
|
} else {
|
||||||
// 如果关单失败,则订单可能已经被处理,直接手动ACK确认消息
|
log.info("=======================关单失败,订单状态已处理,手动确认消息处理完毕=======================");
|
||||||
// basicAck(tag,multiple),multiple为true开启批量确认,小于tag值队列中未被消费的消息一次性确认
|
// basicAck(tag,multiple),multiple为true开启批量确认,小于tag值队列中未被消费的消息一次性确认
|
||||||
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
|
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// 消费失败后,重新入队
|
log.info("=======================系统自动关闭订单消息消费失败,重新入队=======================");
|
||||||
try {
|
try {
|
||||||
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
|
channel.basicReject(message.getMessageProperties().getDeliveryTag(), true);
|
||||||
} catch (IOException ioException) {
|
} catch (IOException ioException) {
|
||||||
|
@ -64,6 +64,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public OrderConfirmVO confirm(OrderConfirmDTO orderConfirmDTO) {
|
public OrderConfirmVO confirm(OrderConfirmDTO orderConfirmDTO) {
|
||||||
|
log.info("=======================订单确认=======================");
|
||||||
OrderConfirmVO orderConfirmVO = new OrderConfirmVO();
|
OrderConfirmVO orderConfirmVO = new OrderConfirmVO();
|
||||||
Long memberId = RequestUtils.getUserId();
|
Long memberId = RequestUtils.getUserId();
|
||||||
// 获取购买商品信息
|
// 获取购买商品信息
|
||||||
@ -111,6 +112,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
|||||||
}, threadPoolExecutor);
|
}, threadPoolExecutor);
|
||||||
|
|
||||||
CompletableFuture.allOf(orderItemsCompletableFuture, addressesCompletableFuture, orderTokenCompletableFuture).join();
|
CompletableFuture.allOf(orderItemsCompletableFuture, addressesCompletableFuture, orderTokenCompletableFuture).join();
|
||||||
|
log.info("获取确认信息",orderConfirmVO.toString());
|
||||||
return orderConfirmVO;
|
return orderConfirmVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +122,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
|||||||
@Override
|
@Override
|
||||||
@GlobalTransactional
|
@GlobalTransactional
|
||||||
public OrderSubmitVO submit(OrderSubmitDTO submitDTO) {
|
public OrderSubmitVO submit(OrderSubmitDTO submitDTO) {
|
||||||
|
log.info("=======================订单提交=======================");
|
||||||
// 订单重复提交校验
|
// 订单重复提交校验
|
||||||
String orderToken = submitDTO.getOrderToken();
|
String orderToken = submitDTO.getOrderToken();
|
||||||
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
|
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(RELEASE_LOCK_LUA_SCRIPT, Long.class);
|
||||||
@ -188,6 +190,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
|||||||
OrderSubmitVO submitVO = new OrderSubmitVO();
|
OrderSubmitVO submitVO = new OrderSubmitVO();
|
||||||
submitVO.setOrderId(order.getId());
|
submitVO.setOrderId(order.getId());
|
||||||
submitVO.setOrderSn(order.getOrderSn());
|
submitVO.setOrderSn(order.getOrderSn());
|
||||||
|
log.info("订单提交返回结果:{}",submitVO.toString());
|
||||||
return submitVO;
|
return submitVO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +262,10 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, OmsOrder> impleme
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OmsOrder getByOrderId(Long id) {
|
public OmsOrder getByOrderId(Long id) {
|
||||||
Long userId = RequestUtils.getUserId();
|
Long memberId = RequestUtils.getUserId();
|
||||||
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
|
OmsOrder order = this.getOne(new LambdaQueryWrapper<OmsOrder>()
|
||||||
.eq(OmsOrder::getId, id)
|
.eq(OmsOrder::getId, id)
|
||||||
.eq(OmsOrder::getMemberId, userId));
|
.eq(OmsOrder::getMemberId, memberId));
|
||||||
if (order == null) {
|
if (order == null) {
|
||||||
throw new BizException("订单不存在,订单ID非法");
|
throw new BizException("订单不存在,订单ID非法");
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ package com.youlai.mall.pms.common.constant;
|
|||||||
*/
|
*/
|
||||||
public interface PmsConstants {
|
public interface PmsConstants {
|
||||||
|
|
||||||
String STOCK_LOCKED_PREFIX = "stock:locked:";
|
String LOCKED_STOCK_PREFIX = "stock:locked:";
|
||||||
|
|
||||||
String LOCK_SKU_PREFIX="lock:sku:";
|
String LOCK_SKU_PREFIX="lock:sku:";
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.youlai.common.web.exception.BizException;
|
import com.youlai.common.web.exception.BizException;
|
||||||
import com.youlai.mall.pms.common.constant.PmsConstants;
|
|
||||||
import com.youlai.mall.pms.mapper.PmsSkuMapper;
|
import com.youlai.mall.pms.mapper.PmsSkuMapper;
|
||||||
import com.youlai.mall.pms.pojo.domain.PmsSku;
|
import com.youlai.mall.pms.pojo.domain.PmsSku;
|
||||||
import com.youlai.mall.pms.pojo.dto.SkuDTO;
|
import com.youlai.mall.pms.pojo.dto.SkuDTO;
|
||||||
@ -24,8 +23,8 @@ import org.springframework.stereotype.Service;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.youlai.mall.pms.common.constant.PmsConstants.LOCKED_STOCK_PREFIX;
|
||||||
import static com.youlai.mall.pms.common.constant.PmsConstants.LOCK_SKU_PREFIX;
|
import static com.youlai.mall.pms.common.constant.PmsConstants.LOCK_SKU_PREFIX;
|
||||||
import static com.youlai.mall.pms.common.constant.PmsConstants.STOCK_LOCKED_PREFIX;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -41,7 +40,8 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean lockStock(List<SkuLockDTO> skuLockList) {
|
public boolean lockStock(List<SkuLockDTO> skuLockList) {
|
||||||
|
log.info("=======================创建订单,开始锁定商品库存=======================");
|
||||||
|
log.info("锁定商品信息:{}", skuLockList.toString());
|
||||||
if (CollectionUtil.isEmpty(skuLockList)) {
|
if (CollectionUtil.isEmpty(skuLockList)) {
|
||||||
throw new BizException("锁定的商品列表为空");
|
throw new BizException("锁定的商品列表为空");
|
||||||
}
|
}
|
||||||
@ -80,7 +80,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
|
|
||||||
// 将锁定的商品保存至Redis中
|
// 将锁定的商品保存至Redis中
|
||||||
String orderToken = skuLockList.get(0).getOrderToken();
|
String orderToken = skuLockList.get(0).getOrderToken();
|
||||||
redisTemplate.opsForValue().set(STOCK_LOCKED_PREFIX + orderToken, JSONUtil.toJsonStr(skuLockList));
|
redisTemplate.opsForValue().set(LOCKED_STOCK_PREFIX + orderToken, JSONUtil.toJsonStr(skuLockList));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,9 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean unlockStock(String orderToken) {
|
public boolean unlockStock(String orderToken) {
|
||||||
String json = redisTemplate.opsForValue().get(STOCK_LOCKED_PREFIX + orderToken);
|
log.info("=======================订单超时未支付系统自动关单释放库存=======================");
|
||||||
|
String json = redisTemplate.opsForValue().get(LOCKED_STOCK_PREFIX + orderToken);
|
||||||
|
log.info("释放库存信息:{}", json);
|
||||||
if (StrUtil.isNotBlank(json)) {
|
if (StrUtil.isNotBlank(json)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -103,7 +105,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 删除redis中锁定的库存
|
// 删除redis中锁定的库存
|
||||||
redisTemplate.opsForValue().decrement(STOCK_LOCKED_PREFIX + orderToken);
|
redisTemplate.delete(LOCKED_STOCK_PREFIX + orderToken);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,7 +114,9 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean deductStock(String orderToken) {
|
public boolean deductStock(String orderToken) {
|
||||||
String json = redisTemplate.opsForValue().get(STOCK_LOCKED_PREFIX + orderToken);
|
log.info("=======================支付成功扣减订单中商品库存=======================");
|
||||||
|
String json = redisTemplate.opsForValue().get(LOCKED_STOCK_PREFIX + orderToken);
|
||||||
|
log.info("订单商品信息:{}", json);
|
||||||
if (StrUtil.isBlank(json)) {
|
if (StrUtil.isBlank(json)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -131,7 +135,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
});
|
});
|
||||||
|
|
||||||
// 删除redis中锁定的库存
|
// 删除redis中锁定的库存
|
||||||
redisTemplate.opsForValue().decrement(STOCK_LOCKED_PREFIX + orderToken);
|
redisTemplate.delete(LOCKED_STOCK_PREFIX + orderToken);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,7 +152,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
public Integer getStockById(Long id) {
|
public Integer getStockById(Long id) {
|
||||||
Integer stock = 0;
|
Integer stock = 0;
|
||||||
// 读->缓存
|
// 读->缓存
|
||||||
Object cacheVal = redisTemplate.opsForValue().get(STOCK_LOCKED_PREFIX + id);
|
Object cacheVal = redisTemplate.opsForValue().get(LOCKED_STOCK_PREFIX + id);
|
||||||
if (cacheVal != null) {
|
if (cacheVal != null) {
|
||||||
stock = Convert.toInt(cacheVal);
|
stock = Convert.toInt(cacheVal);
|
||||||
return stock;
|
return stock;
|
||||||
@ -162,7 +166,7 @@ public class PmsSkuServiceImpl extends ServiceImpl<PmsSkuMapper, PmsSku> impleme
|
|||||||
if (pmsSku != null) {
|
if (pmsSku != null) {
|
||||||
stock = pmsSku.getStock();
|
stock = pmsSku.getStock();
|
||||||
// 写->缓存
|
// 写->缓存
|
||||||
redisTemplate.opsForValue().set(PmsConstants.STOCK_LOCKED_PREFIX + id, String.valueOf(stock));
|
redisTemplate.opsForValue().set(LOCKED_STOCK_PREFIX + id, String.valueOf(stock));
|
||||||
}
|
}
|
||||||
|
|
||||||
return stock;
|
return stock;
|
||||||
|
@ -60,7 +60,8 @@
|
|||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
<!-- 根logger -->
|
<!-- 根logger -->
|
||||||
<root level="INFO">
|
<root>
|
||||||
|
<level>INFO</level>
|
||||||
<appender-ref ref="CONSOLE"/>
|
<appender-ref ref="CONSOLE"/>
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
||||||
|
Loading…
Reference in New Issue
Block a user