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 = "分页查询优惠券")
|
@Operation(summary = "分页查询优惠券")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public ApiResult<PageResult<ShopCoupon>> page(ShopCouponParam param) {
|
public ApiResult<PageResult<ShopCoupon>> page(ShopCouponParam param) {
|
||||||
@@ -100,7 +99,6 @@ public class ShopCouponController extends BaseController {
|
|||||||
return success(shopCouponService.pageRel(param));
|
return success(shopCouponService.pageRel(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
|
|
||||||
@Operation(summary = "查询全部优惠券")
|
@Operation(summary = "查询全部优惠券")
|
||||||
@GetMapping()
|
@GetMapping()
|
||||||
public ApiResult<List<ShopCoupon>> list(ShopCouponParam param) {
|
public ApiResult<List<ShopCoupon>> list(ShopCouponParam param) {
|
||||||
@@ -108,7 +106,6 @@ public class ShopCouponController extends BaseController {
|
|||||||
return success(shopCouponService.listRel(param));
|
return success(shopCouponService.listRel(param));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("hasAuthority('shop:shopCoupon:list')")
|
|
||||||
@Operation(summary = "根据id查询优惠券")
|
@Operation(summary = "根据id查询优惠券")
|
||||||
@GetMapping("/{id}")
|
@GetMapping("/{id}")
|
||||||
public ApiResult<ShopCoupon> get(@PathVariable("id") Integer id) {
|
public ApiResult<ShopCoupon> get(@PathVariable("id") Integer id) {
|
||||||
|
|||||||
@@ -298,8 +298,40 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
|
|||||||
@Override
|
@Override
|
||||||
public void updateByOutTradeNo(ShopOrder order) {
|
public void updateByOutTradeNo(ShopOrder order) {
|
||||||
baseMapper.updateByOutTradeNo(order);
|
baseMapper.updateByOutTradeNo(order);
|
||||||
// 使用优惠券 - 使用新的状态管理服务
|
|
||||||
if (order.getCouponId() != null && order.getCouponId() > 0) {
|
// 处理支付成功后的业务逻辑
|
||||||
|
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 方法
|
||||||
// couponStatusService.useCoupon(order.getCouponId().longValue(), order.getOrderId(), order.getOrderNo());
|
// couponStatusService.useCoupon(order.getCouponId().longValue(), order.getOrderId(), order.getOrderNo());
|
||||||
|
|
||||||
@@ -308,10 +340,65 @@ public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderMapper, ShopOrder
|
|||||||
if (coupon != null) {
|
if (coupon != null) {
|
||||||
coupon.markAsUsed(order.getOrderId(), order.getOrderNo());
|
coupon.markAsUsed(order.getOrderId(), order.getOrderNo());
|
||||||
shopUserCouponService.updateById(coupon);
|
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:
|
spring:
|
||||||
datasource:
|
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
|
username: modules
|
||||||
password: 8YdLnk7KsPAyDXGA
|
password: 8YdLnk7KsPAyDXGA
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
@@ -14,8 +14,8 @@ spring:
|
|||||||
# redis
|
# redis
|
||||||
redis:
|
redis:
|
||||||
database: 0
|
database: 0
|
||||||
host: 8.134.169.209
|
host: 1Panel-redis-Q1LE
|
||||||
port: 16379
|
port: 6379
|
||||||
password: redis_WSDb88
|
password: redis_WSDb88
|
||||||
|
|
||||||
# 日志配置
|
# 日志配置
|
||||||
|
|||||||
@@ -119,9 +119,9 @@ shop:
|
|||||||
order:
|
order:
|
||||||
# 测试账号配置
|
# 测试账号配置
|
||||||
test-account:
|
test-account:
|
||||||
enabled: false # 禁用测试账号功能
|
enabled: true # 禁用测试账号功能
|
||||||
phone-numbers:
|
phone-numbers:
|
||||||
- "13800000000" # 改为其他测试手机号
|
- "13737128880" # 改为其他测试手机号
|
||||||
test-pay-amount: 0.01
|
test-pay-amount: 0.01
|
||||||
|
|
||||||
# 租户特殊规则配置
|
# 租户特殊规则配置
|
||||||
|
|||||||
Reference in New Issue
Block a user