|
@@ -0,0 +1,201 @@
|
|
|
|
+package com.futu.goose.orders.service.impl;
|
|
|
|
+
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.futu.goose.orders.dto.OrderDto;
|
|
|
|
+import com.futu.goose.orders.dto.ProductDto;
|
|
|
|
+import com.futu.goose.orders.mapper.TCouponMapper;
|
|
|
|
+import com.futu.goose.orders.mapper.TOrderItemMapper;
|
|
|
|
+import com.futu.goose.orders.mapper.TProductMapper;
|
|
|
|
+import com.futu.goose.orders.pojo.TCoupon;
|
|
|
|
+import com.futu.goose.orders.pojo.TOrder;
|
|
|
|
+import com.futu.goose.orders.pojo.TOrderItem;
|
|
|
|
+import com.futu.goose.orders.pojo.TProduct;
|
|
|
|
+import com.futu.goose.orders.service.TOrderService;
|
|
|
|
+import com.futu.goose.orders.mapper.TOrderMapper;
|
|
|
|
+import com.futu.goose.utils.RedisClient;
|
|
|
|
+import com.futu.goose.utils.Result;
|
|
|
|
+import com.futu.goose.utils.SnowflakeIdGenerator;
|
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+
|
|
|
|
+import java.math.BigDecimal;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @author 张大宇
|
|
|
|
+ * @description 针对表【t_order(订单主表)】的数据库操作Service实现
|
|
|
|
+ * @createDate 2025-05-13 16:26:58
|
|
|
|
+ */
|
|
|
|
+@Service
|
|
|
|
+public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder>
|
|
|
|
+ implements TOrderService {
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private TOrderMapper orderMapper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private TOrderItemMapper orderItemMapper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private TProductMapper productMapper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private TCouponMapper couponMapper;
|
|
|
|
+
|
|
|
|
+ @Autowired
|
|
|
|
+ private RedisClient redisClient;
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public Result addOrders(OrderDto orderDto) {
|
|
|
|
+ // 输入校验
|
|
|
|
+ if (orderDto == null) {
|
|
|
|
+ return new Result(false, "订单信息不能为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 创建订单对象
|
|
|
|
+ TOrder tOrder = new TOrder();
|
|
|
|
+ tOrder.setId(SnowflakeIdGenerator.getSnowId());
|
|
|
|
+
|
|
|
|
+ // 获取用户ID
|
|
|
|
+ Object uidObj = redisClient.get("uid");
|
|
|
|
+ Long userId = parseUserId(uidObj);
|
|
|
|
+ tOrder.setUserId(userId);
|
|
|
|
+
|
|
|
|
+ // 设置优惠券ID
|
|
|
|
+ Long couponId = orderDto.getId();
|
|
|
|
+ tOrder.setCouponId(couponId);
|
|
|
|
+
|
|
|
|
+ // 获取优惠券信息并校验
|
|
|
|
+ TCoupon tCoupon = null;
|
|
|
|
+ if (couponId != null) {
|
|
|
|
+ QueryWrapper<TCoupon> wrapper = new QueryWrapper<>();
|
|
|
|
+ tCoupon = couponMapper.selectOne(wrapper.lambda().eq(TCoupon::getId, couponId));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 检查优惠券有效性
|
|
|
|
+ if (tCoupon == null || !"可用".equals(tCoupon.getStatus())) {
|
|
|
|
+ return new Result(false, "优惠券不可用或不存在");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算商品总金额
|
|
|
|
+ BigDecimal totalAmount = calculateTotalAmount(orderDto.getProductList());
|
|
|
|
+ if (totalAmount == null || totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
|
|
|
|
+ return new Result(false, "订单金额不能为零或负数");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 设置订单总金额
|
|
|
|
+ tOrder.setTotalAmount(totalAmount);
|
|
|
|
+
|
|
|
|
+ // 计算优惠金额
|
|
|
|
+ BigDecimal discountAmount = calculateDiscountAmount(totalAmount, tCoupon);
|
|
|
|
+ tOrder.setDiscountAmount(discountAmount);
|
|
|
|
+
|
|
|
|
+ // 计算应付金额
|
|
|
|
+ BigDecimal payableAmount = totalAmount.subtract(discountAmount);
|
|
|
|
+ tOrder.setPayableAmount(payableAmount);
|
|
|
|
+
|
|
|
|
+ // 插入订单主表
|
|
|
|
+ orderMapper.insert(tOrder);
|
|
|
|
+
|
|
|
|
+ // 插入订单明细
|
|
|
|
+ createOrderItems(tOrder.getId(), orderDto.getProductList());
|
|
|
|
+
|
|
|
|
+ return new Result(true, "订单创建成功");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 解析用户ID
|
|
|
|
+ private Long parseUserId(Object uidObj) {
|
|
|
|
+ if (uidObj == null) {
|
|
|
|
+ throw new IllegalArgumentException("用户ID不能为空");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (uidObj instanceof Long) {
|
|
|
|
+ return (Long) uidObj;
|
|
|
|
+ } else if (uidObj instanceof Integer) {
|
|
|
|
+ return Long.valueOf((Integer) uidObj);
|
|
|
|
+ } else if (uidObj instanceof String) {
|
|
|
|
+ try {
|
|
|
|
+ return Long.parseLong((String) uidObj);
|
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
|
+ throw new IllegalArgumentException("无效的用户ID格式: " + uidObj, e);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ throw new IllegalArgumentException("不支持的用户ID类型: " + uidObj.getClass());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算商品总金额
|
|
|
|
+ private BigDecimal calculateTotalAmount(List<ProductDto> productList) {
|
|
|
|
+ if (productList == null || productList.isEmpty()) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ BigDecimal total = BigDecimal.ZERO;
|
|
|
|
+
|
|
|
|
+ for (ProductDto productDto : productList) {
|
|
|
|
+ if (productDto == null || productDto.getProductId() == null || productDto.getNum() <= 0) {
|
|
|
|
+ continue; // 跳过无效商品
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询商品信息
|
|
|
|
+ QueryWrapper<TProduct> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ TProduct tProduct = productMapper.selectOne(
|
|
|
|
+ queryWrapper.lambda().eq(TProduct::getId, productDto.getProductId()));
|
|
|
|
+
|
|
|
|
+ if (tProduct != null && tProduct.getPrice() != null) {
|
|
|
|
+ // 计算商品小计: 单价 * 数量
|
|
|
|
+ BigDecimal quantity = new BigDecimal(productDto.getNum());
|
|
|
|
+ BigDecimal subtotal = tProduct.getPrice().multiply(quantity);
|
|
|
|
+ total = total.add(subtotal);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return total;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 计算优惠金额
|
|
|
|
+ private BigDecimal calculateDiscountAmount(BigDecimal totalAmount, TCoupon coupon) {
|
|
|
|
+ if (totalAmount == null || coupon == null) {
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 判断是否达到优惠门槛
|
|
|
|
+ if (totalAmount.compareTo(coupon.getThreshold()) >= 0) {
|
|
|
|
+ return coupon.getAmount();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return BigDecimal.ZERO;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 创建订单明细
|
|
|
|
+ private void createOrderItems(Long orderId, List<ProductDto> productList) {
|
|
|
|
+ if (orderId == null || productList == null || productList.isEmpty()) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (ProductDto productDto : productList) {
|
|
|
|
+ if (productDto == null || productDto.getProductId() == null || productDto.getNum() <= 0) {
|
|
|
|
+ continue; // 跳过无效商品
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 查询商品信息
|
|
|
|
+ QueryWrapper<TProduct> queryWrapper = new QueryWrapper<>();
|
|
|
|
+ TProduct tProduct = productMapper.selectOne(
|
|
|
|
+ queryWrapper.lambda().eq(TProduct::getId, productDto.getProductId()));
|
|
|
|
+
|
|
|
|
+ if (tProduct != null) {
|
|
|
|
+ // 创建订单明细
|
|
|
|
+ TOrderItem orderItem = new TOrderItem();
|
|
|
|
+ orderItem.setId(SnowflakeIdGenerator.getSnowId());
|
|
|
|
+ orderItem.setOrderId(orderId);
|
|
|
|
+ orderItem.setSkuId(tProduct.getSkuId());
|
|
|
|
+ orderItem.setUnitPrice(tProduct.getPrice());
|
|
|
|
+ orderItem.setQuantity(productDto.getNum());
|
|
|
|
+ orderItem.setTotalAmount(tProduct.getPrice().multiply(new BigDecimal(productDto.getNum())));
|
|
|
|
+ // 插入订单明细
|
|
|
|
+ orderItemMapper.insert(orderItem);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|