8 changed files with 340 additions and 3 deletions
-
96src/main/java/com/example/demo/RabbitMQ/CoinRechargeAspect.java
-
31src/main/java/com/example/demo/RabbitMQ/CoinRechargeConsumer.java
-
97src/main/java/com/example/demo/RabbitMQ/CoinRefundAspect.java
-
31src/main/java/com/example/demo/RabbitMQ/CoinRefundConsumer.java
-
39src/main/java/com/example/demo/config/RabbitMQConfig.java
-
2src/main/java/com/example/demo/domain/vo/coin/Messages.java
-
23src/main/java/com/example/demo/serviceImpl/coin/RechargeServiceImpl.java
-
24src/main/java/com/example/demo/serviceImpl/coin/RefundServiceImpl.java
@ -0,0 +1,96 @@ |
|||||
|
package com.example.demo.RabbitMQ; |
||||
|
|
||||
|
import com.example.demo.Util.SecurityUtils; |
||||
|
import com.example.demo.config.RabbitMQConfig; |
||||
|
import com.example.demo.config.interfac.Message; |
||||
|
import com.example.demo.domain.vo.coin.Messages; |
||||
|
import com.example.demo.mapper.coin.OperationLogMapper; |
||||
|
import com.example.demo.mapper.coin.UserMapper; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.aspectj.lang.ProceedingJoinPoint; |
||||
|
import org.aspectj.lang.annotation.Around; |
||||
|
import org.aspectj.lang.annotation.Aspect; |
||||
|
import org.aspectj.lang.reflect.MethodSignature; |
||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* @program: GOLD |
||||
|
* @ClassName CoinRechargeAspect |
||||
|
* @description: 金币充值流程切面 |
||||
|
* @author: |
||||
|
* @create: |
||||
|
* @Version 1.0 |
||||
|
**/ |
||||
|
@Aspect |
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class CoinRechargeAspect { |
||||
|
@Autowired |
||||
|
private RabbitTemplate rabbitTemplate; |
||||
|
@Autowired |
||||
|
private UserMapper userMapper; |
||||
|
@Autowired |
||||
|
private OperationLogMapper operationLogMapper; |
||||
|
|
||||
|
@Around("@annotation(com.example.demo.config.interfac.Message)") |
||||
|
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
|
long startTime = System.currentTimeMillis(); |
||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
|
String methodName = signature.getName(); |
||||
|
String className = signature.getDeclaringTypeName(); |
||||
|
Object[] args = joinPoint.getArgs(); |
||||
|
|
||||
|
Message logAnnotation = signature.getMethod().getAnnotation(Message.class); |
||||
|
String action = logAnnotation.value(); |
||||
|
|
||||
|
// ✅ 使用 Spring Security 获取真实用户 |
||||
|
String username = SecurityUtils.getCurrentUsername(); |
||||
|
Integer userId = SecurityUtils.getCurrentUserId(); |
||||
|
String name = userMapper.selectUserByJwcode(Integer.valueOf(username)).getName(); |
||||
|
|
||||
|
// 添加空值检查 |
||||
|
if (userId == null) { |
||||
|
log.warn("无法获取当前用户ID,使用默认值 -1"); |
||||
|
userId = -1; // 或者使用其他默认值 |
||||
|
} |
||||
|
|
||||
|
ObjectMapper mapper = new ObjectMapper(); |
||||
|
String argsJson = "[]"; |
||||
|
try { |
||||
|
argsJson = mapper.writeValueAsString(args); |
||||
|
} catch (Exception e) { |
||||
|
argsJson = "serialize failed"; |
||||
|
} |
||||
|
|
||||
|
Object result; |
||||
|
try { |
||||
|
result = joinPoint.proceed(); |
||||
|
} catch (Exception e) { |
||||
|
log.error("方法执行异常: {}", e.getMessage()); |
||||
|
throw e; |
||||
|
} |
||||
|
|
||||
|
long duration = System.currentTimeMillis() - startTime; |
||||
|
|
||||
|
// ✅ 构造金币充值消息 DTO |
||||
|
Messages messageDTO = new Messages(); |
||||
|
messageDTO.setJwcode(Integer.valueOf(username)); |
||||
|
messageDTO.setName(name); |
||||
|
messageDTO.setTitle(action); |
||||
|
messageDTO.setDesc(username + "有一条金币充值消息需要处理"); |
||||
|
|
||||
|
// ✅ 发送消息到 RabbitMQ(不等待) |
||||
|
try { |
||||
|
rabbitTemplate.convertAndSend(RabbitMQConfig.COIN_RECHARGE_EXCHANGE, "coin.recharge.save", messageDTO); |
||||
|
log.info("📩 金币充值消息已发送到 RabbitMQ: {}", action); |
||||
|
} catch (Exception e) { |
||||
|
log.error("发送金币充值消息到 RabbitMQ 失败", e); |
||||
|
} |
||||
|
|
||||
|
log.info("✅ AOP 拦截完成: {} 执行 [{}] 耗时 {}ms", username, action, duration); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.example.demo.RabbitMQ; |
||||
|
|
||||
|
import com.example.demo.config.RabbitMQConfig; |
||||
|
import com.example.demo.domain.vo.coin.Messages; |
||||
|
import com.example.demo.mapper.coin.OperationLogMapper; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 金币充值流程消息消费者 |
||||
|
* 监听金币充值流程中各个状态变更的消息队列 |
||||
|
*/ |
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class CoinRechargeConsumer { |
||||
|
@Autowired |
||||
|
private OperationLogMapper operationLogMapper; |
||||
|
|
||||
|
@RabbitListener(queues = RabbitMQConfig.COIN_RECHARGE_QUEUE) |
||||
|
public void consumeLog(Messages messages) { |
||||
|
try { |
||||
|
operationLogMapper.insertMessage(messages); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error("持久化金币充值日志失败", e); |
||||
|
// 可以重试或记录到文件 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,97 @@ |
|||||
|
package com.example.demo.RabbitMQ; |
||||
|
|
||||
|
import com.example.demo.Util.SecurityUtils; |
||||
|
import com.example.demo.config.RabbitMQConfig; |
||||
|
import com.example.demo.config.interfac.Message; |
||||
|
import com.example.demo.domain.DTO.MessageDTO; |
||||
|
import com.example.demo.domain.vo.coin.Messages; |
||||
|
import com.example.demo.mapper.coin.OperationLogMapper; |
||||
|
import com.example.demo.mapper.coin.UserMapper; |
||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.aspectj.lang.ProceedingJoinPoint; |
||||
|
import org.aspectj.lang.annotation.Around; |
||||
|
import org.aspectj.lang.annotation.Aspect; |
||||
|
import org.aspectj.lang.reflect.MethodSignature; |
||||
|
import org.springframework.amqp.rabbit.core.RabbitTemplate; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* @program: GOLD |
||||
|
* @ClassName CoinRefundAspect |
||||
|
* @description: 金币退款流程切面 |
||||
|
* @author: wangguorui |
||||
|
* @create: |
||||
|
* @Version 1.0 |
||||
|
**/ |
||||
|
@Aspect |
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class CoinRefundAspect { |
||||
|
@Autowired |
||||
|
private RabbitTemplate rabbitTemplate; |
||||
|
@Autowired |
||||
|
private UserMapper userMapper; |
||||
|
@Autowired |
||||
|
private OperationLogMapper operationLogMapper; |
||||
|
|
||||
|
@Around("@annotation(com.example.demo.config.interfac.Message)") |
||||
|
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
|
long startTime = System.currentTimeMillis(); |
||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); |
||||
|
String methodName = signature.getName(); |
||||
|
String className = signature.getDeclaringTypeName(); |
||||
|
Object[] args = joinPoint.getArgs(); |
||||
|
|
||||
|
Message logAnnotation = signature.getMethod().getAnnotation(Message.class); |
||||
|
String action = logAnnotation.value(); |
||||
|
|
||||
|
// ✅ 使用 Spring Security 获取真实用户 |
||||
|
String username = SecurityUtils.getCurrentUsername(); |
||||
|
Integer userId = SecurityUtils.getCurrentUserId(); |
||||
|
String name = userMapper.selectUserByJwcode(Integer.valueOf(username)).getName(); |
||||
|
|
||||
|
// 添加空值检查 |
||||
|
if (userId == null) { |
||||
|
log.warn("无法获取当前用户ID,使用默认值 -1"); |
||||
|
userId = -1; // 或者使用其他默认值 |
||||
|
} |
||||
|
|
||||
|
ObjectMapper mapper = new ObjectMapper(); |
||||
|
String argsJson = "[]"; |
||||
|
try { |
||||
|
argsJson = mapper.writeValueAsString(args); |
||||
|
} catch (Exception e) { |
||||
|
argsJson = "serialize failed"; |
||||
|
} |
||||
|
|
||||
|
Object result; |
||||
|
try { |
||||
|
result = joinPoint.proceed(); |
||||
|
} catch (Exception e) { |
||||
|
log.error("方法执行异常: {}", e.getMessage()); |
||||
|
throw e; |
||||
|
} |
||||
|
|
||||
|
long duration = System.currentTimeMillis() - startTime; |
||||
|
|
||||
|
// ✅ 构造金币退款消息 DTO |
||||
|
Messages messageDTO = new Messages(); |
||||
|
messageDTO.setJwcode(Integer.valueOf(username)); |
||||
|
messageDTO.setName(name); |
||||
|
messageDTO.setTitle(action); |
||||
|
messageDTO.setDesc(username + "有一条金币退款消息需要处理"); |
||||
|
|
||||
|
// ✅ 发送消息到 RabbitMQ(不等待) |
||||
|
try { |
||||
|
rabbitTemplate.convertAndSend(RabbitMQConfig.COIN_REFUND_EXCHANGE, "coin.refund.save", messageDTO); |
||||
|
log.info("📩 金币退款消息已发送到 RabbitMQ: {}", action); |
||||
|
} catch (Exception e) { |
||||
|
log.error("发送金币退款消息到 RabbitMQ 失败", e); |
||||
|
} |
||||
|
|
||||
|
log.info("✅ AOP 拦截完成: {} 执行 [{}] 耗时 {}ms", username, action, duration); |
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
package com.example.demo.RabbitMQ; |
||||
|
|
||||
|
import com.example.demo.config.RabbitMQConfig; |
||||
|
import com.example.demo.domain.vo.coin.Messages; |
||||
|
import com.example.demo.mapper.coin.OperationLogMapper; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.amqp.rabbit.annotation.RabbitListener; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
/** |
||||
|
* 金币退款流程消息消费者 |
||||
|
* 监听金币退款流程中各个状态变更的消息队列 |
||||
|
*/ |
||||
|
@Component |
||||
|
@Slf4j |
||||
|
public class CoinRefundConsumer { |
||||
|
@Autowired |
||||
|
private OperationLogMapper operationLogMapper; |
||||
|
|
||||
|
@RabbitListener(queues = RabbitMQConfig.COIN_REFUND_QUEUE) |
||||
|
public void consumeLog(Messages messages) { |
||||
|
try { |
||||
|
operationLogMapper.insertMessage(messages); |
||||
|
|
||||
|
} catch (Exception e) { |
||||
|
log.error("持久化金币退款日志失败", e); |
||||
|
// 可以重试或记录到文件 |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue