239 lines
5.6 KiB
Markdown
239 lines
5.6 KiB
Markdown
# 订单服务开发文档 - Part 1(Entity + DTO + Service接口)
|
||
|
||
## 一、Entity 实体类
|
||
|
||
### Order.java
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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
|
||
|
||
```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 工具类
|
||
|
||
```java
|
||
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
|