Kaynağa Gözat

feat(phase1): ProductOrder 实体/Mapper/Service 实现

User 3 ay önce
ebeveyn
işleme
2de3478c6a

+ 11 - 0
zxyj-backend/src/main/java/com/zxyj/dto/CreateProductOrderDTO.java

@@ -0,0 +1,11 @@
+package com.zxyj.dto;
+
+import lombok.Data;
+
+@Data
+public class CreateProductOrderDTO {
+    private Long productId;
+    private Integer quantity = 1;
+    private String paymentMethod;
+    private String remark;
+}

+ 48 - 0
zxyj-backend/src/main/java/com/zxyj/dto/ProductOrderDTO.java

@@ -0,0 +1,48 @@
+package com.zxyj.dto;
+
+import com.zxyj.entity.ProductOrder;
+import lombok.Data;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+public class ProductOrderDTO {
+    private Long id;
+    private String orderNo;
+    private Long productId;
+    private String productName;
+    private String productType;
+    private Long buyerId;
+    private String buyerName;
+    private Long familyId;
+    private Integer quantity;
+    private BigDecimal unitPrice;
+    private BigDecimal totalAmount;
+    private String status;
+    private String paymentMethod;
+    private String remark;
+    private Date paidAt;
+    private Date createdAt;
+
+    public static ProductOrderDTO from(ProductOrder o) {
+        if (o == null) return null;
+        ProductOrderDTO d = new ProductOrderDTO();
+        d.id = o.getId();
+        d.orderNo = o.getOrderNo();
+        d.productId = o.getProductId();
+        d.productName = o.getProductName();
+        d.productType = o.getProductType();
+        d.buyerId = o.getBuyerId();
+        d.familyId = o.getFamilyId();
+        d.quantity = o.getQuantity();
+        d.unitPrice = o.getUnitPrice();
+        d.totalAmount = o.getTotalAmount();
+        d.status = o.getStatus();
+        d.paymentMethod = o.getPaymentMethod();
+        d.remark = o.getRemark();
+        d.paidAt = o.getPaidAt();
+        d.createdAt = o.getCreatedAt();
+        return d;
+    }
+}

+ 34 - 0
zxyj-backend/src/main/java/com/zxyj/entity/ProductOrder.java

@@ -0,0 +1,34 @@
+package com.zxyj.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+@Data
+@TableName("product_orders")
+public class ProductOrder implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    private String orderNo;
+    private Long productId;
+    private String productName;
+    private String productType;
+    private Long buyerId;
+    private Long familyId;
+    private Integer quantity;
+    private BigDecimal unitPrice;
+    private BigDecimal totalAmount;
+    private String status;
+    private String paymentMethod;
+    private String remark;
+    private Date paidAt;
+    private Date createdAt;
+    private Date updatedAt;
+}

+ 9 - 0
zxyj-backend/src/main/java/com/zxyj/mapper/ProductOrderMapper.java

@@ -0,0 +1,9 @@
+package com.zxyj.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.zxyj.entity.ProductOrder;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface ProductOrderMapper extends BaseMapper<ProductOrder> {
+}

+ 187 - 0
zxyj-backend/src/main/java/com/zxyj/service/ProductOrderService.java

@@ -0,0 +1,187 @@
+package com.zxyj.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.zxyj.common.Result;
+import com.zxyj.dto.CreateProductOrderDTO;
+import com.zxyj.dto.ProductOrderDTO;
+import com.zxyj.entity.Product;
+import com.zxyj.entity.ProductOrder;
+import com.zxyj.entity.User;
+import com.zxyj.mapper.ProductMapper;
+import com.zxyj.mapper.ProductOrderMapper;
+import com.zxyj.mapper.UserMapper;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Service
+public class ProductOrderService {
+
+    @Resource
+    private ProductOrderMapper orderMapper;
+
+    @Resource
+    private ProductMapper productMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private ProductService productService;
+
+    public Result<ProductOrderDTO> create(CreateProductOrderDTO dto, Long buyerId) {
+        if (buyerId == null) {
+            return Result.error("请先登录");
+        }
+        Product product = productMapper.selectById(dto.getProductId());
+        if (product == null) {
+            return Result.error("商品不存在");
+        }
+        if (!"on_shelf".equals(product.getStatus())) {
+            return Result.error("商品已下架");
+        }
+        if (product.getStock() != null && product.getStock() < dto.getQuantity()) {
+            return Result.error("库存不足");
+        }
+
+        User buyer = userMapper.selectById(buyerId);
+        ProductOrder order = new ProductOrder();
+        order.setOrderNo(generateOrderNo());
+        order.setProductId(product.getId());
+        order.setProductName(product.getName());
+        order.setProductType(product.getProductType());
+        order.setBuyerId(buyerId);
+        order.setFamilyId(buyer != null ? buyer.getFamilyId() : null);
+        order.setQuantity(dto.getQuantity());
+        order.setUnitPrice(product.getPrice());
+        order.setTotalAmount(product.getPrice().multiply(BigDecimal.valueOf(dto.getQuantity())));
+        order.setStatus("pending");
+        order.setPaymentMethod(dto.getPaymentMethod() != null ? dto.getPaymentMethod() : "wechat");
+        order.setRemark(dto.getRemark());
+        order.setCreatedAt(new Date());
+        order.setUpdatedAt(new Date());
+        orderMapper.insert(order);
+        return Result.success(ProductOrderDTO.from(order));
+    }
+
+    public Result<ProductOrderDTO> pay(String orderNo, Long userId) {
+        ProductOrder order = orderMapper.selectOne(
+            new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getOrderNo, orderNo));
+        if (order == null) {
+            return Result.error("订单不存在");
+        }
+        if (!order.getBuyerId().equals(userId)) {
+            return Result.error("无权操作此订单");
+        }
+        if (!"pending".equals(order.getStatus())) {
+            return Result.error("订单状态异常");
+        }
+        boolean stockOk = productService.decreaseStock(order.getProductId(), order.getQuantity());
+        if (!stockOk) {
+            return Result.error("库存不足");
+        }
+        order.setStatus("paid");
+        order.setPaidAt(new Date());
+        order.setUpdatedAt(new Date());
+        orderMapper.updateById(order);
+        return Result.success(ProductOrderDTO.from(order));
+    }
+
+    public Result<String> cancel(String orderNo, Long userId) {
+        ProductOrder order = orderMapper.selectOne(
+            new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getOrderNo, orderNo));
+        if (order == null) {
+            return Result.error("订单不存在");
+        }
+        if (!order.getBuyerId().equals(userId)) {
+            return Result.error("无权操作此订单");
+        }
+        if (!"pending".equals(order.getStatus())) {
+            return Result.error("仅待支付订单可取消");
+        }
+        order.setStatus("cancelled");
+        order.setUpdatedAt(new Date());
+        orderMapper.updateById(order);
+        return Result.success("订单已取消");
+    }
+
+    public Result<List<ProductOrderDTO>> myOrders(Long buyerId, String status) {
+        LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
+            .eq(ProductOrder::getBuyerId, buyerId)
+            .orderByDesc(ProductOrder::getCreatedAt);
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(ProductOrder::getStatus, status);
+        }
+        List<ProductOrder> list = orderMapper.selectList(wrapper);
+        return Result.success(list.stream().map(ProductOrderDTO::from).collect(Collectors.toList()));
+    }
+
+    public Result<ProductOrderDTO> detail(String orderNo, Long userId) {
+        ProductOrder order = orderMapper.selectOne(
+            new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getOrderNo, orderNo));
+        if (order == null) {
+            return Result.error("订单不存在");
+        }
+        Product product = productMapper.selectById(order.getProductId());
+        boolean isBuyer = order.getBuyerId().equals(userId);
+        boolean isVendor = product != null && product.getVendorId() != null && product.getVendorId().equals(userId);
+        if (!isBuyer && !isVendor) {
+            return Result.error("无权查看");
+        }
+        return Result.success(ProductOrderDTO.from(order));
+    }
+
+    public Result<List<ProductOrderDTO>> vendorOrders(Long vendorId, String status) {
+        List<Product> products = productMapper.selectList(
+            new LambdaQueryWrapper<Product>().eq(Product::getVendorId, vendorId));
+        if (products == null || products.isEmpty()) {
+            return Result.success(java.util.Collections.emptyList());
+        }
+        List<Long> productIds = products.stream().map(Product::getId).collect(Collectors.toList());
+        LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
+            .in(ProductOrder::getProductId, productIds)
+            .orderByDesc(ProductOrder::getCreatedAt);
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(ProductOrder::getStatus, status);
+        }
+        List<ProductOrder> list = orderMapper.selectList(wrapper);
+        return Result.success(list.stream().map(ProductOrderDTO::from).collect(Collectors.toList()));
+    }
+
+    public Result<List<ProductOrderDTO>> adminList(String status) {
+        LambdaQueryWrapper<ProductOrder> wrapper = new LambdaQueryWrapper<ProductOrder>()
+            .orderByDesc(ProductOrder::getCreatedAt);
+        if (status != null && !status.isEmpty()) {
+            wrapper.eq(ProductOrder::getStatus, status);
+        }
+        List<ProductOrder> list = orderMapper.selectList(wrapper);
+        return Result.success(list.stream().map(ProductOrderDTO::from).collect(Collectors.toList()));
+    }
+
+    public Result<String> confirm(String orderNo, Long vendorId) {
+        ProductOrder order = orderMapper.selectOne(
+            new LambdaQueryWrapper<ProductOrder>().eq(ProductOrder::getOrderNo, orderNo));
+        if (order == null) {
+            return Result.error("订单不存在");
+        }
+        Product product = productMapper.selectById(order.getProductId());
+        if (product == null || !product.getVendorId().equals(vendorId)) {
+            return Result.error("无权操作");
+        }
+        if (!"paid".equals(order.getStatus())) {
+            return Result.error("仅已支付订单可确认完成");
+        }
+        order.setStatus("completed");
+        order.setUpdatedAt(new Date());
+        orderMapper.updateById(order);
+        return Result.success("订单已完成");
+    }
+
+    private String generateOrderNo() {
+        return "PO" + System.currentTimeMillis();
+    }
+}