feat:日志打印、异常处理
This commit is contained in:
@@ -11,10 +11,23 @@
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Validation 依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Logback 依赖(LogUtil使用) -->
|
||||
<!-- Spring Boot Starter已包含,此处显式声明以便直接使用Logger类 -->
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -1,28 +0,0 @@
|
||||
package pers.amos.mall.common.constant;
|
||||
|
||||
/**
|
||||
* 通用错误码
|
||||
*/
|
||||
public interface CommonErrorCode {
|
||||
|
||||
/**
|
||||
* 系统错误
|
||||
*/
|
||||
String SYSTEM_ERROR = "SYSTEM_ERROR";
|
||||
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
String PARAM_ERROR = "PARAM_ERROR";
|
||||
|
||||
/**
|
||||
* 数据不存在
|
||||
*/
|
||||
String DATA_NOT_FOUND = "DATA_NOT_FOUND";
|
||||
|
||||
/**
|
||||
* 操作失败
|
||||
*/
|
||||
String OPERATION_FAILED = "OPERATION_FAILED";
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package pers.amos.mall.common.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务错误码
|
||||
*
|
||||
* @author deepinnet
|
||||
*/
|
||||
@Getter
|
||||
public enum BizErrorCode {
|
||||
|
||||
|
||||
/**
|
||||
* 通用错误码
|
||||
*/
|
||||
SYSTEM_ERROR("SYSTEM_ERROR", "系统内部错误"),
|
||||
ILLEGAL_PARAMS("ILLEGAL_PARAMS", "参数非法"),
|
||||
ILLEGAL_REQUEST("ILLEGAL_REQUEST", "非法请求"),
|
||||
OPERATION_FAILED("OPERATION_FAILED", "操作失败"),
|
||||
NOT_FOUND("NOT_FOUND", "未找到相关资源"),
|
||||
ALREADY_EXISTS("ALREADY_EXISTS", "资源已存在"),
|
||||
UNKNOWN_EXCEPTION("UNKNOWN_EXCEPTION", "未知异常"),
|
||||
NOT_EXIST_ERROR("NOT_EXIST_ERROR", "暂无数据"),
|
||||
FILE_DOWNLOAD_ERROR("FILE_DOWNLOAD_ERROR", "文件下载异常"),
|
||||
NO_PERMISSION("NO_PERMISSION", "无权限"),
|
||||
PARAM_ERROR("PARAM_ERROR", "参数错误"),
|
||||
INTERNAL_SERVER_ERROR("INTERNAL_SERVER_ERROR", "服务器内部错误"),
|
||||
FILE_SIZE_EXCEEDS_THE_LIMIT("FILE_SIZE_EXCEEDS_THE_LIMIT", "文件大小超过限制"),
|
||||
|
||||
|
||||
;
|
||||
/**
|
||||
* 错误码
|
||||
*/
|
||||
private final String code;
|
||||
|
||||
/**
|
||||
* 错误描述
|
||||
*/
|
||||
private final String desc;
|
||||
|
||||
BizErrorCode(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package pers.amos.mall.common.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@Getter
|
||||
public class BizException extends RuntimeException {
|
||||
|
||||
private String errorCode;
|
||||
private String errorDesc;
|
||||
|
||||
public BizException(String errorDesc) {
|
||||
super(errorDesc);
|
||||
this.errorDesc = errorDesc;
|
||||
}
|
||||
|
||||
public BizException(String errorCode, String errorDesc) {
|
||||
super(errorDesc);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
package pers.amos.mall.common.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import pers.amos.mall.common.response.ErrorType;
|
||||
|
||||
/**
|
||||
* 业务异常
|
||||
*/
|
||||
@Getter
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private String errorCode;
|
||||
private String errorDesc;
|
||||
private ErrorType errorType;
|
||||
|
||||
public BusinessException(String errorDesc) {
|
||||
super(errorDesc);
|
||||
this.errorDesc = errorDesc;
|
||||
this.errorType = ErrorType.BUSINESS;
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode, String errorDesc) {
|
||||
super(errorDesc);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
this.errorType = ErrorType.BUSINESS;
|
||||
}
|
||||
|
||||
public BusinessException(String errorCode, String errorDesc, ErrorType errorType) {
|
||||
super(errorDesc);
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
this.errorType = errorType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
package pers.amos.mall.common.exception;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.multipart.MaxUploadSizeExceededException;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局异常处理器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestControllerAdvice
|
||||
@SuppressWarnings("all")
|
||||
public class GlobalControllerAdvise {
|
||||
|
||||
/**
|
||||
* 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常
|
||||
*/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Result methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
|
||||
FieldError fieldError = e.getBindingResult().getFieldError();
|
||||
String message = fieldError != null ? fieldError.getField() + " " + fieldError.getDefaultMessage() : "参数校验失败";
|
||||
LogUtil.error("参数校验失败", e);
|
||||
return Result.fail(BizErrorCode.PARAM_ERROR.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
|
||||
*/
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Result bindExceptionHandler(BindException e) {
|
||||
LogUtil.error("参数绑定异常", e);
|
||||
String message = e.getBindingResult().getAllErrors().stream()
|
||||
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||
.collect(Collectors.joining(";"));
|
||||
return Result.fail(BizErrorCode.PARAM_ERROR.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
|
||||
*/
|
||||
@ExceptionHandler(ConstraintViolationException.class)
|
||||
public Result constraintViolationExceptionHandler(ConstraintViolationException e) {
|
||||
LogUtil.error("参数约束异常", e);
|
||||
String message = e.getConstraintViolations().stream()
|
||||
.map(ConstraintViolation::getMessage)
|
||||
.collect(Collectors.joining(";"));
|
||||
return Result.fail(BizErrorCode.PARAM_ERROR.getCode(), message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务异常处理
|
||||
*
|
||||
* @param e 业务异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(BizException.class)
|
||||
public Result bizExceptionHandler(BizException e) {
|
||||
LogUtil.error("业务异常", e);
|
||||
String errorCode = e.getErrorCode() != null ? e.getErrorCode() : BizErrorCode.OPERATION_FAILED.getCode();
|
||||
String errorDesc = e.getErrorDesc() != null ? e.getErrorDesc() : e.getMessage();
|
||||
return Result.fail(errorCode, errorDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非法参数异常处理
|
||||
*
|
||||
* @param e 非法参数异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public Result illegalArgumentExceptionHandler(IllegalArgumentException e) {
|
||||
LogUtil.error("非法参数", e);
|
||||
return Result.fail(BizErrorCode.PARAM_ERROR.getCode(), e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部兜底异常处理
|
||||
*
|
||||
* @param e 异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Result exceptionHandler(Exception e) {
|
||||
LogUtil.error("系统异常", e);
|
||||
return Result.fail(BizErrorCode.INTERNAL_SERVER_ERROR.getCode(), BizErrorCode.INTERNAL_SERVER_ERROR.getDesc());
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件大小超限异常处理
|
||||
*
|
||||
* @param e 文件大小超限异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(MaxUploadSizeExceededException.class)
|
||||
public Result maxUploadSizeExceededExceptionHandler(MaxUploadSizeExceededException e) {
|
||||
LogUtil.error("文件大小超过限制", e);
|
||||
return Result.fail(BizErrorCode.FILE_SIZE_EXCEEDS_THE_LIMIT.getCode(), "文件大小超过限制,附件大小上限为50MB");
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺少请求参数异常处理
|
||||
*
|
||||
* @param e 缺少请求参数异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(MissingServletRequestParameterException.class)
|
||||
public Result missingServletRequestParameterExceptionHandler(MissingServletRequestParameterException e) {
|
||||
LogUtil.error("缺少必要参数", e);
|
||||
return Result.fail(BizErrorCode.ILLEGAL_PARAMS.getCode(), "缺少必要参数: " + e.getParameterName());
|
||||
}
|
||||
|
||||
/**
|
||||
* HTTP消息不可读异常处理
|
||||
*
|
||||
* @param e HTTP消息不可读异常
|
||||
* @return 失败结果
|
||||
*/
|
||||
@ExceptionHandler(HttpMessageNotReadableException.class)
|
||||
public Result httpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
|
||||
LogUtil.error("请求体格式错误", e);
|
||||
return Result.fail(BizErrorCode.ILLEGAL_PARAMS.getCode(), "请求体格式错误");
|
||||
}
|
||||
}
|
||||
89
common/src/main/java/pers/amos/mall/common/log/LogUtil.java
Normal file
89
common/src/main/java/pers/amos/mall/common/log/LogUtil.java
Normal file
@@ -0,0 +1,89 @@
|
||||
package pers.amos.mall.common.log;
|
||||
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* 日志打印工具类
|
||||
*
|
||||
* @author taobinxian
|
||||
* @version 2022-10-31
|
||||
*/
|
||||
@Slf4j
|
||||
public class LogUtil {
|
||||
|
||||
public static void info(Logger logger, String format, Object... params) {
|
||||
logger.info(format, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印info级别日志
|
||||
*
|
||||
* @param format
|
||||
* @param args
|
||||
*/
|
||||
public static void info(String format, Object... args) {
|
||||
log.info(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印warn级别日志
|
||||
*
|
||||
* @param format
|
||||
* @param args
|
||||
*/
|
||||
public static void warn(Logger logger, String format, Object... args) {
|
||||
logger.warn(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印warn级别日志
|
||||
*
|
||||
* @param format
|
||||
* @param args
|
||||
*/
|
||||
public static void warn(String format, Object... args) {
|
||||
log.warn(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印error级别日志
|
||||
*
|
||||
* @param format
|
||||
* @param args
|
||||
*/
|
||||
public static void error(Logger logger, String format, Object... args) {
|
||||
logger.error(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印error级别日志
|
||||
*
|
||||
* @param format
|
||||
* @param args
|
||||
*/
|
||||
public static void error(String format, Object... args) {
|
||||
log.error(format, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印error级别日志
|
||||
*
|
||||
* @param message
|
||||
* @param throwable
|
||||
*/
|
||||
public static void error(Logger logger, String message, Throwable throwable) {
|
||||
logger.error(message, throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印error级别日志
|
||||
*
|
||||
* @param message
|
||||
* @param throwable
|
||||
*/
|
||||
public static void error(String message, Throwable throwable) {
|
||||
log.error(message, throwable);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package pers.amos.mall.common.response;
|
||||
|
||||
/**
|
||||
* 错误类型枚举
|
||||
*/
|
||||
public enum ErrorType {
|
||||
/**
|
||||
* 系统错误
|
||||
*/
|
||||
SYSTEM,
|
||||
|
||||
/**
|
||||
* 业务错误
|
||||
*/
|
||||
BUSINESS,
|
||||
|
||||
/**
|
||||
* 参数错误
|
||||
*/
|
||||
PARAM,
|
||||
|
||||
/**
|
||||
* 第三方错误
|
||||
*/
|
||||
THIRD_PARTY
|
||||
}
|
||||
|
||||
@@ -35,18 +35,6 @@ public class Result<T> implements Serializable {
|
||||
*/
|
||||
private String errorDesc;
|
||||
|
||||
/**
|
||||
* 失败时异常类型
|
||||
*/
|
||||
private ErrorType errorType = ErrorType.SYSTEM;
|
||||
|
||||
/**
|
||||
* exceptionType
|
||||
* 由于facade不抛出异常通过InsException把异常扔出
|
||||
* 需增加exceptionType去打印异常类型
|
||||
*/
|
||||
private String exceptionType;
|
||||
|
||||
/**
|
||||
* 业务数据
|
||||
*/
|
||||
@@ -67,20 +55,6 @@ public class Result<T> implements Serializable {
|
||||
this.data = model;
|
||||
}
|
||||
|
||||
public Result(boolean success, String errorCode, String errorDesc, ErrorType errorType) {
|
||||
this.success = success;
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
this.errorType = errorType;
|
||||
}
|
||||
|
||||
public Result(boolean success, String errorCode, String errorDesc, String exceptionType) {
|
||||
this.success = success;
|
||||
this.errorCode = errorCode;
|
||||
this.errorDesc = errorDesc;
|
||||
this.exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
public Result(boolean success, String errorCode, String errorDesc) {
|
||||
this.success = success;
|
||||
this.errorCode = errorCode;
|
||||
@@ -108,19 +82,6 @@ public class Result<T> implements Serializable {
|
||||
return new Result<>(true, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果构造
|
||||
*
|
||||
* @param errorCode 错误码
|
||||
* @param errorDesc 错误描述
|
||||
* @param errorType 错误类型
|
||||
* @param <T> 数据类型
|
||||
* @return 失败结果
|
||||
*/
|
||||
public static <T> Result<T> fail(String errorCode, String errorDesc, ErrorType errorType) {
|
||||
return new Result<>(false, errorCode, errorDesc, errorType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果构造
|
||||
*
|
||||
@@ -133,19 +94,6 @@ public class Result<T> implements Serializable {
|
||||
return new Result<>(false, errorCode, errorDesc);
|
||||
}
|
||||
|
||||
/**
|
||||
* 失败结果构造
|
||||
*
|
||||
* @param errorCode 错误码
|
||||
* @param errorDesc 错误描述
|
||||
* @param exceptionType 异常类型
|
||||
* @param <T> 数据类型
|
||||
* @return 失败结果
|
||||
*/
|
||||
public static <T> Result<T> fail(String errorCode, String errorDesc, String exceptionType) {
|
||||
return new Result<>(false, errorCode, errorDesc, exceptionType);
|
||||
}
|
||||
|
||||
public Result<T> setData(T data) {
|
||||
this.data = data;
|
||||
return this;
|
||||
@@ -178,14 +126,5 @@ public class Result<T> implements Serializable {
|
||||
this.errorDesc = errorDesc;
|
||||
}
|
||||
|
||||
public Result<T> setErrorType(ErrorType errorType) {
|
||||
this.errorType = errorType;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setExceptionType(String exceptionType) {
|
||||
this.exceptionType = exceptionType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pers.amos.mall.perform.listener;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
|
||||
import org.apache.rocketmq.spring.core.RocketMQListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -10,13 +9,14 @@ import pers.amos.mall.api.dto.PaymentSuccessMessage;
|
||||
import pers.amos.mall.api.dto.TicketGenerateDTO;
|
||||
import pers.amos.mall.api.service.TicketService;
|
||||
import pers.amos.mall.common.constant.MQConstant;
|
||||
import pers.amos.mall.common.exception.BizException;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
|
||||
/**
|
||||
* 支付成功消息监听器
|
||||
* 监听到支付成功消息后生成车票
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RocketMQMessageListener(
|
||||
topic = MQConstant.PAYMENT_SUCCESS_TOPIC,
|
||||
@@ -30,38 +30,30 @@ public class PaymentSuccessListener implements RocketMQListener<PaymentSuccessMe
|
||||
|
||||
@Override
|
||||
public void onMessage(PaymentSuccessMessage message) {
|
||||
log.info("收到支付成功消息, orderNo={}, message={}",
|
||||
LogUtil.info("收到支付成功消息, orderNo={}, message={}",
|
||||
message.getOrderNo(), JSONUtil.toJsonStr(message));
|
||||
|
||||
try {
|
||||
// 构建车票生成DTO
|
||||
TicketGenerateDTO generateDTO = new TicketGenerateDTO();
|
||||
generateDTO.setOrderNo(message.getOrderNo());
|
||||
generateDTO.setUserNo(message.getUserNo());
|
||||
generateDTO.setRouteCode(message.getRouteCode());
|
||||
generateDTO.setOrderType(message.getOrderType());
|
||||
generateDTO.setScheduleCode(message.getScheduleCode());
|
||||
generateDTO.setRollingScheduleCode(message.getRollingScheduleCode());
|
||||
generateDTO.setTicketType(message.getTicketType());
|
||||
generateDTO.setQuantity(message.getQuantity());
|
||||
|
||||
// 生成车票
|
||||
Result<?> result = ticketService.generateTickets(generateDTO);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
log.info("车票生成成功, orderNo={}, quantity={}",
|
||||
message.getOrderNo(), message.getQuantity());
|
||||
} else {
|
||||
log.error("车票生成失败, orderNo={}, errorMsg={}",
|
||||
message.getOrderNo(), result.getErrorDesc());
|
||||
// TODO: 这里可以考虑重试机制或补偿逻辑
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付成功消息失败, orderNo={}", message.getOrderNo(), e);
|
||||
// TODO: 这里可以考虑将失败消息发送到死信队列
|
||||
throw e; // 抛出异常让RocketMQ重试
|
||||
// 构建车票生成DTO
|
||||
TicketGenerateDTO generateDTO = new TicketGenerateDTO();
|
||||
generateDTO.setOrderNo(message.getOrderNo());
|
||||
generateDTO.setUserNo(message.getUserNo());
|
||||
generateDTO.setRouteCode(message.getRouteCode());
|
||||
generateDTO.setOrderType(message.getOrderType());
|
||||
generateDTO.setScheduleCode(message.getScheduleCode());
|
||||
generateDTO.setRollingScheduleCode(message.getRollingScheduleCode());
|
||||
generateDTO.setTicketType(message.getTicketType());
|
||||
generateDTO.setQuantity(message.getQuantity());
|
||||
|
||||
// 生成车票
|
||||
Result<?> result = ticketService.generateTickets(generateDTO);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
LogUtil.info("车票生成成功, orderNo={}, quantity={}",
|
||||
message.getOrderNo(), message.getQuantity());
|
||||
} else {
|
||||
LogUtil.error("车票生成失败, orderNo={}, errorMsg={}",
|
||||
message.getOrderNo(), result.getErrorDesc());
|
||||
throw new BizException("TICKET_GENERATE_FAILED", "车票生成失败: " + result.getErrorDesc());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pers.amos.mall.perform.service;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -9,6 +8,7 @@ import pers.amos.mall.api.dto.TicketDTO;
|
||||
import pers.amos.mall.api.dto.TicketGenerateDTO;
|
||||
import pers.amos.mall.api.service.TicketService;
|
||||
import pers.amos.mall.common.enums.TicketStatusEnum;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
import pers.amos.mall.perform.dal.dataobject.Ticket;
|
||||
import pers.amos.mall.perform.dal.repository.TicketRepository;
|
||||
@@ -22,7 +22,6 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 车票服务Dubbo实现
|
||||
*/
|
||||
@Slf4j
|
||||
@DubboService
|
||||
public class TicketServiceImpl implements TicketService {
|
||||
|
||||
@@ -31,47 +30,41 @@ public class TicketServiceImpl implements TicketService {
|
||||
|
||||
@Override
|
||||
public Result<List<TicketDTO>> generateTickets(TicketGenerateDTO dto) {
|
||||
try {
|
||||
List<Ticket> tickets = new ArrayList<>();
|
||||
List<Ticket> tickets = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < dto.getQuantity(); i++) {
|
||||
Ticket ticket = new Ticket();
|
||||
ticket.setTicketNo(generateTicketNo());
|
||||
ticket.setOrderNo(dto.getOrderNo());
|
||||
ticket.setUserNo(dto.getUserNo());
|
||||
ticket.setRouteCode(dto.getRouteCode());
|
||||
ticket.setOrderType(dto.getOrderType());
|
||||
ticket.setScheduleCode(dto.getScheduleCode());
|
||||
ticket.setRollingScheduleCode(dto.getRollingScheduleCode());
|
||||
ticket.setTicketType(dto.getTicketType());
|
||||
|
||||
for (int i = 0; i < dto.getQuantity(); i++) {
|
||||
Ticket ticket = new Ticket();
|
||||
ticket.setTicketNo(generateTicketNo());
|
||||
ticket.setOrderNo(dto.getOrderNo());
|
||||
ticket.setUserNo(dto.getUserNo());
|
||||
ticket.setRouteCode(dto.getRouteCode());
|
||||
ticket.setOrderType(dto.getOrderType());
|
||||
ticket.setScheduleCode(dto.getScheduleCode());
|
||||
ticket.setRollingScheduleCode(dto.getRollingScheduleCode());
|
||||
ticket.setTicketType(dto.getTicketType());
|
||||
|
||||
// 生成二维码内容(这里简单使用票号,实际应该加密)
|
||||
ticket.setQrCode(encryptTicketNo(ticket.getTicketNo()));
|
||||
|
||||
ticket.setStatus(TicketStatusEnum.VALID.getCode());
|
||||
ticket.setIssueTime(LocalDateTime.now());
|
||||
ticket.setCreateTime(LocalDateTime.now());
|
||||
ticket.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
tickets.add(ticket);
|
||||
}
|
||||
// 生成二维码内容(这里简单使用票号,实际应该加密)
|
||||
ticket.setQrCode(encryptTicketNo(ticket.getTicketNo()));
|
||||
|
||||
// 批量保存
|
||||
ticketRepository.saveBatch(tickets);
|
||||
ticket.setStatus(TicketStatusEnum.VALID.getCode());
|
||||
ticket.setIssueTime(LocalDateTime.now());
|
||||
ticket.setCreateTime(LocalDateTime.now());
|
||||
ticket.setUpdateTime(LocalDateTime.now());
|
||||
|
||||
log.info("车票生成成功, orderNo={}, quantity={}", dto.getOrderNo(), dto.getQuantity());
|
||||
|
||||
// 转换为DTO
|
||||
List<TicketDTO> ticketDTOs = tickets.stream()
|
||||
.map(this::convertToDTO)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Result.success(ticketDTOs);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("车票生成失败, orderNo={}", dto.getOrderNo(), e);
|
||||
return Result.fail("TICKET_GENERATE_ERROR", "车票生成失败:" + e.getMessage());
|
||||
tickets.add(ticket);
|
||||
}
|
||||
|
||||
// 批量保存
|
||||
ticketRepository.saveBatch(tickets);
|
||||
|
||||
LogUtil.info("车票生成成功, orderNo={}, quantity={}", dto.getOrderNo(), dto.getQuantity());
|
||||
|
||||
// 转换为DTO
|
||||
List<TicketDTO> ticketDTOs = tickets.stream()
|
||||
.map(this::convertToDTO)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return Result.success(ticketDTOs);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,4 +95,3 @@ public class TicketServiceImpl implements TicketService {
|
||||
return dto;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package pers.amos.mall.route.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.dubbo.config.annotation.DubboService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import pers.amos.mall.api.dto.InventoryCheckDTO;
|
||||
@@ -9,6 +8,7 @@ import pers.amos.mall.api.dto.InventoryOperationDTO;
|
||||
import pers.amos.mall.api.service.RouteService;
|
||||
import pers.amos.mall.common.enums.InventoryOperationTypeEnum;
|
||||
import pers.amos.mall.common.enums.OrderTypeEnum;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
import pers.amos.mall.route.dal.dataobject.FixedSchedule;
|
||||
import pers.amos.mall.route.dal.dataobject.InventoryLog;
|
||||
@@ -22,7 +22,6 @@ import java.time.LocalDateTime;
|
||||
/**
|
||||
* 线路服务Dubbo实现
|
||||
*/
|
||||
@Slf4j
|
||||
@DubboService
|
||||
public class RouteServiceImpl implements RouteService {
|
||||
|
||||
@@ -37,57 +36,37 @@ public class RouteServiceImpl implements RouteService {
|
||||
|
||||
@Override
|
||||
public Result<Boolean> checkInventory(InventoryCheckDTO dto) {
|
||||
try {
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return checkFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return checkRollingScheduleInventory(dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("检查库存失败", e);
|
||||
return Result.fail("INVENTORY_CHECK_ERROR", "检查库存失败:" + e.getMessage());
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return checkFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return checkRollingScheduleInventory(dto);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> lockInventory(InventoryOperationDTO dto) {
|
||||
try {
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return lockFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return lockRollingScheduleInventory(dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("锁定库存失败, orderNo={}", dto.getOrderNo(), e);
|
||||
return Result.fail("INVENTORY_LOCK_ERROR", "锁定库存失败:" + e.getMessage());
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return lockFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return lockRollingScheduleInventory(dto);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> deductInventory(InventoryOperationDTO dto) {
|
||||
try {
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return deductFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return deductRollingScheduleInventory(dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("扣减库存失败, orderNo={}", dto.getOrderNo(), e);
|
||||
return Result.fail("INVENTORY_DEDUCT_ERROR", "扣减库存失败:" + e.getMessage());
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return deductFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return deductRollingScheduleInventory(dto);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<Boolean> releaseInventory(InventoryOperationDTO dto) {
|
||||
try {
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return releaseFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return releaseRollingScheduleInventory(dto);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("释放库存失败, orderNo={}", dto.getOrderNo(), e);
|
||||
return Result.fail("INVENTORY_RELEASE_ERROR", "释放库存失败:" + e.getMessage());
|
||||
if (OrderTypeEnum.FIXED.getCode().equals(dto.getOrderType())) {
|
||||
return releaseFixedScheduleInventory(dto);
|
||||
} else {
|
||||
return releaseRollingScheduleInventory(dto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +120,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeQty, beforeQty - dto.getQuantity(),
|
||||
dto.getOrderNo(), "锁定库存");
|
||||
|
||||
log.info("固定班次库存锁定成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("固定班次库存锁定成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -171,7 +150,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeSold, beforeSold + dto.getQuantity(),
|
||||
dto.getOrderNo(), "扣减库存(支付成功)");
|
||||
|
||||
log.info("固定班次库存扣减成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("固定班次库存扣减成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -201,7 +180,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeQty, beforeQty + dto.getQuantity(),
|
||||
dto.getOrderNo(), "释放库存(订单取消/超时)");
|
||||
|
||||
log.info("固定班次库存释放成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("固定班次库存释放成功, scheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -257,7 +236,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeQty, beforeQty - dto.getQuantity(),
|
||||
dto.getOrderNo(), "锁定共享库存池");
|
||||
|
||||
log.info("滚动班次库存锁定成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("滚动班次库存锁定成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getRollingScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -286,7 +265,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeSold, beforeSold + dto.getQuantity(),
|
||||
dto.getOrderNo(), "扣减库存(支付成功)");
|
||||
|
||||
log.info("滚动班次库存扣减成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("滚动班次库存扣减成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getRollingScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -316,7 +295,7 @@ public class RouteServiceImpl implements RouteService {
|
||||
dto.getQuantity(), beforeQty, beforeQty + dto.getQuantity(),
|
||||
dto.getOrderNo(), "释放库存(订单取消/超时)");
|
||||
|
||||
log.info("滚动班次库存释放成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
LogUtil.info("滚动班次库存释放成功, rollingScheduleCode={}, quantity={}, orderNo={}",
|
||||
dto.getRollingScheduleCode(), dto.getQuantity(), dto.getOrderNo());
|
||||
|
||||
return Result.success(true);
|
||||
@@ -328,19 +307,18 @@ public class RouteServiceImpl implements RouteService {
|
||||
String rollingScheduleCode, String operationType,
|
||||
Integer quantity, Integer beforeQty, Integer afterQty,
|
||||
String orderNo, String remark) {
|
||||
InventoryLog log = new InventoryLog();
|
||||
log.setInventoryType(inventoryType);
|
||||
log.setScheduleCode(scheduleCode);
|
||||
log.setRollingScheduleCode(rollingScheduleCode);
|
||||
log.setOperationType(operationType);
|
||||
log.setQuantity(quantity);
|
||||
log.setBeforeQty(beforeQty);
|
||||
log.setAfterQty(afterQty);
|
||||
log.setOrderNo(orderNo);
|
||||
log.setRemark(remark);
|
||||
log.setCreateTime(LocalDateTime.now());
|
||||
InventoryLog inventoryLog = new InventoryLog();
|
||||
inventoryLog.setInventoryType(inventoryType);
|
||||
inventoryLog.setScheduleCode(scheduleCode);
|
||||
inventoryLog.setRollingScheduleCode(rollingScheduleCode);
|
||||
inventoryLog.setOperationType(operationType);
|
||||
inventoryLog.setQuantity(quantity);
|
||||
inventoryLog.setBeforeQty(beforeQty);
|
||||
inventoryLog.setAfterQty(afterQty);
|
||||
inventoryLog.setOrderNo(orderNo);
|
||||
inventoryLog.setRemark(remark);
|
||||
inventoryLog.setCreateTime(LocalDateTime.now());
|
||||
|
||||
inventoryLogRepository.save(log);
|
||||
inventoryLogRepository.save(inventoryLog);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package pers.amos.mall.trade.controller;
|
||||
|
||||
import com.yomahub.liteflow.core.FlowExecutor;
|
||||
import com.yomahub.liteflow.flow.LiteflowResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@@ -10,13 +9,14 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import pers.amos.mall.api.dto.OrderCreateDTO;
|
||||
import pers.amos.mall.api.dto.OrderResultDTO;
|
||||
import pers.amos.mall.common.exception.BizException;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
import pers.amos.mall.trade.liteflow.context.OrderContext;
|
||||
|
||||
/**
|
||||
* 订单Controller
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/order")
|
||||
public class OrderController {
|
||||
@@ -29,30 +29,22 @@ public class OrderController {
|
||||
*/
|
||||
@PostMapping("/create")
|
||||
public Result<OrderResultDTO> createOrder(@RequestBody OrderCreateDTO dto) {
|
||||
log.info("收到创建订单请求, userNo={}, routeCode={}, orderType={}, quantity={}",
|
||||
LogUtil.info("收到创建订单请求, userNo={}, routeCode={}, orderType={}, quantity={}",
|
||||
dto.getUserNo(), dto.getRouteCode(), dto.getOrderType(), dto.getQuantity());
|
||||
|
||||
try {
|
||||
// 创建上下文
|
||||
OrderContext context = new OrderContext();
|
||||
context.setOrderCreateDTO(dto);
|
||||
|
||||
// 执行流程
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("orderChain", null, context);
|
||||
|
||||
if (response.isSuccess()) {
|
||||
OrderResultDTO resultDTO = context.getOrderResultDTO();
|
||||
log.info("订单创建成功, orderNo={}", resultDTO.getOrderNo());
|
||||
return Result.success(resultDTO);
|
||||
} else {
|
||||
log.error("订单创建失败: {}", response.getMessage());
|
||||
return Result.fail("ORDER_CREATE_FAIL", response.getMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("订单创建异常", e);
|
||||
return Result.fail("ORDER_CREATE_ERROR", "订单创建失败:" + e.getMessage());
|
||||
// 创建上下文
|
||||
OrderContext context = new OrderContext();
|
||||
context.setOrderCreateDTO(dto);
|
||||
|
||||
// 执行流程
|
||||
LiteflowResponse response = flowExecutor.execute2Resp("orderChain", null, context);
|
||||
|
||||
if (response.isSuccess()) {
|
||||
OrderResultDTO resultDTO = context.getOrderResultDTO();
|
||||
LogUtil.info("订单创建成功, orderNo={}", resultDTO.getOrderNo());
|
||||
return Result.success(resultDTO);
|
||||
} else {
|
||||
throw new BizException("ORDER_CREATE_FAIL", response.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
package pers.amos.mall.trade.controller;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import pers.amos.mall.api.dto.PaymentCallbackDTO;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
import pers.amos.mall.trade.service.PaymentService;
|
||||
|
||||
/**
|
||||
* 支付控制器
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/payment")
|
||||
public class PaymentController {
|
||||
@@ -29,10 +28,9 @@ public class PaymentController {
|
||||
*/
|
||||
@PostMapping("/callback")
|
||||
public Result<Boolean> paymentCallback(@RequestBody PaymentCallbackDTO callbackDTO) {
|
||||
log.info("接收支付回调, paymentNo={}, orderNo={}",
|
||||
LogUtil.info("接收支付回调, paymentNo={}, orderNo={}",
|
||||
callbackDTO.getPaymentNo(), callbackDTO.getOrderNo());
|
||||
|
||||
return paymentService.handlePaymentCallback(callbackDTO);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.api.dto.OrderResultDTO;
|
||||
import pers.amos.mall.trade.dal.dataobject.Order;
|
||||
import pers.amos.mall.trade.liteflow.context.OrderContext;
|
||||
@@ -11,7 +12,7 @@ import pers.amos.mall.trade.liteflow.context.OrderContext;
|
||||
/**
|
||||
* 构建返回结果节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("buildResult")
|
||||
public class BuildResultNode extends NodeComponent {
|
||||
|
||||
@@ -20,7 +21,7 @@ public class BuildResultNode extends NodeComponent {
|
||||
OrderContext context = this.getContextBean(OrderContext.class);
|
||||
Order order = context.getOrder();
|
||||
|
||||
log.info("开始构建返回结果, orderNo={}", order.getOrderNo());
|
||||
LogUtil.info("开始构建返回结果, orderNo={}", order.getOrderNo());
|
||||
|
||||
// 构建返回DTO
|
||||
OrderResultDTO resultDTO = new OrderResultDTO();
|
||||
@@ -29,7 +30,7 @@ public class BuildResultNode extends NodeComponent {
|
||||
|
||||
context.setOrderResultDTO(resultDTO);
|
||||
|
||||
log.info("返回结果构建成功, orderNo={}", order.getOrderNo());
|
||||
LogUtil.info("返回结果构建成功, orderNo={}", order.getOrderNo());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.api.dto.InventoryCheckDTO;
|
||||
import pers.amos.mall.api.dto.OrderCreateDTO;
|
||||
import pers.amos.mall.api.service.RouteService;
|
||||
@@ -14,7 +15,7 @@ import pers.amos.mall.trade.liteflow.context.OrderContext;
|
||||
/**
|
||||
* 检查库存节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("checkInventory")
|
||||
public class CheckInventoryNode extends NodeComponent {
|
||||
|
||||
@@ -26,7 +27,7 @@ public class CheckInventoryNode extends NodeComponent {
|
||||
OrderContext context = this.getContextBean(OrderContext.class);
|
||||
OrderCreateDTO dto = context.getOrderCreateDTO();
|
||||
|
||||
log.info("开始检查库存, orderType={}, quantity={}", dto.getOrderType(), dto.getQuantity());
|
||||
LogUtil.info("开始检查库存, orderType={}, quantity={}", dto.getOrderType(), dto.getQuantity());
|
||||
|
||||
// 构建库存检查DTO
|
||||
InventoryCheckDTO checkDTO = new InventoryCheckDTO();
|
||||
@@ -42,7 +43,7 @@ public class CheckInventoryNode extends NodeComponent {
|
||||
throw new RuntimeException("库存不足:" + result.getErrorDesc());
|
||||
}
|
||||
|
||||
log.info("库存检查通过, orderType={}, quantity={}", dto.getOrderType(), dto.getQuantity());
|
||||
LogUtil.info("库存检查通过, orderType={}, quantity={}", dto.getOrderType(), dto.getQuantity());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.api.dto.OrderCreateDTO;
|
||||
import pers.amos.mall.common.enums.OrderStatusEnum;
|
||||
import pers.amos.mall.common.enums.OrderTypeEnum;
|
||||
@@ -17,7 +18,7 @@ import java.time.LocalDateTime;
|
||||
/**
|
||||
* 创建订单节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("createOrder")
|
||||
public class CreateOrderNode extends NodeComponent {
|
||||
|
||||
@@ -32,7 +33,7 @@ public class CreateOrderNode extends NodeComponent {
|
||||
// 从上下文获取订单号(临时存储在errorMessage中)
|
||||
String orderNo = context.getErrorMessage();
|
||||
|
||||
log.info("开始创建订单, orderNo={}", orderNo);
|
||||
LogUtil.info("开始创建订单, orderNo={}", orderNo);
|
||||
|
||||
Order order = new Order();
|
||||
order.setOrderNo(orderNo);
|
||||
@@ -66,7 +67,7 @@ public class CreateOrderNode extends NodeComponent {
|
||||
// 将订单保存到上下文
|
||||
context.setOrder(order);
|
||||
|
||||
log.info("订单创建成功, orderNo={}, totalAmount={}", orderNo, order.getTotalAmount());
|
||||
LogUtil.info("订单创建成功, orderNo={}, totalAmount={}", orderNo, order.getTotalAmount());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.api.dto.TicketDTO;
|
||||
import pers.amos.mall.api.dto.TicketGenerateDTO;
|
||||
import pers.amos.mall.api.service.TicketService;
|
||||
@@ -16,7 +17,7 @@ import java.util.List;
|
||||
/**
|
||||
* 生成车票节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("generateTickets")
|
||||
public class GenerateTicketsNode extends NodeComponent {
|
||||
|
||||
@@ -28,7 +29,7 @@ public class GenerateTicketsNode extends NodeComponent {
|
||||
OrderContext context = this.getContextBean(OrderContext.class);
|
||||
Order order = context.getOrder();
|
||||
|
||||
log.info("开始生成车票, orderNo={}, quantity={}", order.getOrderNo(), order.getQuantity());
|
||||
LogUtil.info("开始生成车票, orderNo={}, quantity={}", order.getOrderNo(), order.getQuantity());
|
||||
|
||||
// 构建生成车票DTO
|
||||
TicketGenerateDTO generateDTO = new TicketGenerateDTO();
|
||||
@@ -51,7 +52,7 @@ public class GenerateTicketsNode extends NodeComponent {
|
||||
// 将车票保存到上下文
|
||||
context.setTickets(result.getData());
|
||||
|
||||
log.info("车票生成成功, orderNo={}, ticketCount={}",
|
||||
LogUtil.info("车票生成成功, orderNo={}, ticketCount={}",
|
||||
order.getOrderNo(), result.getData().size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,10 @@ package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.dubbo.config.annotation.DubboReference;
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.api.dto.InventoryOperationDTO;
|
||||
import pers.amos.mall.api.dto.OrderCreateDTO;
|
||||
import pers.amos.mall.api.service.RouteService;
|
||||
@@ -18,7 +19,7 @@ import java.time.format.DateTimeFormatter;
|
||||
/**
|
||||
* 锁定库存节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("lockInventory")
|
||||
public class LockInventoryNode extends NodeComponent {
|
||||
|
||||
@@ -33,7 +34,7 @@ public class LockInventoryNode extends NodeComponent {
|
||||
// 生成订单号
|
||||
String orderNo = generateOrderNo();
|
||||
|
||||
log.info("开始锁定库存, orderNo={}, orderType={}, quantity={}",
|
||||
LogUtil.info("开始锁定库存, orderNo={}, orderType={}, quantity={}",
|
||||
orderNo, dto.getOrderType(), dto.getQuantity());
|
||||
|
||||
// 构建库存操作DTO
|
||||
@@ -58,7 +59,7 @@ public class LockInventoryNode extends NodeComponent {
|
||||
context.setErrorMessage(operationDTO.getRollingScheduleCode()); // 临时存储
|
||||
}
|
||||
|
||||
log.info("库存锁定成功, orderNo={}", orderNo);
|
||||
LogUtil.info("库存锁定成功, orderNo={}", orderNo);
|
||||
|
||||
// 将订单号保存到上下文
|
||||
context.setErrorMessage(orderNo); // 临时存储订单号
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package pers.amos.mall.trade.liteflow.node;
|
||||
|
||||
import com.yomahub.liteflow.core.NodeComponent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import org.springframework.util.StringUtils;
|
||||
import pers.amos.mall.api.dto.OrderCreateDTO;
|
||||
import pers.amos.mall.common.enums.OrderTypeEnum;
|
||||
@@ -11,7 +12,7 @@ import pers.amos.mall.trade.liteflow.context.OrderContext;
|
||||
/**
|
||||
* 参数校验节点
|
||||
*/
|
||||
@Slf4j
|
||||
|
||||
@Component("validateParams")
|
||||
public class ValidateParamsNode extends NodeComponent {
|
||||
|
||||
@@ -20,7 +21,7 @@ public class ValidateParamsNode extends NodeComponent {
|
||||
OrderContext context = this.getContextBean(OrderContext.class);
|
||||
OrderCreateDTO dto = context.getOrderCreateDTO();
|
||||
|
||||
log.info("开始参数校验, userNo={}", dto.getUserNo());
|
||||
LogUtil.info("开始参数校验, userNo={}", dto.getUserNo());
|
||||
|
||||
// 校验基本参数
|
||||
if (!StringUtils.hasText(dto.getUserNo())) {
|
||||
@@ -52,7 +53,7 @@ public class ValidateParamsNode extends NodeComponent {
|
||||
throw new IllegalArgumentException("订单类型无效");
|
||||
}
|
||||
|
||||
log.info("参数校验通过, userNo={}", dto.getUserNo());
|
||||
LogUtil.info("参数校验通过, userNo={}", dto.getUserNo());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@ package pers.amos.mall.trade.service.impl;
|
||||
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.rocketmq.spring.core.RocketMQTemplate;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -15,6 +13,8 @@ import pers.amos.mall.api.service.RouteService;
|
||||
import pers.amos.mall.common.constant.MQConstant;
|
||||
import pers.amos.mall.common.enums.OrderStatusEnum;
|
||||
import pers.amos.mall.common.enums.PaymentStatusEnum;
|
||||
import pers.amos.mall.common.exception.BizException;
|
||||
import pers.amos.mall.common.log.LogUtil;
|
||||
import pers.amos.mall.common.response.Result;
|
||||
import pers.amos.mall.trade.dal.dataobject.Order;
|
||||
import pers.amos.mall.trade.dal.dataobject.Payment;
|
||||
@@ -28,7 +28,6 @@ import java.time.format.DateTimeFormatter;
|
||||
/**
|
||||
* 支付服务实现
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PaymentServiceImpl implements PaymentService {
|
||||
|
||||
@@ -49,65 +48,57 @@ public class PaymentServiceImpl implements PaymentService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> handlePaymentCallback(PaymentCallbackDTO callbackDTO) {
|
||||
log.info("收到支付回调, paymentNo={}, orderNo={}, status={}",
|
||||
LogUtil.info("收到支付回调, paymentNo={}, orderNo={}, status={}",
|
||||
callbackDTO.getPaymentNo(), callbackDTO.getOrderNo(), callbackDTO.getPaymentStatus());
|
||||
|
||||
try {
|
||||
// 1. 查询支付单
|
||||
Payment payment = paymentRepository.getOne(
|
||||
Wrappers.lambdaQuery(Payment.class)
|
||||
.eq(Payment::getPaymentNo, callbackDTO.getPaymentNo())
|
||||
);
|
||||
|
||||
if (payment == null) {
|
||||
log.error("支付单不存在, paymentNo={}", callbackDTO.getPaymentNo());
|
||||
return Result.fail("PAYMENT_NOT_FOUND", "支付单不存在");
|
||||
}
|
||||
|
||||
// 防止重复回调
|
||||
if (!PaymentStatusEnum.UNPAID.getCode().equals(payment.getPaymentStatus())
|
||||
&& !PaymentStatusEnum.PAYING.getCode().equals(payment.getPaymentStatus())) {
|
||||
log.warn("支付单已处理, paymentNo={}, currentStatus={}",
|
||||
callbackDTO.getPaymentNo(), payment.getPaymentStatus());
|
||||
return Result.success(true);
|
||||
}
|
||||
|
||||
// 2. 查询订单
|
||||
Order order = orderRepository.getOne(
|
||||
Wrappers.lambdaQuery(Order.class)
|
||||
.eq(Order::getOrderNo, callbackDTO.getOrderNo())
|
||||
);
|
||||
|
||||
if (order == null) {
|
||||
log.error("订单不存在, orderNo={}", callbackDTO.getOrderNo());
|
||||
return Result.fail("ORDER_NOT_FOUND", "订单不存在");
|
||||
}
|
||||
|
||||
// 3. 更新支付单状态
|
||||
payment.setPaymentStatus(callbackDTO.getPaymentStatus());
|
||||
payment.setTransactionNo(callbackDTO.getTransactionId());
|
||||
payment.setPaymentTime(LocalDateTime.parse(callbackDTO.getPaymentTime(), FORMATTER));
|
||||
payment.setUpdateTime(LocalDateTime.now());
|
||||
paymentRepository.updateById(payment);
|
||||
|
||||
// 4. 根据支付结果处理
|
||||
if (PaymentStatusEnum.PAID.getCode().equals(callbackDTO.getPaymentStatus())) {
|
||||
// 支付成功
|
||||
handlePaymentSuccess(order, payment, callbackDTO);
|
||||
} else if (PaymentStatusEnum.FAILED.getCode().equals(callbackDTO.getPaymentStatus())) {
|
||||
// 支付失败
|
||||
handlePaymentFailed(order);
|
||||
}
|
||||
|
||||
log.info("支付回调处理成功, paymentNo={}, status={}",
|
||||
callbackDTO.getPaymentNo(), callbackDTO.getPaymentStatus());
|
||||
|
||||
return Result.success(true);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("处理支付回调失败, paymentNo={}", callbackDTO.getPaymentNo(), e);
|
||||
return Result.fail("PAYMENT_CALLBACK_ERROR", "处理支付回调失败:" + e.getMessage());
|
||||
// 1. 查询支付单
|
||||
Payment payment = paymentRepository.getOne(
|
||||
Wrappers.lambdaQuery(Payment.class)
|
||||
.eq(Payment::getPaymentNo, callbackDTO.getPaymentNo())
|
||||
);
|
||||
|
||||
if (payment == null) {
|
||||
throw new BizException("PAYMENT_NOT_FOUND", "支付单不存在");
|
||||
}
|
||||
|
||||
// 防止重复回调
|
||||
if (!PaymentStatusEnum.UNPAID.getCode().equals(payment.getPaymentStatus())
|
||||
&& !PaymentStatusEnum.PAYING.getCode().equals(payment.getPaymentStatus())) {
|
||||
LogUtil.warn("支付单已处理, paymentNo={}, currentStatus={}",
|
||||
callbackDTO.getPaymentNo(), payment.getPaymentStatus());
|
||||
return Result.success(true);
|
||||
}
|
||||
|
||||
// 2. 查询订单
|
||||
Order order = orderRepository.getOne(
|
||||
Wrappers.lambdaQuery(Order.class)
|
||||
.eq(Order::getOrderNo, callbackDTO.getOrderNo())
|
||||
);
|
||||
|
||||
if (order == null) {
|
||||
throw new BizException("ORDER_NOT_FOUND", "订单不存在");
|
||||
}
|
||||
|
||||
// 3. 更新支付单状态
|
||||
payment.setPaymentStatus(callbackDTO.getPaymentStatus());
|
||||
payment.setTransactionNo(callbackDTO.getTransactionId());
|
||||
payment.setPaymentTime(LocalDateTime.parse(callbackDTO.getPaymentTime(), FORMATTER));
|
||||
payment.setUpdateTime(LocalDateTime.now());
|
||||
paymentRepository.updateById(payment);
|
||||
|
||||
// 4. 根据支付结果处理
|
||||
if (PaymentStatusEnum.PAID.getCode().equals(callbackDTO.getPaymentStatus())) {
|
||||
// 支付成功
|
||||
handlePaymentSuccess(order, payment, callbackDTO);
|
||||
} else if (PaymentStatusEnum.FAILED.getCode().equals(callbackDTO.getPaymentStatus())) {
|
||||
// 支付失败
|
||||
handlePaymentFailed(order);
|
||||
}
|
||||
|
||||
LogUtil.info("支付回调处理成功, paymentNo={}, status={}",
|
||||
callbackDTO.getPaymentNo(), callbackDTO.getPaymentStatus());
|
||||
|
||||
return Result.success(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,14 +121,13 @@ public class PaymentServiceImpl implements PaymentService {
|
||||
|
||||
Result<Boolean> deductResult = routeService.deductInventory(inventoryDTO);
|
||||
if (!deductResult.isSuccess()) {
|
||||
log.error("扣减库存失败, orderNo={}", order.getOrderNo());
|
||||
throw new RuntimeException("扣减库存失败:" + deductResult.getErrorDesc());
|
||||
throw new BizException("INVENTORY_DEDUCT_FAILED", "扣减库存失败:" + deductResult.getErrorDesc());
|
||||
}
|
||||
|
||||
// 3. 发送支付成功消息到MQ
|
||||
sendPaymentSuccessMessage(order, payment, callbackDTO);
|
||||
|
||||
log.info("支付成功处理完成, orderNo={}, paymentNo={}", order.getOrderNo(), payment.getPaymentNo());
|
||||
LogUtil.info("支付成功处理完成, orderNo={}, paymentNo={}", order.getOrderNo(), payment.getPaymentNo());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,10 +149,10 @@ public class PaymentServiceImpl implements PaymentService {
|
||||
|
||||
Result<Boolean> releaseResult = routeService.releaseInventory(inventoryDTO);
|
||||
if (!releaseResult.isSuccess()) {
|
||||
log.error("释放库存失败, orderNo={}", order.getOrderNo());
|
||||
LogUtil.error("释放库存失败, orderNo={}", order.getOrderNo());
|
||||
}
|
||||
|
||||
log.info("支付失败处理完成, orderNo={}", order.getOrderNo());
|
||||
LogUtil.info("支付失败处理完成, orderNo={}", order.getOrderNo());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,7 +175,6 @@ public class PaymentServiceImpl implements PaymentService {
|
||||
String destination = MQConstant.PAYMENT_SUCCESS_TOPIC + ":" + MQConstant.PAYMENT_SUCCESS_TAG;
|
||||
rocketMQTemplate.syncSend(destination, message);
|
||||
|
||||
log.info("发送支付成功消息, orderNo={}, message={}", order.getOrderNo(), JSONUtil.toJsonStr(message));
|
||||
LogUtil.info("发送支付成功消息, orderNo={}, message={}", order.getOrderNo(), JSONUtil.toJsonStr(message));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user