diff --git a/src/main/java/com/example/demo/RabbitMQ/CashCollectionAspect.java b/src/main/java/com/example/demo/RabbitMQ/CashCollectionAspect.java new file mode 100644 index 0000000..c08aa81 --- /dev/null +++ b/src/main/java/com/example/demo/RabbitMQ/CashCollectionAspect.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.DTO.MessageDTO; +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 CashCollectionAspect + * @description: + * @author: huangqizhen + * @create: 2025−11-14 19:10 + * @Version 1.0 + **/ +@Aspect +@Component +@Slf4j +public class CashCollectionAspect { + @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 + MessageDTO messageDTO = new MessageDTO(); + messageDTO.setJwcode(Integer.valueOf(username)); + messageDTO.setName(name); + messageDTO.setTitle(action); + messageDTO.setDesc(username+"有一条消息需要处理"); +// operationLogMapper.insertMessage(messageDTO); + + // ✅ 发送消息到 RabbitMQ(不等待) + try { + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_COLLECTION_EXCHANGE, "cash.collection.save", messageDTO); + log.info("📩 日志消息已发送到 RabbitMQ: {}", action); + } catch (Exception e) { + log.error("发送日志消息到 RabbitMQ 失败", e); + } + log.info("✅ AOP 拦截完成: {} 执行 [{}] 耗时 {}ms", username, action, duration); + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/RabbitMQ/CashCollectionConsumer.java b/src/main/java/com/example/demo/RabbitMQ/CashCollectionConsumer.java index 40e5e44..5e11d1e 100644 --- a/src/main/java/com/example/demo/RabbitMQ/CashCollectionConsumer.java +++ b/src/main/java/com/example/demo/RabbitMQ/CashCollectionConsumer.java @@ -1,9 +1,15 @@ package com.example.demo.RabbitMQ; import com.example.demo.config.RabbitMQConfig; +import com.example.demo.domain.DTO.MessageDTO; +import com.example.demo.domain.DTO.OperationLogDTO; +import com.example.demo.domain.entity.OperationLog; import com.example.demo.domain.vo.cash.CashCollectionMessage; +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; /** @@ -13,64 +19,17 @@ import org.springframework.stereotype.Component; @Component @Slf4j public class CashCollectionConsumer { + @Autowired + private OperationLogMapper operationLogMapper; - /** - * 处理收款订单创建消息 - * 当有新的收款订单创建时,该方法会被调用 - * - * @param message 收款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.COLLECTION_CREATED_QUEUE) - public void handleCollectionCreated(CashCollectionMessage message) { - log.info("收款订单创建通知: 订单号={}, 状态={}, 提交人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getSubmitterId(), message.getMessage()); - } - - /** - * 处理收款订单审核通过消息 - * 当收款订单审核通过时,该方法会被调用 - * - * @param message 收款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.COLLECTION_AUDITED_QUEUE) - public void handleCollectionAudited(CashCollectionMessage message) { - log.info("收款订单审核通过通知: 订单号={}, 状态={}, 审核人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getAuditId(), message.getMessage()); - } - - /** - * 处理收款订单审核驳回消息 - * 当收款订单被审核驳回时,该方法会被调用 - * - * @param message 收款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.COLLECTION_REJECTED_QUEUE) - public void handleCollectionRejected(CashCollectionMessage message) { - log.info("收款订单审核驳回通知: 订单号={}, 状态={}, 审核人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getAuditId(), message.getMessage()); - } - - /** - * 处理收款订单完成消息 - * 当收款订单流程全部完成时,该方法会被调用 - * - * @param message 收款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.COLLECTION_COMPLETED_QUEUE) - public void handleCollectionCompleted(CashCollectionMessage message) { - log.info("收款订单完成通知: 订单号={}, 状态={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getMessage()); - } + @RabbitListener(queues = RabbitMQConfig.CASH_COLLECTION_QUEUE) + public void consumeLog(Messages messages) { + try { + operationLogMapper.insertMessage(messages); - /** - * 处理收款订单撤回消息 - * 当收款订单被撤回时,该方法会被调用 - * - * @param message 收款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.COLLECTION_CANCELLED_QUEUE) - public void handleCollectionCancelled(CashCollectionMessage message) { - log.info("收款订单撤回通知: 订单号={}, 状态={}, 提交人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getSubmitterId(), message.getMessage()); + } catch (Exception e) { + log.error("持久化日志失败", e); + // 可以重试或记录到文件 + } } } diff --git a/src/main/java/com/example/demo/RabbitMQ/CashRefundAspect.java b/src/main/java/com/example/demo/RabbitMQ/CashRefundAspect.java new file mode 100644 index 0000000..1e67585 --- /dev/null +++ b/src/main/java/com/example/demo/RabbitMQ/CashRefundAspect.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.DTO.MessageDTO; +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 CashRefundAspect + * @description: + * @author: huangqizhen + * @create: 2025−11-14 19:10 + * @Version 1.0 + **/ +@Aspect +@Component +@Slf4j +public class CashRefundAspect { + @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 + MessageDTO messageDTO = new MessageDTO(); + messageDTO.setJwcode(Integer.valueOf(username)); + messageDTO.setName(name); + messageDTO.setTitle(action); + messageDTO.setDesc(username+"有一条消息需要处理"); +// operationLogMapper.insertMessage(messageDTO); + + // ✅ 发送消息到 RabbitMQ(不等待) + try { + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_COLLECTION_EXCHANGE, "cash.collection.save", messageDTO); + log.info("📩 日志消息已发送到 RabbitMQ: {}", action); + } catch (Exception e) { + log.error("发送日志消息到 RabbitMQ 失败", e); + } + log.info("✅ AOP 拦截完成: {} 执行 [{}] 耗时 {}ms", username, action, duration); + return result; + } + +} diff --git a/src/main/java/com/example/demo/RabbitMQ/CashRefundConsumer.java b/src/main/java/com/example/demo/RabbitMQ/CashRefundConsumer.java index 09a8d77..0d82406 100644 --- a/src/main/java/com/example/demo/RabbitMQ/CashRefundConsumer.java +++ b/src/main/java/com/example/demo/RabbitMQ/CashRefundConsumer.java @@ -1,9 +1,14 @@ package com.example.demo.RabbitMQ; import com.example.demo.config.RabbitMQConfig; +import com.example.demo.domain.DTO.OperationLogDTO; +import com.example.demo.domain.entity.OperationLog; import com.example.demo.domain.vo.cash.CashRefundMessage; +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; /** @@ -13,64 +18,17 @@ import org.springframework.stereotype.Component; @Component @Slf4j public class CashRefundConsumer { + @Autowired + private OperationLogMapper operationLogMapper; - /** - * 处理退款订单创建消息 - * 当有新的退款订单创建时,该方法会被调用 - * - * @param message 退款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.REFUND_CREATED_QUEUE) - public void handleRefundCreated(CashRefundMessage message) { - log.info("退款订单创建通知: 订单号={}, 状态={}, 提交人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getSubmitterId(), message.getMessage()); - } - - /** - * 处理退款订单审核通过消息 - * 当退款订单审核通过时,该方法会被调用 - * - * @param message 退款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.REFUND_REVIEWED_QUEUE) - public void handleRefundReviewed(CashRefundMessage message) { - log.info("退款订单审核通过通知: 订单号={}, 状态={}, 审核人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getAuditId(), message.getMessage()); - } - - /** - * 处理退款订单审核驳回消息 - * 当退款订单被审核驳回时,该方法会被调用 - * - * @param message 退款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.REFUND_REJECTED_QUEUE) - public void handleRefundRejected(CashRefundMessage message) { - log.info("退款订单审核驳回通知: 订单号={}, 状态={}, 审核人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getAuditId(), message.getMessage()); - } - - /** - * 处理退款订单执行消息 - * 当退款订单被执行时,该方法会被调用 - * - * @param message 退款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.REFUND_EXECUTED_QUEUE) - public void handleRefundExecuted(CashRefundMessage message) { - log.info("退款订单执行通知: 订单号={}, 状态={}, 执行人={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getExecutorId(), message.getMessage()); - } + @RabbitListener(queues = RabbitMQConfig.CASH_REFUND_QUEUE) + public void consumeLog(Messages messages) { + try { + operationLogMapper.insertMessage(messages); - /** - * 处理退款订单完成消息 - * 当退款订单流程全部完成时,该方法会被调用 - * - * @param message 退款订单消息对象 - */ - @RabbitListener(queues = RabbitMQConfig.REFUND_COMPLETED_QUEUE) - public void handleRefundCompleted(CashRefundMessage message) { - log.info("退款订单完成通知: 订单号={}, 状态={}, 消息={}", - message.getOrderCode(), message.getStatus(), message.getMessage()); + } catch (Exception e) { + log.error("持久化日志失败", e); + // 可以重试或记录到文件 + } } } diff --git a/src/main/java/com/example/demo/config/RabbitMQConfig.java b/src/main/java/com/example/demo/config/RabbitMQConfig.java index 8caa0b7..ffa9c72 100644 --- a/src/main/java/com/example/demo/config/RabbitMQConfig.java +++ b/src/main/java/com/example/demo/config/RabbitMQConfig.java @@ -11,32 +11,16 @@ import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -/** - * RabbitMQ配置类 - * 配置消息队列、交换机以及它们之间的绑定关系 - */ + @Configuration public class RabbitMQConfig { public static final String LOG_QUEUE = "operation_log_queue"; public static final String LOG_EXCHANGE = "operation_log_exchange"; - - // 收款流程相关队列和交换机常量定义 + public static final String CASH_COLLECTION_QUEUE = "cash_collection_queue"; public static final String CASH_COLLECTION_EXCHANGE = "cash_collection_exchange"; - public static final String COLLECTION_CREATED_QUEUE = "collection_created_queue"; - public static final String COLLECTION_AUDITED_QUEUE = "collection_audited_queue"; - public static final String COLLECTION_COMPLETED_QUEUE = "collection_completed_queue"; - public static final String COLLECTION_CANCELLED_QUEUE = "collection_cancelled_queue"; - public static final String COLLECTION_REJECTED_QUEUE = "collection_rejected_queue"; - - // 退款流程相关队列和交换机常量定义 + public static final String CASH_REFUND_QUEUE = "cash_collection_exchange"; public static final String CASH_REFUND_EXCHANGE = "cash_refund_exchange"; - public static final String REFUND_CREATED_QUEUE = "refund_created_queue"; - public static final String REFUND_REVIEWED_QUEUE = "refund_reviewed_queue"; - public static final String REFUND_EXECUTED_QUEUE = "refund_executed_queue"; - public static final String REFUND_COMPLETED_QUEUE = "refund_completed_queue"; - public static final String REFUND_REJECTED_QUEUE = "refund_rejected_queue"; - @Bean public Queue logQueue() { return new Queue(LOG_QUEUE, true); @@ -54,223 +38,42 @@ public class RabbitMQConfig { .with("log.*"); } - /** - * 创建收款流程交换机 - * @return TopicExchange对象 - */ - @Bean - public TopicExchange cashCollectionExchange() { - return new TopicExchange(CASH_COLLECTION_EXCHANGE); - } - - /** - * 创建收款创建队列 - * @return Queue对象 - */ + // 现金收款队列和绑定(按照操作日志的标准) @Bean - public Queue collectionCreatedQueue() { - return new Queue(COLLECTION_CREATED_QUEUE, true); + public Queue cashCollectionQueue() { + return new Queue(CASH_COLLECTION_QUEUE, true); } - /** - * 创建收款审核队列 - * @return Queue对象 - */ @Bean - public Queue collectionAuditedQueue() { - return new Queue(COLLECTION_AUDITED_QUEUE, true); - } - - /** - * 创建收款完成队列 - * @return Queue对象 - */ - @Bean - public Queue collectionCompletedQueue() { - return new Queue(COLLECTION_COMPLETED_QUEUE, true); + public TopicExchange cashCollectionExchange() { + return new TopicExchange(CASH_COLLECTION_EXCHANGE); } - /** - * 创建收款取消队列 - * @return Queue对象 - */ @Bean - public Queue collectionCancelledQueue() { - return new Queue(COLLECTION_CANCELLED_QUEUE, true); + public Binding cashCollectionBinding() { + return BindingBuilder.bind(cashCollectionQueue()) + .to(cashCollectionExchange()) + .with("cash.collection.*"); } - /** - * 创建收款拒绝队列 - * @return Queue对象 - */ + // 现金退款队列和绑定(按照操作日志的标准) @Bean - public Queue collectionRejectedQueue() { - return new Queue(COLLECTION_REJECTED_QUEUE, true); + public Queue cashRefundQueue() { + return new Queue(CASH_REFUND_QUEUE, true); } - /** - * 创建退款流程交换机 - * @return TopicExchange对象 - */ @Bean public TopicExchange cashRefundExchange() { return new TopicExchange(CASH_REFUND_EXCHANGE); } - /** - * 创建退款创建队列 - * @return Queue对象 - */ @Bean - public Queue refundCreatedQueue() { - return new Queue(REFUND_CREATED_QUEUE, true); - } - - /** - * 创建退款审核队列 - * @return Queue对象 - */ - @Bean - public Queue refundReviewedQueue() { - return new Queue(REFUND_REVIEWED_QUEUE, true); - } - - /** - * 创建退款执行队列 - * @return Queue对象 - */ - @Bean - public Queue refundExecutedQueue() { - return new Queue(REFUND_EXECUTED_QUEUE, true); - } - - /** - * 创建退款完成队列 - * @return Queue对象 - */ - @Bean - public Queue refundCompletedQueue() { - return new Queue(REFUND_COMPLETED_QUEUE, true); - } - - /** - * 创建退款拒绝队列 - * @return Queue对象 - */ - @Bean - public Queue refundRejectedQueue() { - return new Queue(REFUND_REJECTED_QUEUE, true); - } - - /** - * 绑定收款创建队列到收款交换机 - * @return Binding对象 - */ - @Bean - public Binding collectionCreatedBinding() { - return BindingBuilder.bind(collectionCreatedQueue()) - .to(cashCollectionExchange()) - .with("collection.created"); - } - - /** - * 绑定收款审核队列到收款交换机 - * @return Binding对象 - */ - @Bean - public Binding collectionAuditedBinding() { - return BindingBuilder.bind(collectionAuditedQueue()) - .to(cashCollectionExchange()) - .with("collection.audited"); - } - - /** - * 绑定收款完成队列到收款交换机 - * @return Binding对象 - */ - @Bean - public Binding collectionCompletedBinding() { - return BindingBuilder.bind(collectionCompletedQueue()) - .to(cashCollectionExchange()) - .with("collection.completed"); - } - - /** - * 绑定收款取消队列到收款交换机 - * @return Binding对象 - */ - @Bean - public Binding collectionCancelledBinding() { - return BindingBuilder.bind(collectionCancelledQueue()) - .to(cashCollectionExchange()) - .with("collection.cancelled"); - } - - /** - * 绑定收款拒绝队列到收款交换机 - * @return Binding对象 - */ - @Bean - public Binding collectionRejectedBinding() { - return BindingBuilder.bind(collectionRejectedQueue()) - .to(cashCollectionExchange()) - .with("collection.rejected"); - } - - /** - * 绑定退款创建队列到退款交换机 - * @return Binding对象 - */ - @Bean - public Binding refundCreatedBinding() { - return BindingBuilder.bind(refundCreatedQueue()) - .to(cashRefundExchange()) - .with("refund.created"); - } - - /** - * 绑定退款审核队列到退款交换机 - * @return Binding对象 - */ - @Bean - public Binding refundReviewedBinding() { - return BindingBuilder.bind(refundReviewedQueue()) - .to(cashRefundExchange()) - .with("refund.reviewed"); - } - - /** - * 绑定退款执行队列到退款交换机 - * @return Binding对象 - */ - @Bean - public Binding refundExecutedBinding() { - return BindingBuilder.bind(refundExecutedQueue()) - .to(cashRefundExchange()) - .with("refund.executed"); - } - - /** - * 绑定退款完成队列到退款交换机 - * @return Binding对象 - */ - @Bean - public Binding refundCompletedBinding() { - return BindingBuilder.bind(refundCompletedQueue()) + public Binding cashRefundBinding() { + return BindingBuilder.bind(cashRefundQueue()) .to(cashRefundExchange()) - .with("refund.completed"); + .with("cash.refund.*"); } - /** - * 绑定退款拒绝队列到退款交换机 - * @return Binding对象 - */ - @Bean - public Binding refundRejectedBinding() { - return BindingBuilder.bind(refundRejectedQueue()) - .to(cashRefundExchange()) - .with("refund.rejected"); - } @Bean public MessageConverter messageConverter() { diff --git a/src/main/java/com/example/demo/config/interfac/Message.java b/src/main/java/com/example/demo/config/interfac/Message.java new file mode 100644 index 0000000..d7eb603 --- /dev/null +++ b/src/main/java/com/example/demo/config/interfac/Message.java @@ -0,0 +1,18 @@ +package com.example.demo.config.interfac; + +import java.lang.annotation.*; + +/** + * @program: GOLD + * @ClassName Message + * @description: + * @author: huangqizhen + * @create: 2025−11-14 19:12 + * @Version 1.0 + **/ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Message { + String value() default ""; +} diff --git a/src/main/java/com/example/demo/controller/cash/CashRefundController.java b/src/main/java/com/example/demo/controller/cash/CashRefundController.java index bced193..37462b4 100644 --- a/src/main/java/com/example/demo/controller/cash/CashRefundController.java +++ b/src/main/java/com/example/demo/controller/cash/CashRefundController.java @@ -98,6 +98,7 @@ public class CashRefundController { */ @PostMapping("/add") public Result add(@RequestBody CashRecordRefund cashRecordRefund) throws Exception { + cashRecordRefund.setStatus(10); try { return Result.success(refundService.add(cashRecordRefund)); } catch (Exception e) { @@ -213,6 +214,7 @@ public class CashRefundController { */ @PostMapping("/addOnline") public Result addOnline(@RequestBody CashRecordRefund cashRecordRefund){ + cashRecordRefund.setStatus(20); try { return Result.success(refundService.add(cashRecordRefund)); } catch (Exception e) { diff --git a/src/main/java/com/example/demo/controller/cash/MessageController.java b/src/main/java/com/example/demo/controller/cash/MessageController.java new file mode 100644 index 0000000..e83ff91 --- /dev/null +++ b/src/main/java/com/example/demo/controller/cash/MessageController.java @@ -0,0 +1,67 @@ +package com.example.demo.controller.cash; + +import com.example.demo.Util.JWTUtil; +import com.example.demo.domain.DTO.IdRequest; +import com.example.demo.domain.entity.Admin; +import com.example.demo.domain.vo.coin.Result; +import com.example.demo.service.cash.MessageService; +import com.example.demo.service.coin.MarketService; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; + + +import java.util.Arrays; +import java.util.List; + +/** + * @program: GOLD + * @ClassName MessageController + * @description: + * @author: huangqizhen + * @create: 2025−11-14 22:12 + * @Version 1.0 + **/ +@RestController +@RequestMapping("/getMessage") +@RequiredArgsConstructor +@Slf4j +@CrossOrigin +public class MessageController { + @Autowired + private MessageService messageService; + @Autowired + private MarketService marketService; + @PostMapping + public Result getMessage() throws Exception { + HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + String token = request.getHeader("token"); + +// 解析 token 获取用户信息 + Admin admin = (Admin) JWTUtil.getUserDetailsList(String.valueOf(token), Admin.class); + List userMarkets = Arrays.asList(StringUtils.split(admin.getMarkets(), ",")); + List markets = marketService.getMarketIds(userMarkets); + +// 权限校验逻辑 + if (markets.contains("9") || markets.contains("9999")) { + markets=null; + } + return Result.success(messageService.getMessage(markets)); + } + @PostMapping("/update") + public Result update(@RequestBody IdRequest idRequest) throws Exception { + try { + Integer id = idRequest.getId(); + messageService.update(id); + return Result.success(); + } + catch (Exception e) { + return Result.error("更新失败"); + } + } +} diff --git a/src/main/java/com/example/demo/domain/DTO/IdRequest.java b/src/main/java/com/example/demo/domain/DTO/IdRequest.java new file mode 100644 index 0000000..224f0bc --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/IdRequest.java @@ -0,0 +1,14 @@ +package com.example.demo.domain.DTO; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; + +// 1. 定义一个极简 DTO(可复用) +@Data +@NoArgsConstructor +@AllArgsConstructor +public class IdRequest { + private Integer id; +} \ No newline at end of file diff --git a/src/main/java/com/example/demo/domain/DTO/MessageDTO.java b/src/main/java/com/example/demo/domain/DTO/MessageDTO.java new file mode 100644 index 0000000..1524cf0 --- /dev/null +++ b/src/main/java/com/example/demo/domain/DTO/MessageDTO.java @@ -0,0 +1,28 @@ +package com.example.demo.domain.DTO; + +import com.stripe.model.tax.Registration; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @program: GOLD + * @ClassName MessageDTO + * @description: + * @author: huangqizhen + * @create: 2025−11-14 19:15 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class MessageDTO { + private Integer id; + private Integer jwcode; + private String name; + private String title; + private String desc; + private Integer status; + private Integer type; + private Integer typeId; +} diff --git a/src/main/java/com/example/demo/domain/vo/cash/CashRecordRefund.java b/src/main/java/com/example/demo/domain/vo/cash/CashRecordRefund.java index 7e4f6bf..0cdd8c3 100644 --- a/src/main/java/com/example/demo/domain/vo/cash/CashRecordRefund.java +++ b/src/main/java/com/example/demo/domain/vo/cash/CashRecordRefund.java @@ -23,6 +23,8 @@ public class CashRecordRefund { */ private Integer id; + private Integer originalOrderId; + /** * 精网号 */ diff --git a/src/main/java/com/example/demo/domain/vo/coin/Messages.java b/src/main/java/com/example/demo/domain/vo/coin/Messages.java new file mode 100644 index 0000000..53bb2de --- /dev/null +++ b/src/main/java/com/example/demo/domain/vo/coin/Messages.java @@ -0,0 +1,36 @@ +package com.example.demo.domain.vo.coin; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.stripe.model.tax.Registration; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * @program: GOLD + * @ClassName Messages + * @description: + * @author: huangqizhen + * @create: 2025−11-14 18:01 + * @Version 1.0 + **/ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Messages { + private Integer id;//id + private Integer jwcode;//精网号 + private String name;// 姓名 + private String title;//标题 + private String desc; + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Shanghai") + private Date czTime; // 创建时间 + private Integer status;//状态 + private Integer type; + private Integer typeId; + private Integer market; + + +} diff --git a/src/main/java/com/example/demo/mapper/cash/CashRefundMapper.java b/src/main/java/com/example/demo/mapper/cash/CashRefundMapper.java index ee5fa3a..cac7c96 100644 --- a/src/main/java/com/example/demo/mapper/cash/CashRefundMapper.java +++ b/src/main/java/com/example/demo/mapper/cash/CashRefundMapper.java @@ -36,4 +36,6 @@ public interface CashRefundMapper { List exSelect(CashRecordDTO cashRecordDTO); List getAuditBatch(Set auditIds); + //根据id查订单信息 + CashRecordDTO selectById(Integer id); } \ No newline at end of file diff --git a/src/main/java/com/example/demo/mapper/cash/MessageMapper.java b/src/main/java/com/example/demo/mapper/cash/MessageMapper.java new file mode 100644 index 0000000..2d72f29 --- /dev/null +++ b/src/main/java/com/example/demo/mapper/cash/MessageMapper.java @@ -0,0 +1,22 @@ +package com.example.demo.mapper.cash; + +import com.example.demo.domain.vo.coin.Messages; +import com.example.demo.service.cash.MessageService; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +/** + * @program: GOLD + * @ClassName MessageMapper + * @description: + * @author: huangqizhen + * @create: 2025−11-14 22:24 + * @Version 1.0 + **/ +@Mapper +public interface MessageMapper { + List getMessage(List markets); + + void update(Integer id); +} diff --git a/src/main/java/com/example/demo/mapper/coin/OperationLogMapper.java b/src/main/java/com/example/demo/mapper/coin/OperationLogMapper.java index 099908b..5f55848 100644 --- a/src/main/java/com/example/demo/mapper/coin/OperationLogMapper.java +++ b/src/main/java/com/example/demo/mapper/coin/OperationLogMapper.java @@ -1,8 +1,8 @@ package com.example.demo.mapper.coin;// com.example.demo.mapper.OperationLogMapper.java +import com.example.demo.domain.DTO.MessageDTO; import com.example.demo.domain.entity.OperationLog; -import org.apache.ibatis.annotations.Insert; -import org.apache.ibatis.annotations.Mapper; -import org.apache.ibatis.annotations.Param; +import com.example.demo.domain.vo.coin.Messages; +import org.apache.ibatis.annotations.*; @Mapper public interface OperationLogMapper { @@ -10,4 +10,13 @@ public interface OperationLogMapper { @Insert("INSERT INTO operation_log (user_id, username, action, ip, method, args, create_time) " + "VALUES (#{userId}, #{username}, #{action}, #{ip}, #{method}, #{args}, NOW())") void insertLog(OperationLog log); + @Insert("INSERT INTO message (jwcode, name, title, `desc`, status,type,type_id,market) "+" VALUES (#{jwcode}, #{name}, #{title}, #{desc},#{status},#{type},#{typeId},#{market})") + void insertMessage(Messages message); + @Options( + useGeneratedKeys = true, // ✅ 告诉 MyBatis 使用数据库生成的主键 + keyProperty = "id", // ✅ 将生成的主键值 set 到 messageDTO.id 字段 + keyColumn = "id" // ✅ 可选:指定数据库列名(默认就是 id,一般可省略) + ) + @Select("SELECT * FROM message WHERE id = #{id}") + Messages selectMessageById(@Param("id") Integer id); } \ No newline at end of file diff --git a/src/main/java/com/example/demo/service/cash/MessageService.java b/src/main/java/com/example/demo/service/cash/MessageService.java new file mode 100644 index 0000000..6194b8a --- /dev/null +++ b/src/main/java/com/example/demo/service/cash/MessageService.java @@ -0,0 +1,21 @@ +package com.example.demo.service.cash; + +import com.example.demo.domain.vo.coin.Messages; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * @program: GOLD + * @ClassName MessageService + * @description: + * @author: huangqizhen + * @create: 2025−11-14 22:13 + * @Version 1.0 + **/ +@Service +public interface MessageService { + List getMessage(List markets); + + void update(Integer id) throws Exception; +} diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java index 0a07376..fbea6bb 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/cash/CashCollectionServiceImpl.java @@ -6,6 +6,7 @@ import com.example.demo.domain.entity.*; import com.example.demo.domain.vo.cash.CashCollection; import com.example.demo.domain.vo.cash.CashCollectionMessage; import com.example.demo.domain.vo.coin.GoldUser; +import com.example.demo.domain.vo.coin.Messages; import com.example.demo.domain.vo.coin.Result; import com.example.demo.mapper.cash.CashCollectionMapper; import com.example.demo.mapper.coin.MarketMapper; @@ -127,21 +128,16 @@ public class CashCollectionServiceImpl implements CashCollectionService { //插入新收款订单 cashCollectionMapper.add(cashRecord); // 发送收款创建消息 - CashCollectionMessage message = new CashCollectionMessage(); - message.setId(cashRecord.getId()); - message.setOrderCode(cashRecord.getOrderCode()); + Messages message = new Messages(); + message.setJwcode(cashRecord.getJwcode()); + message.setName(cashRecord.getName()); message.setStatus(cashRecord.getStatus()); - message.setStatusDescription("线下财务待审核"); - message.setMessage("收款订单已创建"); - message.setSubmitterId(cashRecord.getSubmitterId()); - // 可以通过 submitterId 查询提交人姓名 - message.setTimestamp(LocalDateTime.now()); - - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_COLLECTION_EXCHANGE, - "collection.created", - message - ); + message.setDesc(cashRecord.getJwcode()+"用户有条退款订单需审核"); + message.setTitle("现金退款--新增退款"); + message.setType(1); + message.setTypeId(cashRecord.getId()); + message.setMarket(Integer.valueOf(cashRecord.getMarket())); + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_COLLECTION_EXCHANGE, "cash.collection.save", message); return "添加成功"; } @@ -157,24 +153,7 @@ public class CashCollectionServiceImpl implements CashCollectionService { } //修改订单状态 int rows = cashCollectionMapper.updateStatus(orderCode, 5); - if (rows > 0) { - // 发送收款撤回消息 - CashCollectionMessage message = new CashCollectionMessage(); - message.setId(cashRecord.getId()); - message.setOrderCode(cashRecord.getOrderCode()); - message.setStatus(5); - message.setStatusDescription("手动撤回待编辑提交"); - message.setMessage("收款订单已撤回"); - message.setSubmitterId(cashRecord.getSubmitterId()); - message.setAuditId(cashRecord.getAuditId()); - message.setTimestamp(LocalDateTime.now()); - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_COLLECTION_EXCHANGE, - "collection.cancelled", - message - ); - } return rows > 0 ? "撤回成功" : "撤回失败"; } diff --git a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java index d1f0578..0cbf58e 100644 --- a/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java +++ b/src/main/java/com/example/demo/serviceImpl/cash/CashRefundServiceImpl.java @@ -8,10 +8,12 @@ import com.example.demo.domain.vo.cash.CashRecordDTO; import com.example.demo.domain.vo.cash.CashRecordDone; import com.example.demo.domain.vo.cash.CashRecordRefund; import com.example.demo.domain.vo.cash.CashRefundMessage; +import com.example.demo.domain.vo.coin.Messages; import com.example.demo.domain.vo.coin.Result; import com.example.demo.mapper.cash.CashRefundMapper; import com.example.demo.mapper.coin.AuditMapper; import com.example.demo.mapper.coin.MarketMapper; +import com.example.demo.mapper.coin.OperationLogMapper; import com.example.demo.mapper.coin.RefundMapper; import com.example.demo.service.cash.RefundService; import com.github.pagehelper.PageHelper; @@ -20,6 +22,7 @@ import jakarta.servlet.http.HttpServletRequest; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.math.BigDecimal; import java.time.LocalDate; @@ -39,7 +42,7 @@ import static org.apache.commons.lang3.StringUtils.substring; * @Version 1.0 **/ @Service - +@Transactional public class CashRefundServiceImpl implements RefundService { @Autowired @@ -52,6 +55,8 @@ public class CashRefundServiceImpl implements RefundService { private MarketMapper marketMapper; @Autowired private RabbitTemplate rabbitTemplate; + @Autowired + private OperationLogMapper operationLogMapper; @Override public PageInfo select(Integer pageNum, Integer pageSize, CashRecordDTO cashRecordDTO) { @@ -78,7 +83,7 @@ public class CashRefundServiceImpl implements RefundService { cashRefundMapper.addAudit(cashRecordDonetwo); cashRecordRefund.setAuditId(cashRecordDonetwo.getId()); - cashRecordRefund.setStatus(10); +// cashRecordRefund.setStatus(10); //生成订单号后半部分 String orderNumber = cashRecordRefund.getOrderCode(); //构建订单信息 @@ -93,20 +98,16 @@ public class CashRefundServiceImpl implements RefundService { else return Result.error("提交失败").getCode(); // 发送退款创建消息 - CashRefundMessage message = new CashRefundMessage(); - message.setId(cashRecordRefund.getId()); - message.setOrderCode(cashRecordRefund.getOrderCode()); - message.setStatus(10); - message.setStatusDescription("地区财务待审核"); - message.setMessage("退款订单已创建"); - message.setSubmitterId(cashRecordRefund.getSubmitterId()); - message.setTimestamp(LocalDateTime.now()); - - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_REFUND_EXCHANGE, - "refund.created", - message - ); + Messages message = new Messages(); + message.setJwcode(cashRecordRefund.getJwcode()); + message.setName(cashRecordRefund.getName()); + message.setStatus(cashRecordRefund.getStatus()); + message.setDesc(cashRecordRefund.getJwcode()+"用户有条退款订单需审核"); + message.setTitle("现金退款--新增退款"); + message.setType(1); + message.setTypeId(cashRecordRefund.getId()); + message.setMarket(Integer.valueOf(cashRecordRefund.getMarket())); + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_REFUND_EXCHANGE, "cash.refund.save", message); return Result.success("提交成功").getCode(); } @@ -155,32 +156,21 @@ public class CashRefundServiceImpl implements RefundService { } cashRefundMapper.updateAudit(cashRecordDone); int result = cashRefundMapper.review(cashRecordDone); - + CashRecordDTO cashRecordDTO = cashRefundMapper.selectById(cashRecordDone.getId()); if (result > 0) { // 发送审核消息 - CashRefundMessage message = new CashRefundMessage(); - message.setId(cashRecordDone.getId()); - message.setOrderCode(cashRecordDone.getOrderCode()); - message.setStatus(cashRecordDone.getStatus()); - message.setStatusDescription(getStatusDescription(cashRecordDone.getStatus())); - message.setMessage("退款订单已审核"); - message.setSubmitterId(cashRecordDone.getSubmitterId()); - message.setAuditId(cashRecordDone.getAuditId()); - // 可以通过 auditId 查询审核人姓名 - message.setTimestamp(LocalDateTime.now()); + Messages message = new Messages(); + message.setJwcode(cashRecordDTO.getJwcode()); + message.setName(cashRecordDTO.getName()); + message.setStatus(cashRecordDTO.getStatus()); + message.setDesc(cashRecordDTO.getJwcode()+"用户有条退款订单需审核"); + message.setTitle("现金退款--新增退款"); + message.setType(1); + message.setTypeId(cashRecordDTO.getId()); + message.setMarket(cashRecordDTO.getMarket()); - if (cashRecordDone.getStatus() == 12 || cashRecordDone.getStatus() == 22) { - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_REFUND_EXCHANGE, - "refund.rejected", - message - ); - } else { - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_REFUND_EXCHANGE, - "refund.reviewed", - message - ); + if (cashRecordDTO.getStatus() != 12 || cashRecordDTO.getStatus() != 22) { + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_REFUND_EXCHANGE, "cash.refund.save", message); } } @@ -209,25 +199,7 @@ public class CashRefundServiceImpl implements RefundService { throw new RuntimeException("未输入退款金额"); } int result = cashRefundMapper.executor(cashRecordDone); - if (result > 0) { - // 发送执行消息 - CashRefundMessage message = new CashRefundMessage(); - message.setId(cashRecordDone.getId()); - message.setOrderCode(cashRecordDone.getOrderCode()); - message.setStatus(cashRecordDone.getStatus()); - message.setStatusDescription(getStatusDescription(cashRecordDone.getStatus())); - message.setMessage("退款订单已执行"); - message.setSubmitterId(cashRecordDone.getSubmitterId()); - message.setExecutorId(cashRecordDone.getExecutor()); - // 可以通过 executorId 查询执行人姓名 - message.setTimestamp(LocalDateTime.now()); - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_REFUND_EXCHANGE, - "refund.executed", - message - ); - } return (result > 0 ? Result.success("提交成功") : Result.error("提交失败")).getCode(); } @@ -299,23 +271,22 @@ public class CashRefundServiceImpl implements RefundService { cashRefundMapper.updateAudit(cashRecordDone); int result = cashRefundMapper.review(cashRecordDone); + CashRecordDTO cashRecordDTO = cashRefundMapper.selectById(cashRecordDone.getId()); if (result > 0) { - // 发送最终审核消息 - CashRefundMessage message = new CashRefundMessage(); - message.setId(cashRecordDone.getId()); - message.setOrderCode(cashRecordDone.getOrderCode()); - message.setStatus(cashRecordDone.getStatus()); - message.setStatusDescription(getStatusDescription(cashRecordDone.getStatus())); - message.setMessage("退款订单已完成"); - message.setSubmitterId(cashRecordDone.getSubmitterId()); - message.setAuditId(cashRecordDone.getAuditId()); - message.setTimestamp(LocalDateTime.now()); + // 发送审核消息 + Messages message = new Messages(); + message.setJwcode(cashRecordDTO.getJwcode()); + message.setName(cashRecordDTO.getName()); + message.setStatus(cashRecordDTO.getStatus()); + message.setDesc(cashRecordDTO.getJwcode()+"用户有条退款订单需审核"); + message.setTitle("现金退款--新增退款"); + message.setType(1); + message.setTypeId(cashRecordDTO.getId()); + message.setMarket(cashRecordDTO.getMarket()); - rabbitTemplate.convertAndSend( - RabbitMQConfig.CASH_REFUND_EXCHANGE, - "refund.completed", - message - ); + if (cashRecordDTO.getStatus() != 32) { + rabbitTemplate.convertAndSend(RabbitMQConfig.CASH_REFUND_EXCHANGE, "cash.refund.save", message); + } } return (result > 0 ? Result.success("提交成功") : Result.error("提交失败")).getCode(); } diff --git a/src/main/java/com/example/demo/serviceImpl/cash/MessageServiceImpl.java b/src/main/java/com/example/demo/serviceImpl/cash/MessageServiceImpl.java new file mode 100644 index 0000000..b62821c --- /dev/null +++ b/src/main/java/com/example/demo/serviceImpl/cash/MessageServiceImpl.java @@ -0,0 +1,39 @@ +package com.example.demo.serviceImpl.cash; + +import com.example.demo.domain.vo.coin.Messages; +import com.example.demo.service.cash.MessageService; +import com.example.demo.mapper.cash.MessageMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; + +/** + * @program: GOLD + * @ClassName MessageServiceImpl + * @description: + * @author: huangqizhen + * @create: 2025−11-14 22:23 + * @Version 1.0 + **/ +@Service +@Transactional +public class MessageServiceImpl implements MessageService { + @Autowired + private MessageMapper messageMapper; + @Override + public List getMessage(List markets) { + return messageMapper.getMessage(markets) ; + } + + @Override + public void update(Integer id) throws Exception { + try { + messageMapper.update(id); + } + catch (Exception e){ + throw new Exception("更新失败"); + } + } +} diff --git a/src/main/resources/cashMapper/CashRefundMapper.xml b/src/main/resources/cashMapper/CashRefundMapper.xml index 282c396..1d32ba5 100644 --- a/src/main/resources/cashMapper/CashRefundMapper.xml +++ b/src/main/resources/cashMapper/CashRefundMapper.xml @@ -1,7 +1,9 @@ - + INSERT INTO cash_record_refund ( jwcode, name, @@ -49,7 +51,7 @@ #{refundVoucher}, #{refundCurrency}, #{refundAmount}, - #{id}, + #{originalOrderId}, #{auditId}, #{status} ); @@ -393,5 +395,14 @@ + + \ No newline at end of file diff --git a/src/main/resources/cashMapper/MessageMapper.xml b/src/main/resources/cashMapper/MessageMapper.xml new file mode 100644 index 0000000..c6f1652 --- /dev/null +++ b/src/main/resources/cashMapper/MessageMapper.xml @@ -0,0 +1,23 @@ + + + + + update message + set flag=1 + where id=#{id} + + + \ No newline at end of file