feat(shop): 优化订单处理逻辑并添加新功能
- 新增 DateTimeUtil 工具类,用于统一处理日期时间格式化- 移除 ShopCouponController 中的 PreAuthorize 注解 -重构 ShopOrderServiceImpl 中的支付成功后业务逻辑处理 - 添加处理支付成功后业务逻辑的 handlePaymentSuccess 方法 - 新增标记优惠券为已使用的 markCouponAsUsed 方法 - 新增累计商品销量的 updateGoodsSales 和 updateSingleGoodsSales 方法 - 更新测试账号配置和生产环境配置
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
package com.gxwebsoft.common.core.utils;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
/**
|
||||
* 时间格式化工具类
|
||||
* 用于统一处理LocalDateTime的格式化
|
||||
*
|
||||
* @author WebSoft
|
||||
* @since 2025-08-23
|
||||
*/
|
||||
public class DateTimeUtil {
|
||||
|
||||
/**
|
||||
* 默认的日期时间格式
|
||||
*/
|
||||
public static final String DEFAULT_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 默认的日期格式
|
||||
*/
|
||||
public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd";
|
||||
|
||||
/**
|
||||
* 默认的时间格式
|
||||
*/
|
||||
public static final String DEFAULT_TIME_PATTERN = "HH:mm:ss";
|
||||
|
||||
/**
|
||||
* 默认的日期时间格式化器
|
||||
*/
|
||||
private static final DateTimeFormatter DEFAULT_DATETIME_FORMATTER =
|
||||
DateTimeFormatter.ofPattern(DEFAULT_DATETIME_PATTERN);
|
||||
|
||||
/**
|
||||
* 格式化LocalDateTime为字符串
|
||||
* 使用默认格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateTime 要格式化的时间
|
||||
* @return 格式化后的字符串,如果输入为null则返回null
|
||||
*/
|
||||
public static String formatDateTime(LocalDateTime dateTime) {
|
||||
if (dateTime == null) {
|
||||
return null;
|
||||
}
|
||||
return dateTime.format(DEFAULT_DATETIME_FORMATTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化LocalDateTime为字符串
|
||||
* 使用指定格式
|
||||
*
|
||||
* @param dateTime 要格式化的时间
|
||||
* @param pattern 格式模式
|
||||
* @return 格式化后的字符串,如果输入为null则返回null
|
||||
*/
|
||||
public static String formatDateTime(LocalDateTime dateTime, String pattern) {
|
||||
if (dateTime == null) {
|
||||
return null;
|
||||
}
|
||||
return dateTime.format(DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串为LocalDateTime
|
||||
* 使用默认格式:yyyy-MM-dd HH:mm:ss
|
||||
*
|
||||
* @param dateTimeStr 时间字符串
|
||||
* @return LocalDateTime对象,如果输入为null或空字符串则返回null
|
||||
*/
|
||||
public static LocalDateTime parseDateTime(String dateTimeStr) {
|
||||
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return LocalDateTime.parse(dateTimeStr, DEFAULT_DATETIME_FORMATTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串为LocalDateTime
|
||||
* 使用指定格式
|
||||
*
|
||||
* @param dateTimeStr 时间字符串
|
||||
* @param pattern 格式模式
|
||||
* @return LocalDateTime对象,如果输入为null或空字符串则返回null
|
||||
*/
|
||||
public static LocalDateTime parseDateTime(String dateTimeStr, String pattern) {
|
||||
if (dateTimeStr == null || dateTimeStr.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
return LocalDateTime.parse(dateTimeStr, DateTimeFormatter.ofPattern(pattern));
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,6 @@ public class ShopCouponController extends BaseController {
|
||||
}
|
||||
|
||||
|
||||
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
|
||||
@Operation(summary = "分页查询优惠券")
|
||||
@GetMapping("/page")
|
||||
public ApiResult<PageResult<ShopCoupon>> page(ShopCouponParam param) {
|
||||
@@ -100,7 +99,6 @@ public class ShopCouponController extends BaseController {
|
||||
return success(shopCouponService.pageRel(param));
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
|
||||
@Operation(summary = "查询全部优惠券")
|
||||
@GetMapping()
|
||||
public ApiResult<List<ShopCoupon>> list(ShopCouponParam param) {
|
||||
@@ -108,7 +106,6 @@ public class ShopCouponController extends BaseController {
|
||||
return success(shopCouponService.listRel(param));
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
|
||||
@Operation(summary = "根据id查询优惠券")
|
||||
@GetMapping("/{id}")
|
||||
public ApiResult<ShopCoupon> get(@PathVariable("id") Integer id) {
|
||||
|
||||
@@ -298,8 +298,40 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
|
||||
@Override
|
||||
public void updateByOutTradeNo(ShopOrder order) {
|
||||
baseMapper.updateByOutTradeNo(order);
|
||||
// 使用优惠券 - 使用新的状态管理服务
|
||||
|
||||
// 处理支付成功后的业务逻辑
|
||||
handlePaymentSuccess(order);
|
||||
|
||||
if (order.getTenantId().equals(10550)) {
|
||||
shopOrderUpdate10550Service.update(order);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理支付成功后的业务逻辑
|
||||
*/
|
||||
private void handlePaymentSuccess(ShopOrder order) {
|
||||
try {
|
||||
// 1. 使用优惠券
|
||||
if (order.getCouponId() != null && order.getCouponId() > 0) {
|
||||
markCouponAsUsed(order);
|
||||
}
|
||||
|
||||
// 2. 累计商品销量
|
||||
updateGoodsSales(order);
|
||||
|
||||
log.info("支付成功后业务逻辑处理完成 - 订单号:{}", order.getOrderNo());
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付成功后业务逻辑失败 - 订单号:{}", order.getOrderNo(), e);
|
||||
// 不抛出异常,避免影响支付回调的成功响应
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记优惠券为已使用
|
||||
*/
|
||||
private void markCouponAsUsed(ShopOrder order) {
|
||||
try {
|
||||
// 注入 CouponStatusService 并使用其 useCoupon 方法
|
||||
// couponStatusService.useCoupon(order.getCouponId().longValue(), order.getOrderId(), order.getOrderNo());
|
||||
|
||||
@@ -308,10 +340,65 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
|
||||
if (coupon != null) {
|
||||
coupon.markAsUsed(order.getOrderId(), order.getOrderNo());
|
||||
shopUserCouponService.updateById(coupon);
|
||||
log.info("优惠券标记为已使用 - 优惠券ID:{},订单号:{}", order.getCouponId(), order.getOrderNo());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("标记优惠券为已使用失败 - 优惠券ID:{},订单号:{}", order.getCouponId(), order.getOrderNo(), e);
|
||||
}
|
||||
}
|
||||
if (order.getTenantId().equals(10550)) {
|
||||
shopOrderUpdate10550Service.update(order);
|
||||
|
||||
/**
|
||||
* 累计商品销量
|
||||
*/
|
||||
private void updateGoodsSales(ShopOrder order) {
|
||||
try {
|
||||
// 获取订单商品列表
|
||||
List<ShopOrderGoods> orderGoodsList = shopOrderGoodsService.list(
|
||||
new LambdaQueryWrapper<ShopOrderGoods>()
|
||||
.eq(ShopOrderGoods::getOrderId, order.getOrderId())
|
||||
);
|
||||
|
||||
if (orderGoodsList.isEmpty()) {
|
||||
log.warn("订单商品列表为空 - 订单号:{}", order.getOrderNo());
|
||||
return;
|
||||
}
|
||||
|
||||
// 累计每个商品的销量
|
||||
for (ShopOrderGoods orderGoods : orderGoodsList) {
|
||||
updateSingleGoodsSales(orderGoods);
|
||||
}
|
||||
|
||||
log.info("商品销量累计完成 - 订单号:{},商品数量:{}", order.getOrderNo(), orderGoodsList.size());
|
||||
} catch (Exception e) {
|
||||
log.error("累计商品销量失败 - 订单号:{}", order.getOrderNo(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 累计单个商品的销量
|
||||
*/
|
||||
private void updateSingleGoodsSales(ShopOrderGoods orderGoods) {
|
||||
try {
|
||||
ShopGoods goods = shopGoodsService.getById(orderGoods.getGoodsId());
|
||||
if (goods != null) {
|
||||
// 累计商品销量
|
||||
Integer currentSales = goods.getSales() != null ? goods.getSales() : 0;
|
||||
Integer newSales = currentSales + orderGoods.getTotalNum();
|
||||
goods.setSales(newSales);
|
||||
|
||||
boolean updated = shopGoodsService.updateById(goods);
|
||||
if (updated) {
|
||||
log.info("商品销量累计成功 - 商品ID:{},商品名称:{},购买数量:{},累计销量:{} -> {}",
|
||||
orderGoods.getGoodsId(), orderGoods.getGoodsName(), orderGoods.getTotalNum(), currentSales, newSales);
|
||||
} else {
|
||||
log.warn("商品销量更新失败 - 商品ID:{}", orderGoods.getGoodsId());
|
||||
}
|
||||
} else {
|
||||
log.warn("商品不存在,无法累计销量 - 商品ID:{}", orderGoods.getGoodsId());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("累计单个商品销量失败 - 商品ID:{},商品名称:{}",
|
||||
orderGoods.getGoodsId(), orderGoods.getGoodsName(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: jdbc:mysql://8.134.169.209:13306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://1Panel-mysql-Bqdt:3306/modules?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
|
||||
username: modules
|
||||
password: 8YdLnk7KsPAyDXGA
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
@@ -14,8 +14,8 @@ spring:
|
||||
# redis
|
||||
redis:
|
||||
database: 0
|
||||
host: 8.134.169.209
|
||||
port: 16379
|
||||
host: 1Panel-redis-Q1LE
|
||||
port: 6379
|
||||
password: redis_WSDb88
|
||||
|
||||
# 日志配置
|
||||
|
||||
@@ -119,9 +119,9 @@ shop:
|
||||
order:
|
||||
# 测试账号配置
|
||||
test-account:
|
||||
enabled: false # 禁用测试账号功能
|
||||
enabled: true # 禁用测试账号功能
|
||||
phone-numbers:
|
||||
- "13800000000" # 改为其他测试手机号
|
||||
- "13737128880" # 改为其他测试手机号
|
||||
test-pay-amount: 0.01
|
||||
|
||||
# 租户特殊规则配置
|
||||
|
||||
Reference in New Issue
Block a user