You've already forked FrameTour-BE
feat(order): 新增订单管理功能 V2
- 新增订单创建、查询、备注更新、申请退款等接口 - 添加订单相关实体类和枚举类 - 实现订单事件监听器,处理支付、退款、订单状态变化 - 优化移动端订单创建逻辑,集成订单服务
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package com.ycwl.basic.controller.mobile;
|
package com.ycwl.basic.controller.mobile;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
import com.ycwl.basic.constant.BaseContextHandler;
|
import com.ycwl.basic.constant.BaseContextHandler;
|
||||||
import com.ycwl.basic.utils.ApiResponse;
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
import com.ycwl.basic.pricing.dto.*;
|
import com.ycwl.basic.pricing.dto.*;
|
||||||
@@ -8,6 +9,10 @@ import com.ycwl.basic.service.pc.FaceService;
|
|||||||
import com.ycwl.basic.service.PriceCacheService;
|
import com.ycwl.basic.service.PriceCacheService;
|
||||||
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
import com.ycwl.basic.model.pc.face.resp.FaceRespVO;
|
||||||
import com.ycwl.basic.dto.MobileOrderRequest;
|
import com.ycwl.basic.dto.MobileOrderRequest;
|
||||||
|
import com.ycwl.basic.order.service.IOrderService;
|
||||||
|
import com.ycwl.basic.order.dto.OrderV2DetailResponse;
|
||||||
|
import com.ycwl.basic.order.dto.OrderV2ListResponse;
|
||||||
|
import com.ycwl.basic.order.dto.OrderV2PageRequest;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@@ -27,6 +32,7 @@ public class AppOrderV2Controller {
|
|||||||
private final IPriceCalculationService priceCalculationService;
|
private final IPriceCalculationService priceCalculationService;
|
||||||
private final FaceService faceService;
|
private final FaceService faceService;
|
||||||
private final PriceCacheService priceCacheService;
|
private final PriceCacheService priceCacheService;
|
||||||
|
private final IOrderService orderService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 移动端价格计算
|
* 移动端价格计算
|
||||||
@@ -157,20 +163,80 @@ public class AppOrderV2Controller {
|
|||||||
log.info("价格缓存验证通过: userId={}, scenicId={}, finalAmount={}",
|
log.info("价格缓存验证通过: userId={}, scenicId={}, finalAmount={}",
|
||||||
currentUserId, scenicId, cachedResult.getFinalAmount());
|
currentUserId, scenicId, cachedResult.getFinalAmount());
|
||||||
|
|
||||||
// TODO: 实现订单创建逻辑
|
// 创建订单
|
||||||
// 1. 生成订单号
|
try {
|
||||||
// 2. 创建订单基础信息
|
Long orderId = orderService.createOrder(request, currentUserId, scenicId, cachedResult);
|
||||||
// 3. 保存订单商品明细
|
|
||||||
// 4. 记录使用的优惠券和券码信息
|
|
||||||
// 5. 更新优惠券和券码状态
|
|
||||||
// 6. 初始化订单状态为待支付
|
|
||||||
// 7. 发送订单创建成功通知
|
|
||||||
|
|
||||||
String orderId = "ORDER_" + System.currentTimeMillis(); // 临时订单号生成逻辑
|
log.info("移动端订单创建成功: orderId={}, userId={}, scenicId={}, finalAmount={}",
|
||||||
|
orderId, currentUserId, scenicId, cachedResult.getFinalAmount());
|
||||||
|
|
||||||
log.info("移动端订单创建成功: orderId={}, userId={}, scenicId={}, finalAmount={}",
|
return ApiResponse.success(orderId.toString());
|
||||||
orderId, currentUserId, scenicId, cachedResult.getFinalAmount());
|
|
||||||
|
|
||||||
return ApiResponse.success(orderId);
|
} catch (Exception e) {
|
||||||
|
log.error("订单创建失败: userId={}, scenicId={}, error={}", currentUserId, scenicId, e.getMessage(), e);
|
||||||
|
return ApiResponse.fail("订单创建失败,请稍后重试");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== 新增移动端订单查询功能 ======
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户分页查询自己的订单列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/page")
|
||||||
|
public ApiResponse<PageInfo<OrderV2ListResponse>> pageUserOrders(@RequestBody OrderV2PageRequest request) {
|
||||||
|
String currentUserIdStr = BaseContextHandler.getUserId();
|
||||||
|
if (currentUserIdStr == null) {
|
||||||
|
log.warn("用户未登录");
|
||||||
|
return ApiResponse.fail("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long currentUserId = Long.valueOf(currentUserIdStr);
|
||||||
|
request.setMemberId(currentUserId); // 设置当前用户ID,确保只查询自己的订单
|
||||||
|
|
||||||
|
log.info("用户查询订单列表: userId={}, request={}", currentUserId, request);
|
||||||
|
|
||||||
|
try {
|
||||||
|
PageInfo<OrderV2ListResponse> pageInfo = orderService.pageOrdersByUser(request);
|
||||||
|
return ApiResponse.success(pageInfo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询用户订单列表失败: userId={}", currentUserId, e);
|
||||||
|
return ApiResponse.fail("查询失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户查询自己的订单详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/detail/{orderId}")
|
||||||
|
public ApiResponse<OrderV2DetailResponse> getUserOrderDetail(@PathVariable("orderId") Long orderId) {
|
||||||
|
String currentUserIdStr = BaseContextHandler.getUserId();
|
||||||
|
if (currentUserIdStr == null) {
|
||||||
|
log.warn("用户未登录");
|
||||||
|
return ApiResponse.fail("用户未登录");
|
||||||
|
}
|
||||||
|
|
||||||
|
Long currentUserId = Long.valueOf(currentUserIdStr);
|
||||||
|
|
||||||
|
log.info("用户查询订单详情: userId={}, orderId={}", currentUserId, orderId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OrderV2DetailResponse detail = orderService.getOrderDetail(orderId);
|
||||||
|
if (detail == null) {
|
||||||
|
return ApiResponse.fail("订单不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证订单是否属于当前用户
|
||||||
|
if (!currentUserId.equals(detail.getMemberId())) {
|
||||||
|
log.warn("用户尝试访问他人订单: userId={}, orderId={}, orderOwner={}",
|
||||||
|
currentUserId, orderId, detail.getMemberId());
|
||||||
|
return ApiResponse.fail("无权访问该订单");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ApiResponse.success(detail);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询用户订单详情失败: userId={}, orderId={}", currentUserId, orderId, e);
|
||||||
|
return ApiResponse.fail("查询失败:" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,89 @@
|
|||||||
|
package com.ycwl.basic.order.controller;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.ycwl.basic.order.dto.*;
|
||||||
|
import com.ycwl.basic.order.service.IOrderService;
|
||||||
|
import com.ycwl.basic.utils.ApiResponse;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单管理控制器V2 - 管理端
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/order/v2")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OrderV2Controller {
|
||||||
|
|
||||||
|
private final IOrderService orderService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询订单列表
|
||||||
|
*/
|
||||||
|
@PostMapping("/page")
|
||||||
|
public ApiResponse<PageInfo<OrderV2ListResponse>> pageOrders(@RequestBody OrderV2PageRequest request) {
|
||||||
|
log.info("分页查询订单列表: {}", request);
|
||||||
|
try {
|
||||||
|
PageInfo<OrderV2ListResponse> pageInfo = orderService.pageOrders(request);
|
||||||
|
return ApiResponse.success(pageInfo);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("分页查询订单列表失败", e);
|
||||||
|
return ApiResponse.fail("查询失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/detail/{orderId}")
|
||||||
|
public ApiResponse<OrderV2DetailResponse> getOrderDetail(@PathVariable("orderId") Long orderId) {
|
||||||
|
log.info("查询订单详情: orderId={}", orderId);
|
||||||
|
try {
|
||||||
|
OrderV2DetailResponse detail = orderService.getOrderDetail(orderId);
|
||||||
|
if (detail == null) {
|
||||||
|
return ApiResponse.fail("订单不存在");
|
||||||
|
}
|
||||||
|
return ApiResponse.success(detail);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询订单详情失败: orderId={}", orderId, e);
|
||||||
|
return ApiResponse.fail("查询失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单备注
|
||||||
|
*/
|
||||||
|
@PutMapping("/remark/{orderId}")
|
||||||
|
public ApiResponse<String> updateOrderRemarks(@PathVariable("orderId") Long orderId,
|
||||||
|
@RequestBody OrderRemarkRequest request) {
|
||||||
|
log.info("更新订单备注: orderId={}, remarks={}", orderId, request.getRemarks());
|
||||||
|
try {
|
||||||
|
boolean success = orderService.updateOrderRemarks(orderId, request.getRemarks());
|
||||||
|
if (success) {
|
||||||
|
return ApiResponse.success("备注更新成功");
|
||||||
|
} else {
|
||||||
|
return ApiResponse.fail("备注更新失败");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("更新订单备注失败: orderId={}", orderId, e);
|
||||||
|
return ApiResponse.fail("更新失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请退款
|
||||||
|
*/
|
||||||
|
@PostMapping("/refund")
|
||||||
|
public ApiResponse<String> createRefund(@RequestBody RefundRequest request) {
|
||||||
|
log.info("申请退款: {}", request);
|
||||||
|
try {
|
||||||
|
Long refundId = orderService.createRefundRecord(request);
|
||||||
|
return ApiResponse.success("退款申请已提交,退款ID:" + refundId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("申请退款失败: {}", request, e);
|
||||||
|
return ApiResponse.fail("退款申请失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,15 @@
|
|||||||
|
package com.ycwl.basic.order.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注修改请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderRemarkRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注
|
||||||
|
*/
|
||||||
|
private String remarks;
|
||||||
|
}
|
@@ -0,0 +1,150 @@
|
|||||||
|
package com.ycwl.basic.order.dto;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.entity.OrderDiscountV2;
|
||||||
|
import com.ycwl.basic.order.entity.OrderItemV2;
|
||||||
|
import com.ycwl.basic.order.entity.OrderRefundV2;
|
||||||
|
import com.ycwl.basic.order.enums.OrderStatus;
|
||||||
|
import com.ycwl.basic.order.enums.PaymentStatus;
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单详情响应DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderV2DetailResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员ID
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序openId
|
||||||
|
*/
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸ID
|
||||||
|
*/
|
||||||
|
private Long faceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始金额
|
||||||
|
*/
|
||||||
|
private BigDecimal originalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠金额
|
||||||
|
*/
|
||||||
|
private BigDecimal discountAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最终金额
|
||||||
|
*/
|
||||||
|
private BigDecimal finalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态
|
||||||
|
*/
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态描述
|
||||||
|
*/
|
||||||
|
private String orderStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态
|
||||||
|
*/
|
||||||
|
private PaymentStatus paymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态描述
|
||||||
|
*/
|
||||||
|
private String paymentStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态
|
||||||
|
*/
|
||||||
|
private RefundStatus refundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态描述
|
||||||
|
*/
|
||||||
|
private String refundStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal totalRefundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注
|
||||||
|
*/
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付时间
|
||||||
|
*/
|
||||||
|
private Date payTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成时间
|
||||||
|
*/
|
||||||
|
private Date completeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单商品明细列表
|
||||||
|
*/
|
||||||
|
private List<OrderItemV2> orderItems;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单优惠记录列表
|
||||||
|
*/
|
||||||
|
private List<OrderDiscountV2> orderDiscounts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单退款记录列表
|
||||||
|
*/
|
||||||
|
private List<OrderRefundV2> orderRefunds;
|
||||||
|
}
|
131
src/main/java/com/ycwl/basic/order/dto/OrderV2ListResponse.java
Normal file
131
src/main/java/com/ycwl/basic/order/dto/OrderV2ListResponse.java
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
package com.ycwl.basic.order.dto;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.enums.OrderStatus;
|
||||||
|
import com.ycwl.basic.order.enums.PaymentStatus;
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单列表响应DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderV2ListResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员ID
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序openId
|
||||||
|
*/
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸ID
|
||||||
|
*/
|
||||||
|
private Long faceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始金额
|
||||||
|
*/
|
||||||
|
private BigDecimal originalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠金额
|
||||||
|
*/
|
||||||
|
private BigDecimal discountAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最终金额
|
||||||
|
*/
|
||||||
|
private BigDecimal finalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态
|
||||||
|
*/
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态描述
|
||||||
|
*/
|
||||||
|
private String orderStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态
|
||||||
|
*/
|
||||||
|
private PaymentStatus paymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态描述
|
||||||
|
*/
|
||||||
|
private String paymentStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态
|
||||||
|
*/
|
||||||
|
private RefundStatus refundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态描述
|
||||||
|
*/
|
||||||
|
private String refundStatusDesc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal totalRefundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注
|
||||||
|
*/
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付时间
|
||||||
|
*/
|
||||||
|
private Date payTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成时间
|
||||||
|
*/
|
||||||
|
private Date completeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品数量(订单中商品种类数)
|
||||||
|
*/
|
||||||
|
private Integer itemCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品总数量(所有商品数量之和)
|
||||||
|
*/
|
||||||
|
private Integer totalQuantity;
|
||||||
|
}
|
@@ -0,0 +1,72 @@
|
|||||||
|
package com.ycwl.basic.order.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单分页查询请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderV2PageRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页码(从1开始)
|
||||||
|
*/
|
||||||
|
private Integer pageNum = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每页大小
|
||||||
|
*/
|
||||||
|
private Integer pageSize = 10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户ID(移动端查询时自动设置)
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态
|
||||||
|
*/
|
||||||
|
private String orderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态
|
||||||
|
*/
|
||||||
|
private String paymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态
|
||||||
|
*/
|
||||||
|
private String refundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始创建时间
|
||||||
|
*/
|
||||||
|
private Date createTimeStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束创建时间
|
||||||
|
*/
|
||||||
|
private Date createTimeEnd;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始支付时间
|
||||||
|
*/
|
||||||
|
private Date payTimeStart;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束支付时间
|
||||||
|
*/
|
||||||
|
private Date payTimeEnd;
|
||||||
|
}
|
52
src/main/java/com/ycwl/basic/order/dto/RefundRequest.java
Normal file
52
src/main/java/com/ycwl/basic/order/dto/RefundRequest.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package com.ycwl.basic.order.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款申请请求DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RefundRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款类型
|
||||||
|
*/
|
||||||
|
private String refundType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款手续费
|
||||||
|
*/
|
||||||
|
private BigDecimal refundFee = BigDecimal.ZERO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款原因
|
||||||
|
*/
|
||||||
|
private String refundReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款详细说明
|
||||||
|
*/
|
||||||
|
private String refundDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作备注
|
||||||
|
*/
|
||||||
|
private String operatorRemarks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款渠道
|
||||||
|
*/
|
||||||
|
private String refundChannel = "ORIGINAL";
|
||||||
|
}
|
@@ -0,0 +1,91 @@
|
|||||||
|
package com.ycwl.basic.order.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.ycwl.basic.order.enums.DiscountType;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单优惠记录表实体V2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("order_discount_v2")
|
||||||
|
public class OrderDiscountV2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
@TableField("order_id")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠类型
|
||||||
|
*/
|
||||||
|
@TableField("discount_type")
|
||||||
|
private DiscountType discountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠名称
|
||||||
|
*/
|
||||||
|
@TableField("discount_name")
|
||||||
|
private String discountName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠金额
|
||||||
|
*/
|
||||||
|
@TableField("discount_amount")
|
||||||
|
private BigDecimal discountAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠比例
|
||||||
|
*/
|
||||||
|
@TableField("discount_rate")
|
||||||
|
private BigDecimal discountRate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示顺序
|
||||||
|
*/
|
||||||
|
@TableField("sort_order")
|
||||||
|
private Integer sortOrder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券ID
|
||||||
|
*/
|
||||||
|
@TableField("coupon_id")
|
||||||
|
private Long couponId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券码
|
||||||
|
*/
|
||||||
|
@TableField("coupon_code")
|
||||||
|
private String couponCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 券码
|
||||||
|
*/
|
||||||
|
@TableField("voucher_code")
|
||||||
|
private String voucherCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 券码批次ID
|
||||||
|
*/
|
||||||
|
@TableField("voucher_batch_id")
|
||||||
|
private Long voucherBatchId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
private Date createTime;
|
||||||
|
}
|
84
src/main/java/com/ycwl/basic/order/entity/OrderItemV2.java
Normal file
84
src/main/java/com/ycwl/basic/order/entity/OrderItemV2.java
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
package com.ycwl.basic.order.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单商品明细表实体V2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("order_item_v2")
|
||||||
|
public class OrderItemV2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
@TableField("order_id")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品类型
|
||||||
|
*/
|
||||||
|
@TableField("product_type")
|
||||||
|
private String productType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品ID
|
||||||
|
*/
|
||||||
|
@TableField("product_id")
|
||||||
|
private String productId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品名称
|
||||||
|
*/
|
||||||
|
@TableField("product_name")
|
||||||
|
private String productName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品数量
|
||||||
|
*/
|
||||||
|
@TableField("quantity")
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单价
|
||||||
|
*/
|
||||||
|
@TableField("unit_price")
|
||||||
|
private BigDecimal unitPrice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始小计
|
||||||
|
*/
|
||||||
|
@TableField("original_amount")
|
||||||
|
private BigDecimal originalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最终小计
|
||||||
|
*/
|
||||||
|
@TableField("final_amount")
|
||||||
|
private BigDecimal finalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_time")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
146
src/main/java/com/ycwl/basic/order/entity/OrderRefundV2.java
Normal file
146
src/main/java/com/ycwl/basic/order/entity/OrderRefundV2.java
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
package com.ycwl.basic.order.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import com.ycwl.basic.order.enums.RefundType;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单退款记录表实体V2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("order_refund_v2")
|
||||||
|
public class OrderRefundV2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
@TableField("order_id")
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款单号
|
||||||
|
*/
|
||||||
|
@TableField("refund_no")
|
||||||
|
private String refundNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款类型
|
||||||
|
*/
|
||||||
|
@TableField("refund_type")
|
||||||
|
private RefundType refundType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
@TableField("refund_amount")
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款手续费
|
||||||
|
*/
|
||||||
|
@TableField("refund_fee")
|
||||||
|
private BigDecimal refundFee;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态
|
||||||
|
*/
|
||||||
|
@TableField("refund_status")
|
||||||
|
private RefundStatus refundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款原因
|
||||||
|
*/
|
||||||
|
@TableField("refund_reason")
|
||||||
|
private String refundReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款详细说明
|
||||||
|
*/
|
||||||
|
@TableField("refund_description")
|
||||||
|
private String refundDescription;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请人ID
|
||||||
|
*/
|
||||||
|
@TableField("apply_by")
|
||||||
|
private Long applyBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批人ID
|
||||||
|
*/
|
||||||
|
@TableField("approve_by")
|
||||||
|
private Long approveBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作备注
|
||||||
|
*/
|
||||||
|
@TableField("operator_remarks")
|
||||||
|
private String operatorRemarks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付平台退款单号
|
||||||
|
*/
|
||||||
|
@TableField("payment_refund_id")
|
||||||
|
private String paymentRefundId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款渠道
|
||||||
|
*/
|
||||||
|
@TableField("refund_channel")
|
||||||
|
private String refundChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 申请时间
|
||||||
|
*/
|
||||||
|
@TableField("apply_time")
|
||||||
|
private Date applyTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 审批时间
|
||||||
|
*/
|
||||||
|
@TableField("approve_time")
|
||||||
|
private Date approveTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成时间
|
||||||
|
*/
|
||||||
|
@TableField("complete_time")
|
||||||
|
private Date completeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_time")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@TableField("create_by")
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@TableField("update_by")
|
||||||
|
private Long updateBy;
|
||||||
|
}
|
153
src/main/java/com/ycwl/basic/order/entity/OrderV2.java
Normal file
153
src/main/java/com/ycwl/basic/order/entity/OrderV2.java
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package com.ycwl.basic.order.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.ycwl.basic.order.enums.OrderStatus;
|
||||||
|
import com.ycwl.basic.order.enums.PaymentStatus;
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单主表实体V2
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@TableName("order_v2")
|
||||||
|
public class OrderV2 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键ID
|
||||||
|
*/
|
||||||
|
@TableId(value = "id", type = IdType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
@TableField("order_no")
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员ID
|
||||||
|
*/
|
||||||
|
@TableField("member_id")
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 小程序openId
|
||||||
|
*/
|
||||||
|
@TableField("open_id")
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸ID
|
||||||
|
*/
|
||||||
|
@TableField("face_id")
|
||||||
|
private Long faceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
@TableField("scenic_id")
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原始金额
|
||||||
|
*/
|
||||||
|
@TableField("original_amount")
|
||||||
|
private BigDecimal originalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠金额
|
||||||
|
*/
|
||||||
|
@TableField("discount_amount")
|
||||||
|
private BigDecimal discountAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最终金额
|
||||||
|
*/
|
||||||
|
@TableField("final_amount")
|
||||||
|
private BigDecimal finalAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态
|
||||||
|
*/
|
||||||
|
@TableField("order_status")
|
||||||
|
private OrderStatus orderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态
|
||||||
|
*/
|
||||||
|
@TableField("payment_status")
|
||||||
|
private PaymentStatus paymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态
|
||||||
|
*/
|
||||||
|
@TableField("refund_status")
|
||||||
|
private RefundStatus refundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总退款金额
|
||||||
|
*/
|
||||||
|
@TableField("total_refund_amount")
|
||||||
|
private BigDecimal totalRefundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单备注
|
||||||
|
*/
|
||||||
|
@TableField("remarks")
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付时间
|
||||||
|
*/
|
||||||
|
@TableField("pay_time")
|
||||||
|
private Date payTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成时间
|
||||||
|
*/
|
||||||
|
@TableField("complete_time")
|
||||||
|
private Date completeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@TableField("create_time")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@TableField("update_time")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建人
|
||||||
|
*/
|
||||||
|
@TableField("create_by")
|
||||||
|
private Long createBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新人
|
||||||
|
*/
|
||||||
|
@TableField("update_by")
|
||||||
|
private Long updateBy;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否删除
|
||||||
|
*/
|
||||||
|
@TableField("deleted")
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除时间
|
||||||
|
*/
|
||||||
|
@TableField("deleted_at")
|
||||||
|
private Date deletedAt;
|
||||||
|
}
|
60
src/main/java/com/ycwl/basic/order/enums/DiscountType.java
Normal file
60
src/main/java/com/ycwl/basic/order/enums/DiscountType.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ycwl.basic.order.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠类型枚举
|
||||||
|
*/
|
||||||
|
public enum DiscountType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠券
|
||||||
|
*/
|
||||||
|
COUPON("COUPON", "优惠券"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 券码
|
||||||
|
*/
|
||||||
|
VOUCHER("VOUCHER", "券码"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限时立减
|
||||||
|
*/
|
||||||
|
FLASH_SALE("FLASH_SALE", "限时立减"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 套餐优惠
|
||||||
|
*/
|
||||||
|
BUNDLE("BUNDLE", "套餐优惠"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一口价优惠
|
||||||
|
*/
|
||||||
|
FIXED_PRICE("FIXED_PRICE", "一口价优惠");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
DiscountType(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static DiscountType fromCode(String code) {
|
||||||
|
for (DiscountType type : values()) {
|
||||||
|
if (type.code.equals(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown DiscountType code: " + code);
|
||||||
|
}
|
||||||
|
}
|
70
src/main/java/com/ycwl/basic/order/enums/OrderStatus.java
Normal file
70
src/main/java/com/ycwl/basic/order/enums/OrderStatus.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package com.ycwl.basic.order.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态枚举
|
||||||
|
*/
|
||||||
|
public enum OrderStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 待支付
|
||||||
|
*/
|
||||||
|
PENDING_PAYMENT("PENDING_PAYMENT", "待支付"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已支付
|
||||||
|
*/
|
||||||
|
PAID("PAID", "已支付"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理中
|
||||||
|
*/
|
||||||
|
PROCESSING("PROCESSING", "处理中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已完成
|
||||||
|
*/
|
||||||
|
COMPLETED("COMPLETED", "已完成"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已取消
|
||||||
|
*/
|
||||||
|
CANCELLED("CANCELLED", "已取消"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款中
|
||||||
|
*/
|
||||||
|
REFUNDING("REFUNDING", "退款中"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已退款
|
||||||
|
*/
|
||||||
|
REFUNDED("REFUNDED", "已退款");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
OrderStatus(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static OrderStatus fromCode(String code) {
|
||||||
|
for (OrderStatus status : values()) {
|
||||||
|
if (status.code.equals(code)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown OrderStatus code: " + code);
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/com/ycwl/basic/order/enums/PaymentStatus.java
Normal file
50
src/main/java/com/ycwl/basic/order/enums/PaymentStatus.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package com.ycwl.basic.order.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态枚举
|
||||||
|
*/
|
||||||
|
public enum PaymentStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 未支付
|
||||||
|
*/
|
||||||
|
UNPAID("UNPAID", "未支付"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已支付
|
||||||
|
*/
|
||||||
|
PAID("PAID", "已支付"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已退款
|
||||||
|
*/
|
||||||
|
REFUNDED("REFUNDED", "已退款");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
PaymentStatus(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static PaymentStatus fromCode(String code) {
|
||||||
|
for (PaymentStatus status : values()) {
|
||||||
|
if (status.code.equals(code)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown PaymentStatus code: " + code);
|
||||||
|
}
|
||||||
|
}
|
55
src/main/java/com/ycwl/basic/order/enums/RefundStatus.java
Normal file
55
src/main/java/com/ycwl/basic/order/enums/RefundStatus.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package com.ycwl.basic.order.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态枚举
|
||||||
|
*/
|
||||||
|
public enum RefundStatus {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 无退款
|
||||||
|
*/
|
||||||
|
NO_REFUND("NO_REFUND", "无退款"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部分退款
|
||||||
|
*/
|
||||||
|
PARTIAL_REFUND("PARTIAL_REFUND", "部分退款"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全额退款
|
||||||
|
*/
|
||||||
|
FULL_REFUND("FULL_REFUND", "全额退款"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款处理中
|
||||||
|
*/
|
||||||
|
REFUND_PROCESSING("REFUND_PROCESSING", "退款处理中");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
RefundStatus(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static RefundStatus fromCode(String code) {
|
||||||
|
for (RefundStatus status : values()) {
|
||||||
|
if (status.code.equals(code)) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown RefundStatus code: " + code);
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/com/ycwl/basic/order/enums/RefundType.java
Normal file
50
src/main/java/com/ycwl/basic/order/enums/RefundType.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package com.ycwl.basic.order.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款类型枚举
|
||||||
|
*/
|
||||||
|
public enum RefundType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全额退款
|
||||||
|
*/
|
||||||
|
FULL_REFUND("FULL_REFUND", "全额退款"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 部分退款
|
||||||
|
*/
|
||||||
|
PARTIAL_REFUND("PARTIAL_REFUND", "部分退款"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品退款
|
||||||
|
*/
|
||||||
|
ITEM_REFUND("ITEM_REFUND", "商品退款");
|
||||||
|
|
||||||
|
private final String code;
|
||||||
|
private final String description;
|
||||||
|
|
||||||
|
RefundType(String code, String description) {
|
||||||
|
this.code = code;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCode() {
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据code获取枚举
|
||||||
|
*/
|
||||||
|
public static RefundType fromCode(String code) {
|
||||||
|
for (RefundType type : values()) {
|
||||||
|
if (type.code.equals(code)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown RefundType code: " + code);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,28 @@
|
|||||||
|
package com.ycwl.basic.order.event;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单事件监听器接口
|
||||||
|
*/
|
||||||
|
public interface OrderEventListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 支付状态变更事件
|
||||||
|
*/
|
||||||
|
void onPaymentStatusChanged(PaymentStatusChangeEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 退款状态变更事件
|
||||||
|
*/
|
||||||
|
void onRefundStatusChanged(RefundStatusChangeEvent event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 订单状态变更事件
|
||||||
|
*/
|
||||||
|
void onOrderStatusChanged(OrderStatusChangeEvent event);
|
||||||
|
}
|
125
src/main/java/com/ycwl/basic/order/event/OrderEventManager.java
Normal file
125
src/main/java/com/ycwl/basic/order/event/OrderEventManager.java
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
package com.ycwl.basic.order.event;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单事件管理器
|
||||||
|
* 管理事件监听器的注册和事件分发
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class OrderEventManager {
|
||||||
|
|
||||||
|
private final List<OrderEventListener> listeners = new ArrayList<>();
|
||||||
|
private final Executor eventExecutor = Executors.newFixedThreadPool(5,
|
||||||
|
r -> new Thread(r, "order-event-thread"));
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
log.info("订单事件管理器初始化完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册事件监听器
|
||||||
|
*
|
||||||
|
* @param listener 监听器实例
|
||||||
|
*/
|
||||||
|
public void registerListener(OrderEventListener listener) {
|
||||||
|
if (listener != null && !listeners.contains(listener)) {
|
||||||
|
listeners.add(listener);
|
||||||
|
log.info("注册订单事件监听器: {}", listener.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除事件监听器
|
||||||
|
*
|
||||||
|
* @param listener 监听器实例
|
||||||
|
*/
|
||||||
|
public void removeListener(OrderEventListener listener) {
|
||||||
|
if (listeners.remove(listener)) {
|
||||||
|
log.info("移除订单事件监听器: {}", listener.getClass().getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布支付状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 支付状态变更事件
|
||||||
|
*/
|
||||||
|
public void publishPaymentStatusChangeEvent(PaymentStatusChangeEvent event) {
|
||||||
|
log.info("发布支付状态变更事件: orderId={}, {} -> {}",
|
||||||
|
event.getOrderId(), event.getOldPaymentStatus(), event.getNewPaymentStatus());
|
||||||
|
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
for (OrderEventListener listener : listeners) {
|
||||||
|
try {
|
||||||
|
listener.onPaymentStatusChanged(event);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理支付状态变更事件失败: listener={}, orderId={}",
|
||||||
|
listener.getClass().getSimpleName(), event.getOrderId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, eventExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布退款状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 退款状态变更事件
|
||||||
|
*/
|
||||||
|
public void publishRefundStatusChangeEvent(RefundStatusChangeEvent event) {
|
||||||
|
log.info("发布退款状态变更事件: orderId={}, refundId={}, {} -> {}",
|
||||||
|
event.getOrderId(), event.getRefundId(),
|
||||||
|
event.getOldRefundStatus(), event.getNewRefundStatus());
|
||||||
|
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
for (OrderEventListener listener : listeners) {
|
||||||
|
try {
|
||||||
|
listener.onRefundStatusChanged(event);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理退款状态变更事件失败: listener={}, orderId={}, refundId={}",
|
||||||
|
listener.getClass().getSimpleName(), event.getOrderId(), event.getRefundId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, eventExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布订单状态变更事件
|
||||||
|
*
|
||||||
|
* @param event 订单状态变更事件
|
||||||
|
*/
|
||||||
|
public void publishOrderStatusChangeEvent(OrderStatusChangeEvent event) {
|
||||||
|
log.info("发布订单状态变更事件: orderId={}, {} -> {}",
|
||||||
|
event.getOrderId(), event.getOldOrderStatus(), event.getNewOrderStatus());
|
||||||
|
|
||||||
|
CompletableFuture.runAsync(() -> {
|
||||||
|
for (OrderEventListener listener : listeners) {
|
||||||
|
try {
|
||||||
|
listener.onOrderStatusChanged(event);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("处理订单状态变更事件失败: listener={}, orderId={}",
|
||||||
|
listener.getClass().getSimpleName(), event.getOrderId(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, eventExecutor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取已注册的监听器数量
|
||||||
|
*
|
||||||
|
* @return 监听器数量
|
||||||
|
*/
|
||||||
|
public int getListenerCount() {
|
||||||
|
return listeners.size();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ycwl.basic.order.event;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.enums.OrderStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单状态变更事件
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderStatusChangeEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旧的订单状态
|
||||||
|
*/
|
||||||
|
private OrderStatus oldOrderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新的订单状态
|
||||||
|
*/
|
||||||
|
private OrderStatus newOrderStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更时间
|
||||||
|
*/
|
||||||
|
private Date changeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更原因
|
||||||
|
*/
|
||||||
|
private String changeReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人ID
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
public OrderStatusChangeEvent(Long orderId, String orderNo,
|
||||||
|
OrderStatus oldStatus, OrderStatus newStatus,
|
||||||
|
String changeReason, Long operatorId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.orderNo = orderNo;
|
||||||
|
this.oldOrderStatus = oldStatus;
|
||||||
|
this.newOrderStatus = newStatus;
|
||||||
|
this.changeReason = changeReason;
|
||||||
|
this.operatorId = operatorId;
|
||||||
|
this.changeTime = new Date();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ycwl.basic.order.event;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.enums.PaymentStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态变更事件
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PaymentStatusChangeEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旧的支付状态
|
||||||
|
*/
|
||||||
|
private PaymentStatus oldPaymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新的支付状态
|
||||||
|
*/
|
||||||
|
private PaymentStatus newPaymentStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更时间
|
||||||
|
*/
|
||||||
|
private Date changeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更原因
|
||||||
|
*/
|
||||||
|
private String changeReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人ID
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
public PaymentStatusChangeEvent(Long orderId, String orderNo,
|
||||||
|
PaymentStatus oldStatus, PaymentStatus newStatus,
|
||||||
|
String changeReason, Long operatorId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.orderNo = orderNo;
|
||||||
|
this.oldPaymentStatus = oldStatus;
|
||||||
|
this.newPaymentStatus = newStatus;
|
||||||
|
this.changeReason = changeReason;
|
||||||
|
this.operatorId = operatorId;
|
||||||
|
this.changeTime = new Date();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,79 @@
|
|||||||
|
package com.ycwl.basic.order.event;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款状态变更事件
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RefundStatusChangeEvent {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单ID
|
||||||
|
*/
|
||||||
|
private Long orderId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单号
|
||||||
|
*/
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款记录ID
|
||||||
|
*/
|
||||||
|
private Long refundId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款单号
|
||||||
|
*/
|
||||||
|
private String refundNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旧的退款状态
|
||||||
|
*/
|
||||||
|
private RefundStatus oldRefundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新的退款状态
|
||||||
|
*/
|
||||||
|
private RefundStatus newRefundStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退款金额
|
||||||
|
*/
|
||||||
|
private BigDecimal refundAmount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更时间
|
||||||
|
*/
|
||||||
|
private Date changeTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更原因
|
||||||
|
*/
|
||||||
|
private String changeReason;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作人ID
|
||||||
|
*/
|
||||||
|
private Long operatorId;
|
||||||
|
|
||||||
|
public RefundStatusChangeEvent(Long orderId, String orderNo, Long refundId, String refundNo,
|
||||||
|
RefundStatus oldStatus, RefundStatus newStatus,
|
||||||
|
BigDecimal refundAmount, String changeReason, Long operatorId) {
|
||||||
|
this.orderId = orderId;
|
||||||
|
this.orderNo = orderNo;
|
||||||
|
this.refundId = refundId;
|
||||||
|
this.refundNo = refundNo;
|
||||||
|
this.oldRefundStatus = oldStatus;
|
||||||
|
this.newRefundStatus = newStatus;
|
||||||
|
this.refundAmount = refundAmount;
|
||||||
|
this.changeReason = changeReason;
|
||||||
|
this.operatorId = operatorId;
|
||||||
|
this.changeTime = new Date();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,120 @@
|
|||||||
|
package com.ycwl.basic.order.event.impl;
|
||||||
|
|
||||||
|
import com.ycwl.basic.order.event.*;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付状态变更监听器示例
|
||||||
|
* 应用启动后自动注册到事件管理器
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class PaymentStatusChangeListener implements OrderEventListener {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderEventManager orderEventManager;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
// 应用启动后自动注册到事件管理器
|
||||||
|
orderEventManager.registerListener(this);
|
||||||
|
log.info("支付状态变更监听器注册完成");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPaymentStatusChanged(PaymentStatusChangeEvent event) {
|
||||||
|
log.info("处理支付状态变更事件: orderId={}, orderNo={}, {} -> {}, reason={}",
|
||||||
|
event.getOrderId(), event.getOrderNo(),
|
||||||
|
event.getOldPaymentStatus(), event.getNewPaymentStatus(),
|
||||||
|
event.getChangeReason());
|
||||||
|
|
||||||
|
// 根据支付状态执行相应的业务逻辑
|
||||||
|
switch (event.getNewPaymentStatus()) {
|
||||||
|
case PAID:
|
||||||
|
handlePaymentSuccess(event);
|
||||||
|
break;
|
||||||
|
case REFUNDED:
|
||||||
|
handlePaymentRefunded(event);
|
||||||
|
break;
|
||||||
|
case UNPAID:
|
||||||
|
handlePaymentPending(event);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.warn("未处理的支付状态: {}", event.getNewPaymentStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRefundStatusChanged(RefundStatusChangeEvent event) {
|
||||||
|
log.info("处理退款状态变更事件: orderId={}, refundId={}, {} -> {}",
|
||||||
|
event.getOrderId(), event.getRefundId(),
|
||||||
|
event.getOldRefundStatus(), event.getNewRefundStatus());
|
||||||
|
|
||||||
|
// 可以在这里添加退款相关的业务逻辑
|
||||||
|
// 比如发送通知、更新库存等
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOrderStatusChanged(OrderStatusChangeEvent event) {
|
||||||
|
log.info("处理订单状态变更事件: orderId={}, {} -> {}",
|
||||||
|
event.getOrderId(), event.getOldOrderStatus(), event.getNewOrderStatus());
|
||||||
|
|
||||||
|
// 可以在这里添加订单状态相关的业务逻辑
|
||||||
|
// 比如发送用户通知、触发后续流程等
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理支付成功事件
|
||||||
|
*/
|
||||||
|
private void handlePaymentSuccess(PaymentStatusChangeEvent event) {
|
||||||
|
log.info("处理支付成功: orderId={}", event.getOrderId());
|
||||||
|
|
||||||
|
// 这里可以添加支付成功后的业务逻辑:
|
||||||
|
// 1. 发送支付成功通知
|
||||||
|
// 2. 更新商品库存
|
||||||
|
// 3. 生成相关凭证
|
||||||
|
// 4. 发送短信/邮件通知
|
||||||
|
// 5. 启动履约流程
|
||||||
|
|
||||||
|
// 示例:记录支付成功日志
|
||||||
|
log.info("订单支付成功处理完成: orderId={}, changeTime={}",
|
||||||
|
event.getOrderId(), event.getChangeTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理支付退款事件
|
||||||
|
*/
|
||||||
|
private void handlePaymentRefunded(PaymentStatusChangeEvent event) {
|
||||||
|
log.info("处理支付退款: orderId={}", event.getOrderId());
|
||||||
|
|
||||||
|
// 这里可以添加支付退款后的业务逻辑:
|
||||||
|
// 1. 恢复商品库存
|
||||||
|
// 2. 取消相关服务
|
||||||
|
// 3. 发送退款通知
|
||||||
|
// 4. 更新会员积分
|
||||||
|
|
||||||
|
// 示例:记录退款处理日志
|
||||||
|
log.info("订单退款处理完成: orderId={}, changeTime={}",
|
||||||
|
event.getOrderId(), event.getChangeTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理支付待处理事件
|
||||||
|
*/
|
||||||
|
private void handlePaymentPending(PaymentStatusChangeEvent event) {
|
||||||
|
log.info("处理支付待处理: orderId={}", event.getOrderId());
|
||||||
|
|
||||||
|
// 这里可以添加支付待处理的业务逻辑:
|
||||||
|
// 1. 设置支付超时提醒
|
||||||
|
// 2. 预留库存
|
||||||
|
// 3. 发送支付提醒
|
||||||
|
|
||||||
|
// 示例:记录待支付处理日志
|
||||||
|
log.info("订单待支付处理完成: orderId={}, changeTime={}",
|
||||||
|
event.getOrderId(), event.getChangeTime());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ycwl.basic.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ycwl.basic.order.entity.OrderDiscountV2;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单优惠记录表Mapper接口
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderDiscountMapper extends BaseMapper<OrderDiscountV2> {
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ycwl.basic.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ycwl.basic.order.entity.OrderItemV2;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单商品明细表Mapper接口
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderItemMapper extends BaseMapper<OrderItemV2> {
|
||||||
|
}
|
12
src/main/java/com/ycwl/basic/order/mapper/OrderMapper.java
Normal file
12
src/main/java/com/ycwl/basic/order/mapper/OrderMapper.java
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ycwl.basic.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ycwl.basic.order.entity.OrderV2;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单表Mapper接口
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderMapper extends BaseMapper<OrderV2> {
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
package com.ycwl.basic.order.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import com.ycwl.basic.order.entity.OrderRefundV2;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单退款记录表Mapper接口
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface OrderRefundMapper extends BaseMapper<OrderRefundV2> {
|
||||||
|
}
|
119
src/main/java/com/ycwl/basic/order/service/IOrderService.java
Normal file
119
src/main/java/com/ycwl/basic/order/service/IOrderService.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
package com.ycwl.basic.order.service;
|
||||||
|
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.ycwl.basic.dto.MobileOrderRequest;
|
||||||
|
import com.ycwl.basic.order.dto.*;
|
||||||
|
import com.ycwl.basic.order.entity.OrderV2;
|
||||||
|
import com.ycwl.basic.order.enums.RefundStatus;
|
||||||
|
import com.ycwl.basic.pricing.dto.PriceCalculationResult;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单服务接口
|
||||||
|
*/
|
||||||
|
public interface IOrderService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建订单
|
||||||
|
*
|
||||||
|
* @param request 移动端下单请求
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @param scenicId 景区ID
|
||||||
|
* @param priceResult 价格计算结果
|
||||||
|
* @return 订单ID
|
||||||
|
*/
|
||||||
|
Long createOrder(MobileOrderRequest request, Long userId, Long scenicId, PriceCalculationResult priceResult);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单号查询订单
|
||||||
|
*
|
||||||
|
* @param orderNo 订单号
|
||||||
|
* @return 订单信息
|
||||||
|
*/
|
||||||
|
OrderV2 getByOrderNo(String orderNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据订单ID查询订单
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 订单信息
|
||||||
|
*/
|
||||||
|
OrderV2 getById(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单状态
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @param orderStatus 订单状态
|
||||||
|
* @param paymentStatus 支付状态
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
boolean updateOrderStatus(Long orderId, String orderStatus, String paymentStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成订单号
|
||||||
|
*
|
||||||
|
* @return 订单号
|
||||||
|
*/
|
||||||
|
String generateOrderNo();
|
||||||
|
|
||||||
|
// ====== 新增方法 ======
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分页查询订单列表
|
||||||
|
*
|
||||||
|
* @param request 分页查询请求
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
PageInfo<OrderV2ListResponse> pageOrders(OrderV2PageRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询订单详情(包含商品明细、优惠记录、退款记录)
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @return 订单详情
|
||||||
|
*/
|
||||||
|
OrderV2DetailResponse getOrderDetail(Long orderId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新订单备注
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @param remarks 备注内容
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
boolean updateOrderRemarks(Long orderId, String remarks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新支付状态
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @param paymentStatus 支付状态
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
boolean updatePaymentStatus(Long orderId, String paymentStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新退款状态
|
||||||
|
*
|
||||||
|
* @param orderId 订单ID
|
||||||
|
* @param refundStatus 退款状态
|
||||||
|
* @return 更新结果
|
||||||
|
*/
|
||||||
|
boolean updateRefundStatus(Long orderId, RefundStatus refundStatus);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建退款记录
|
||||||
|
*
|
||||||
|
* @param request 退款申请请求
|
||||||
|
* @return 退款记录ID
|
||||||
|
*/
|
||||||
|
Long createRefundRecord(RefundRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户ID分页查询订单列表(移动端使用)
|
||||||
|
*
|
||||||
|
* @param request 分页查询请求(已设置用户ID)
|
||||||
|
* @return 分页结果
|
||||||
|
*/
|
||||||
|
PageInfo<OrderV2ListResponse> pageOrdersByUser(OrderV2PageRequest request);
|
||||||
|
}
|
@@ -0,0 +1,530 @@
|
|||||||
|
package com.ycwl.basic.order.service.impl;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.github.pagehelper.PageInfo;
|
||||||
|
import com.ycwl.basic.dto.MobileOrderRequest;
|
||||||
|
import com.ycwl.basic.order.dto.*;
|
||||||
|
import com.ycwl.basic.order.entity.OrderDiscountV2;
|
||||||
|
import com.ycwl.basic.order.entity.OrderItemV2;
|
||||||
|
import com.ycwl.basic.order.entity.OrderRefundV2;
|
||||||
|
import com.ycwl.basic.order.entity.OrderV2;
|
||||||
|
import com.ycwl.basic.order.enums.*;
|
||||||
|
import com.ycwl.basic.order.mapper.OrderDiscountMapper;
|
||||||
|
import com.ycwl.basic.order.mapper.OrderItemMapper;
|
||||||
|
import com.ycwl.basic.order.mapper.OrderMapper;
|
||||||
|
import com.ycwl.basic.order.mapper.OrderRefundMapper;
|
||||||
|
import com.ycwl.basic.order.service.IOrderService;
|
||||||
|
import com.ycwl.basic.order.event.*;
|
||||||
|
import com.ycwl.basic.pricing.dto.DiscountDetail;
|
||||||
|
import com.ycwl.basic.pricing.dto.PriceCalculationResult;
|
||||||
|
import com.ycwl.basic.pricing.dto.ProductItem;
|
||||||
|
import com.ycwl.basic.pricing.dto.VoucherInfo;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 订单服务实现类
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class OrderServiceImpl implements IOrderService {
|
||||||
|
|
||||||
|
private final OrderMapper orderMapper;
|
||||||
|
private final OrderItemMapper orderItemMapper;
|
||||||
|
private final OrderDiscountMapper orderDiscountMapper;
|
||||||
|
private final OrderRefundMapper orderRefundMapper;
|
||||||
|
private final OrderEventManager orderEventManager;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Long createOrder(MobileOrderRequest request, Long userId, Long scenicId, PriceCalculationResult priceResult) {
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
// 1. 生成订单号
|
||||||
|
String orderNo = generateOrderNo();
|
||||||
|
|
||||||
|
// 2. 创建订单基础信息
|
||||||
|
OrderV2 order = new OrderV2();
|
||||||
|
order.setOrderNo(orderNo);
|
||||||
|
order.setMemberId(userId);
|
||||||
|
order.setOpenId(request.getFaceId().toString()); // 临时使用faceId,实际应传入openId
|
||||||
|
order.setFaceId(request.getFaceId());
|
||||||
|
order.setScenicId(scenicId);
|
||||||
|
|
||||||
|
order.setOriginalAmount(priceResult.getOriginalAmount());
|
||||||
|
order.setDiscountAmount(priceResult.getDiscountAmount());
|
||||||
|
order.setFinalAmount(priceResult.getFinalAmount());
|
||||||
|
|
||||||
|
order.setOrderStatus(OrderStatus.PENDING_PAYMENT);
|
||||||
|
order.setPaymentStatus(PaymentStatus.UNPAID);
|
||||||
|
order.setRefundStatus(RefundStatus.NO_REFUND);
|
||||||
|
order.setTotalRefundAmount(BigDecimal.ZERO);
|
||||||
|
|
||||||
|
order.setRemarks(request.getRemarks());
|
||||||
|
order.setCreateTime(now);
|
||||||
|
order.setUpdateTime(now);
|
||||||
|
order.setCreateBy(userId);
|
||||||
|
order.setUpdateBy(userId);
|
||||||
|
order.setDeleted(0);
|
||||||
|
|
||||||
|
// 保存订单
|
||||||
|
orderMapper.insert(order);
|
||||||
|
Long orderId = order.getId();
|
||||||
|
|
||||||
|
log.info("订单基础信息创建成功: orderId={}, orderNo={}", orderId, orderNo);
|
||||||
|
|
||||||
|
// 3. 保存订单商品明细
|
||||||
|
for (ProductItem product : request.getProducts()) {
|
||||||
|
OrderItemV2 orderItem = new OrderItemV2();
|
||||||
|
orderItem.setOrderId(orderId);
|
||||||
|
orderItem.setProductType(product.getProductType().name());
|
||||||
|
orderItem.setProductId(product.getProductId());
|
||||||
|
orderItem.setProductName(getProductName(product)); // 根据商品类型和ID获取商品名称
|
||||||
|
orderItem.setQuantity(product.getQuantity());
|
||||||
|
orderItem.setUnitPrice(product.getUnitPrice());
|
||||||
|
orderItem.setOriginalAmount(product.getOriginalPrice());
|
||||||
|
orderItem.setFinalAmount(product.getSubtotal());
|
||||||
|
orderItem.setCreateTime(now);
|
||||||
|
orderItem.setUpdateTime(now);
|
||||||
|
|
||||||
|
orderItemMapper.insert(orderItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("订单商品明细保存成功: orderId={}, itemCount={}", orderId, request.getProducts().size());
|
||||||
|
|
||||||
|
// 4. 记录使用的优惠券信息
|
||||||
|
if (priceResult.getUsedCoupon() != null) {
|
||||||
|
OrderDiscountV2 couponDiscount = new OrderDiscountV2();
|
||||||
|
couponDiscount.setOrderId(orderId);
|
||||||
|
couponDiscount.setDiscountType(DiscountType.COUPON);
|
||||||
|
couponDiscount.setDiscountName(priceResult.getUsedCoupon().getCouponName());
|
||||||
|
couponDiscount.setDiscountAmount(priceResult.getUsedCoupon().getActualDiscountAmount());
|
||||||
|
couponDiscount.setSortOrder(3); // 优惠券显示顺序
|
||||||
|
couponDiscount.setCouponId(priceResult.getUsedCoupon().getCouponId());
|
||||||
|
couponDiscount.setCreateTime(now);
|
||||||
|
|
||||||
|
orderDiscountMapper.insert(couponDiscount);
|
||||||
|
log.info("优惠券记录保存成功: orderId={}, couponId={}, discountAmount={}",
|
||||||
|
orderId, priceResult.getUsedCoupon().getCouponId(), priceResult.getUsedCoupon().getActualDiscountAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 记录使用的券码信息
|
||||||
|
if (priceResult.getUsedVoucher() != null) {
|
||||||
|
VoucherInfo voucherInfo = priceResult.getUsedVoucher();
|
||||||
|
OrderDiscountV2 voucherDiscount = new OrderDiscountV2();
|
||||||
|
voucherDiscount.setOrderId(orderId);
|
||||||
|
voucherDiscount.setDiscountType(DiscountType.VOUCHER);
|
||||||
|
voucherDiscount.setDiscountName(voucherInfo.getBatchName());
|
||||||
|
voucherDiscount.setDiscountAmount(voucherInfo.getActualDiscountAmount());
|
||||||
|
voucherDiscount.setSortOrder(1); // 券码显示顺序最高
|
||||||
|
voucherDiscount.setVoucherCode(voucherInfo.getVoucherCode());
|
||||||
|
voucherDiscount.setCreateTime(now);
|
||||||
|
|
||||||
|
orderDiscountMapper.insert(voucherDiscount);
|
||||||
|
log.info("券码记录保存成功: orderId={}, voucherCode={}, discountAmount={}",
|
||||||
|
orderId, voucherInfo.getVoucherCode(), voucherInfo.getActualDiscountAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 记录其他优惠信息(如限时立减等)
|
||||||
|
if (priceResult.getDiscountDetails() != null) {
|
||||||
|
for (DiscountDetail discount : priceResult.getDiscountDetails()) {
|
||||||
|
// 跳过已经记录的优惠券和券码
|
||||||
|
if ("VOUCHER".equals(discount.getDiscountType()) || "COUPON".equals(discount.getDiscountType())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrderDiscountV2 otherDiscount = new OrderDiscountV2();
|
||||||
|
otherDiscount.setOrderId(orderId);
|
||||||
|
otherDiscount.setDiscountType(DiscountType.fromCode(discount.getDiscountType()));
|
||||||
|
otherDiscount.setDiscountName(discount.getDiscountName());
|
||||||
|
otherDiscount.setDiscountAmount(discount.getDiscountAmount());
|
||||||
|
otherDiscount.setSortOrder(discount.getSortOrder());
|
||||||
|
otherDiscount.setCreateTime(now);
|
||||||
|
|
||||||
|
orderDiscountMapper.insert(otherDiscount);
|
||||||
|
log.info("其他优惠记录保存成功: orderId={}, type={}, discountAmount={}",
|
||||||
|
orderId, discount.getDiscountType(), discount.getDiscountAmount());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("订单创建完成: orderId={}, orderNo={}, finalAmount={}",
|
||||||
|
orderId, orderNo, priceResult.getFinalAmount());
|
||||||
|
|
||||||
|
return orderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrderV2 getByOrderNo(String orderNo) {
|
||||||
|
QueryWrapper<OrderV2> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("order_no", orderNo);
|
||||||
|
queryWrapper.eq("deleted", 0);
|
||||||
|
return orderMapper.selectOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrderV2 getById(Long orderId) {
|
||||||
|
return orderMapper.selectById(orderId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean updateOrderStatus(Long orderId, String orderStatus, String paymentStatus) {
|
||||||
|
OrderV2 order = new OrderV2();
|
||||||
|
order.setId(orderId);
|
||||||
|
order.setOrderStatus(OrderStatus.fromCode(orderStatus));
|
||||||
|
order.setPaymentStatus(PaymentStatus.fromCode(paymentStatus));
|
||||||
|
order.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
if ("PAID".equals(paymentStatus)) {
|
||||||
|
order.setPayTime(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ("COMPLETED".equals(orderStatus)) {
|
||||||
|
order.setCompleteTime(new Date());
|
||||||
|
}
|
||||||
|
|
||||||
|
return orderMapper.updateById(order) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String generateOrderNo() {
|
||||||
|
// 生成订单号:ORDER + 时间戳 + 3位随机数
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
String timestamp = sdf.format(new Date());
|
||||||
|
int random = (int) (Math.random() * 900) + 100;
|
||||||
|
return "ORDER" + timestamp + random;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据商品类型和ID获取商品名称
|
||||||
|
* TODO: 实际应该从商品配置表或其他数据源获取
|
||||||
|
*/
|
||||||
|
private String getProductName(ProductItem product) {
|
||||||
|
return product.getProductType().getDescription() + "-" + product.getProductId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== 新增方法实现 ======
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageInfo<OrderV2ListResponse> pageOrders(OrderV2PageRequest request) {
|
||||||
|
PageHelper.startPage(request.getPageNum(), request.getPageSize());
|
||||||
|
|
||||||
|
QueryWrapper<OrderV2> queryWrapper = buildOrderQueryWrapper(request);
|
||||||
|
List<OrderV2> orders = orderMapper.selectList(queryWrapper);
|
||||||
|
|
||||||
|
// 转换为响应DTO
|
||||||
|
List<OrderV2ListResponse> responseList = orders.stream()
|
||||||
|
.map(this::convertToListResponse)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return new PageInfo<>(responseList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrderV2DetailResponse getOrderDetail(Long orderId) {
|
||||||
|
// 查询订单基础信息
|
||||||
|
OrderV2 order = orderMapper.selectById(orderId);
|
||||||
|
if (order == null || order.getDeleted() == 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询订单商品明细
|
||||||
|
QueryWrapper<OrderItemV2> itemQuery = new QueryWrapper<>();
|
||||||
|
itemQuery.eq("order_id", orderId);
|
||||||
|
List<OrderItemV2> orderItems = orderItemMapper.selectList(itemQuery);
|
||||||
|
|
||||||
|
// 查询订单优惠记录
|
||||||
|
QueryWrapper<OrderDiscountV2> discountQuery = new QueryWrapper<>();
|
||||||
|
discountQuery.eq("order_id", orderId).orderByAsc("sort_order");
|
||||||
|
List<OrderDiscountV2> orderDiscounts = orderDiscountMapper.selectList(discountQuery);
|
||||||
|
|
||||||
|
// 查询订单退款记录
|
||||||
|
QueryWrapper<OrderRefundV2> refundQuery = new QueryWrapper<>();
|
||||||
|
refundQuery.eq("order_id", orderId).orderByDesc("create_time");
|
||||||
|
List<OrderRefundV2> orderRefunds = orderRefundMapper.selectList(refundQuery);
|
||||||
|
|
||||||
|
// 转换为响应DTO
|
||||||
|
return convertToDetailResponse(order, orderItems, orderDiscounts, orderRefunds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public boolean updateOrderRemarks(Long orderId, String remarks) {
|
||||||
|
OrderV2 order = new OrderV2();
|
||||||
|
order.setId(orderId);
|
||||||
|
order.setRemarks(remarks);
|
||||||
|
order.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
return orderMapper.updateById(order) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public boolean updatePaymentStatus(Long orderId, String paymentStatus) {
|
||||||
|
// 先查询当前订单状态
|
||||||
|
OrderV2 currentOrder = orderMapper.selectById(orderId);
|
||||||
|
if (currentOrder == null) {
|
||||||
|
log.warn("订单不存在: orderId={}", orderId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PaymentStatus oldPaymentStatus = currentOrder.getPaymentStatus();
|
||||||
|
PaymentStatus newPaymentStatus = PaymentStatus.fromCode(paymentStatus);
|
||||||
|
|
||||||
|
// 更新订单支付状态
|
||||||
|
OrderV2 order = new OrderV2();
|
||||||
|
order.setId(orderId);
|
||||||
|
order.setPaymentStatus(newPaymentStatus);
|
||||||
|
order.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
if ("PAID".equals(paymentStatus)) {
|
||||||
|
order.setPayTime(new Date());
|
||||||
|
// 支付完成后,订单状态也需要更新
|
||||||
|
order.setOrderStatus(OrderStatus.PAID);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = orderMapper.updateById(order) > 0;
|
||||||
|
|
||||||
|
// 发布支付状态变更事件
|
||||||
|
if (success && !oldPaymentStatus.equals(newPaymentStatus)) {
|
||||||
|
PaymentStatusChangeEvent event = new PaymentStatusChangeEvent(
|
||||||
|
orderId, currentOrder.getOrderNo(),
|
||||||
|
oldPaymentStatus, newPaymentStatus,
|
||||||
|
"支付状态更新", null
|
||||||
|
);
|
||||||
|
orderEventManager.publishPaymentStatusChangeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public boolean updateRefundStatus(Long orderId, RefundStatus refundStatus) {
|
||||||
|
// 先查询当前订单状态
|
||||||
|
OrderV2 currentOrder = orderMapper.selectById(orderId);
|
||||||
|
if (currentOrder == null) {
|
||||||
|
log.warn("订单不存在: orderId={}", orderId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefundStatus oldRefundStatus = currentOrder.getRefundStatus();
|
||||||
|
|
||||||
|
// 更新订单退款状态
|
||||||
|
OrderV2 order = new OrderV2();
|
||||||
|
order.setId(orderId);
|
||||||
|
order.setRefundStatus(refundStatus);
|
||||||
|
order.setUpdateTime(new Date());
|
||||||
|
|
||||||
|
// 根据退款状态更新订单状态
|
||||||
|
if (RefundStatus.FULL_REFUND.equals(refundStatus)) {
|
||||||
|
order.setOrderStatus(OrderStatus.REFUNDED);
|
||||||
|
} else if (RefundStatus.REFUND_PROCESSING.equals(refundStatus)) {
|
||||||
|
order.setOrderStatus(OrderStatus.REFUNDING);
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean success = orderMapper.updateById(order) > 0;
|
||||||
|
|
||||||
|
// 发布退款状态变更事件
|
||||||
|
if (success && !oldRefundStatus.equals(refundStatus)) {
|
||||||
|
RefundStatusChangeEvent event = new RefundStatusChangeEvent(
|
||||||
|
orderId, currentOrder.getOrderNo(), null, null,
|
||||||
|
oldRefundStatus, refundStatus, null,
|
||||||
|
"退款状态更新", null
|
||||||
|
);
|
||||||
|
orderEventManager.publishRefundStatusChangeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public Long createRefundRecord(RefundRequest request) {
|
||||||
|
Date now = new Date();
|
||||||
|
|
||||||
|
// 生成退款单号
|
||||||
|
String refundNo = generateRefundNo();
|
||||||
|
|
||||||
|
// 创建退款记录
|
||||||
|
OrderRefundV2 refund = new OrderRefundV2();
|
||||||
|
refund.setOrderId(request.getOrderId());
|
||||||
|
refund.setRefundNo(refundNo);
|
||||||
|
refund.setRefundType(RefundType.fromCode(request.getRefundType()));
|
||||||
|
refund.setRefundAmount(request.getRefundAmount());
|
||||||
|
refund.setRefundFee(request.getRefundFee());
|
||||||
|
refund.setRefundStatus(com.ycwl.basic.order.enums.RefundStatus.REFUND_PROCESSING);
|
||||||
|
refund.setRefundReason(request.getRefundReason());
|
||||||
|
refund.setRefundDescription(request.getRefundDescription());
|
||||||
|
refund.setOperatorRemarks(request.getOperatorRemarks());
|
||||||
|
refund.setRefundChannel(request.getRefundChannel());
|
||||||
|
refund.setApplyTime(now);
|
||||||
|
refund.setCreateTime(now);
|
||||||
|
refund.setUpdateTime(now);
|
||||||
|
|
||||||
|
orderRefundMapper.insert(refund);
|
||||||
|
|
||||||
|
// 更新订单退款状态
|
||||||
|
updateRefundStatus(request.getOrderId(), com.ycwl.basic.order.enums.RefundStatus.REFUND_PROCESSING);
|
||||||
|
|
||||||
|
log.info("退款记录创建成功: refundId={}, refundNo={}, orderId={}, refundAmount={}",
|
||||||
|
refund.getId(), refundNo, request.getOrderId(), request.getRefundAmount());
|
||||||
|
|
||||||
|
return refund.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageInfo<OrderV2ListResponse> pageOrdersByUser(OrderV2PageRequest request) {
|
||||||
|
// 移动端查询,确保只查询当前用户的订单
|
||||||
|
return pageOrders(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====== 私有辅助方法 ======
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建订单查询条件
|
||||||
|
*/
|
||||||
|
private QueryWrapper<OrderV2> buildOrderQueryWrapper(OrderV2PageRequest request) {
|
||||||
|
QueryWrapper<OrderV2> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("deleted", 0);
|
||||||
|
|
||||||
|
if (request.getOrderNo() != null && !request.getOrderNo().trim().isEmpty()) {
|
||||||
|
queryWrapper.like("order_no", request.getOrderNo().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getMemberId() != null) {
|
||||||
|
queryWrapper.eq("member_id", request.getMemberId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getScenicId() != null) {
|
||||||
|
queryWrapper.eq("scenic_id", request.getScenicId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getOrderStatus() != null && !request.getOrderStatus().trim().isEmpty()) {
|
||||||
|
queryWrapper.eq("order_status", request.getOrderStatus().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getPaymentStatus() != null && !request.getPaymentStatus().trim().isEmpty()) {
|
||||||
|
queryWrapper.eq("payment_status", request.getPaymentStatus().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getRefundStatus() != null && !request.getRefundStatus().trim().isEmpty()) {
|
||||||
|
queryWrapper.eq("refund_status", request.getRefundStatus().trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getCreateTimeStart() != null) {
|
||||||
|
queryWrapper.ge("create_time", request.getCreateTimeStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getCreateTimeEnd() != null) {
|
||||||
|
queryWrapper.le("create_time", request.getCreateTimeEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getPayTimeStart() != null) {
|
||||||
|
queryWrapper.ge("pay_time", request.getPayTimeStart());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getPayTimeEnd() != null) {
|
||||||
|
queryWrapper.le("pay_time", request.getPayTimeEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
queryWrapper.orderByDesc("create_time");
|
||||||
|
|
||||||
|
return queryWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为列表响应DTO
|
||||||
|
*/
|
||||||
|
private OrderV2ListResponse convertToListResponse(OrderV2 order) {
|
||||||
|
OrderV2ListResponse response = new OrderV2ListResponse();
|
||||||
|
response.setId(order.getId());
|
||||||
|
response.setOrderNo(order.getOrderNo());
|
||||||
|
response.setMemberId(order.getMemberId());
|
||||||
|
response.setOpenId(order.getOpenId());
|
||||||
|
response.setFaceId(order.getFaceId());
|
||||||
|
response.setScenicId(order.getScenicId());
|
||||||
|
response.setOriginalAmount(order.getOriginalAmount());
|
||||||
|
response.setDiscountAmount(order.getDiscountAmount());
|
||||||
|
response.setFinalAmount(order.getFinalAmount());
|
||||||
|
response.setOrderStatus(order.getOrderStatus());
|
||||||
|
response.setOrderStatusDesc(order.getOrderStatus().getDescription());
|
||||||
|
response.setPaymentStatus(order.getPaymentStatus());
|
||||||
|
response.setPaymentStatusDesc(order.getPaymentStatus().getDescription());
|
||||||
|
response.setRefundStatus(order.getRefundStatus());
|
||||||
|
response.setRefundStatusDesc(order.getRefundStatus().getDescription());
|
||||||
|
response.setTotalRefundAmount(order.getTotalRefundAmount());
|
||||||
|
response.setRemarks(order.getRemarks());
|
||||||
|
response.setPayTime(order.getPayTime());
|
||||||
|
response.setCompleteTime(order.getCompleteTime());
|
||||||
|
response.setCreateTime(order.getCreateTime());
|
||||||
|
response.setUpdateTime(order.getUpdateTime());
|
||||||
|
|
||||||
|
// 查询商品数量信息
|
||||||
|
QueryWrapper<OrderItemV2> itemQuery = new QueryWrapper<>();
|
||||||
|
itemQuery.eq("order_id", order.getId());
|
||||||
|
List<OrderItemV2> items = orderItemMapper.selectList(itemQuery);
|
||||||
|
response.setItemCount(items.size());
|
||||||
|
response.setTotalQuantity(items.stream().mapToInt(OrderItemV2::getQuantity).sum());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为详情响应DTO
|
||||||
|
*/
|
||||||
|
private OrderV2DetailResponse convertToDetailResponse(OrderV2 order,
|
||||||
|
List<OrderItemV2> orderItems,
|
||||||
|
List<OrderDiscountV2> orderDiscounts,
|
||||||
|
List<OrderRefundV2> orderRefunds) {
|
||||||
|
OrderV2DetailResponse response = new OrderV2DetailResponse();
|
||||||
|
response.setId(order.getId());
|
||||||
|
response.setOrderNo(order.getOrderNo());
|
||||||
|
response.setMemberId(order.getMemberId());
|
||||||
|
response.setOpenId(order.getOpenId());
|
||||||
|
response.setFaceId(order.getFaceId());
|
||||||
|
response.setScenicId(order.getScenicId());
|
||||||
|
response.setOriginalAmount(order.getOriginalAmount());
|
||||||
|
response.setDiscountAmount(order.getDiscountAmount());
|
||||||
|
response.setFinalAmount(order.getFinalAmount());
|
||||||
|
response.setOrderStatus(order.getOrderStatus());
|
||||||
|
response.setOrderStatusDesc(order.getOrderStatus().getDescription());
|
||||||
|
response.setPaymentStatus(order.getPaymentStatus());
|
||||||
|
response.setPaymentStatusDesc(order.getPaymentStatus().getDescription());
|
||||||
|
response.setRefundStatus(order.getRefundStatus());
|
||||||
|
response.setRefundStatusDesc(order.getRefundStatus().getDescription());
|
||||||
|
response.setTotalRefundAmount(order.getTotalRefundAmount());
|
||||||
|
response.setRemarks(order.getRemarks());
|
||||||
|
response.setPayTime(order.getPayTime());
|
||||||
|
response.setCompleteTime(order.getCompleteTime());
|
||||||
|
response.setCreateTime(order.getCreateTime());
|
||||||
|
response.setUpdateTime(order.getUpdateTime());
|
||||||
|
response.setCreateBy(order.getCreateBy());
|
||||||
|
response.setUpdateBy(order.getUpdateBy());
|
||||||
|
|
||||||
|
response.setOrderItems(orderItems);
|
||||||
|
response.setOrderDiscounts(orderDiscounts);
|
||||||
|
response.setOrderRefunds(orderRefunds);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成退款单号
|
||||||
|
*/
|
||||||
|
private String generateRefundNo() {
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||||
|
String timestamp = sdf.format(new Date());
|
||||||
|
int random = (int) (Math.random() * 900) + 100;
|
||||||
|
return "REFUND" + timestamp + random;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user