Files
number/后端架构设计/07-订单服务开发文档-part1.md
2026-03-17 12:09:43 +08:00

5.6 KiB
Raw Blame History

订单服务开发文档 - Part 1Entity + DTO + Service接口

一、Entity 实体类

Order.java

package com.openclaw.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@TableName("orders")
public class Order {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String orderNo;
    private Long userId;
    private BigDecimal totalAmount;
    private BigDecimal cashAmount;
    private Integer pointsUsed;
    private BigDecimal pointsDeductAmount;
    private String status;        // pending/paid/completed/cancelled/refunding/refunded
    private String paymentMethod; // wechat/alipay/points/mixed
    private String remark;
    private String cancelReason;
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    private LocalDateTime paidAt;
    private LocalDateTime expiredAt;
}

OrderItem.java

package com.openclaw.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("order_items")
public class OrderItem {
    @TableId(type = IdType.AUTO)
    private Long id;
    private Long orderId;
    private Long skillId;
    private String skillName;    // 下单时快照
    private String skillCover;   // 下单时快照
    private BigDecimal unitPrice;
    private Integer quantity;
    private BigDecimal totalPrice;
}

OrderRefund.java

package com.openclaw.entity;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Data
@TableName("order_refunds")
public class OrderRefund {
    @TableId(type = IdType.AUTO)
    private Long id;
    private Long orderId;
    private String refundNo;
    private BigDecimal refundAmount;
    private Integer refundPoints;
    private String reason;
    private String images;       // JSON
    private String status;       // pending/approved/rejected/completed
    private String rejectReason;
    private Long operatorId;           // 处理人ID
    private LocalDateTime processedAt; // 处理时间
    private String remark;             // 处理备注
    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;
    private LocalDateTime completedAt;
}

二、DTO / VO

OrderCreateDTO.java

package com.openclaw.dto;

import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;

@Data
public class OrderCreateDTO {
    @NotEmpty(message = "请选择要购买的Skill")
    private List<Long> skillIds;
    private Integer pointsToUse = 0;    // 使用积分数
    private String paymentMethod;       // wechat/alipay/points/mixed
}

RefundApplyDTO.java

package com.openclaw.dto;

import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.List;

@Data
public class RefundApplyDTO {
    @NotBlank(message = "请填写退款原因")
    private String reason;
    private List<String> images; // 腾讯云COS URL
}

OrderVO.java

package com.openclaw.vo;

import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

@Data
public class OrderVO {
    private Long id;
    private String orderNo;
    private BigDecimal totalAmount;
    private BigDecimal cashAmount;
    private Integer pointsUsed;
    private BigDecimal pointsDeductAmount;
    private String status;
    private String statusLabel;       // 中文状态
    private String paymentMethod;
    private LocalDateTime createdAt;
    private LocalDateTime paidAt;
    private List<OrderItemVO> items;
}

OrderItemVO.java

package com.openclaw.vo;

import lombok.Data;
import java.math.BigDecimal;

@Data
public class OrderItemVO {
    private Long skillId;
    private String skillName;
    private String skillCover;
    private BigDecimal unitPrice;
    private Integer quantity;
    private BigDecimal totalPrice;
}

三、Service 接口

OrderService.java

package com.openclaw.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.openclaw.dto.*;
import com.openclaw.vo.*;

public interface OrderService {
    /** 创建订单(含积分抵扣计算) */
    OrderVO createOrder(Long userId, OrderCreateDTO dto);

    /** 订单详情 */
    OrderVO getOrderDetail(Long orderId, Long userId);

    /** 订单列表(分页) */
    IPage<OrderVO> listOrders(Long userId, String status, int pageNum, int pageSize);

    /** 取消订单 */
    void cancelOrder(Long orderId, Long userId, String reason);

    /** 支付成功回调处理 */
    void handlePaySuccess(String orderNo, String transactionId);

    /** 申请退款 */
    void applyRefund(Long orderId, Long userId, RefundApplyDTO dto);
}

四、IdGenerator 工具类

package com.openclaw.util;

import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class IdGenerator {
    private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private final AtomicInteger seq = new AtomicInteger(1000);

    public String generateOrderNo() {
        return LocalDateTime.now().format(FMT) + seq.incrementAndGet();
    }

    public String generateRefundNo() {
        return "R" + LocalDateTime.now().format(FMT) + seq.incrementAndGet();
    }

    public String generateRechargeNo() {
        return "RC" + LocalDateTime.now().format(FMT) + seq.incrementAndGet();
    }
}

文档版本v1.0 | 创建日期2026-03-16