From 4aaaa1fc6aba5d04a8ed9d27c85f3a4360cc5708 Mon Sep 17 00:00:00 2001 From: forely <1605769034@qq.com> Date: Mon, 2 Jun 2025 19:35:39 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AB=AF=E7=9A=84=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=E5=B7=A5=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../config/FeedbackRabbitMQConfig.java | 67 +++++++++++++++++++ .../controller/FeedbackTicketController.java | 51 ++++++++++++++ .../dto/FeedbackTicketBasicInfoDTO.java | 2 + .../dto/FeedbackTicketPageQueryDTO.java | 2 + .../feedback/entity/FeedbackTicket.java | 2 + .../feedback/mapper/FeedbackTicketMapper.java | 10 +++ .../mq/consumer/FeedbackMessageConsumer.java | 34 ++++++++++ .../mq/domain/DelayHandleTicketMessage.java | 2 + .../mq/producer/FeedbackMessageProducer.java | 47 +++++++++++++ .../service/FeedbackTicketService.java | 37 ++++++++++ .../impl/FeedbackTicketServiceImpl.java | 2 + 11 files changed, 256 insertions(+) create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/config/FeedbackRabbitMQConfig.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/controller/FeedbackTicketController.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketBasicInfoDTO.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketPageQueryDTO.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/entity/FeedbackTicket.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mapper/FeedbackTicketMapper.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/consumer/FeedbackMessageConsumer.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/domain/DelayHandleTicketMessage.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/producer/FeedbackMessageProducer.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/FeedbackTicketService.java create mode 100644 珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/impl/FeedbackTicketServiceImpl.java diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/config/FeedbackRabbitMQConfig.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/config/FeedbackRabbitMQConfig.java new file mode 100644 index 0000000..4c4bb71 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/config/FeedbackRabbitMQConfig.java @@ -0,0 +1,67 @@ +package com.luojia_channel.modules.feedback.config; + +import org.springframework.amqp.core.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FeedbackRabbitMQConfig { + + // 反馈工单交换机 + public static final String FEEDBACK_EXCHANGE = "feedback.exchange"; + + // 延迟队列 - 消息先进入此队列,过期后转发到死信队列 + public static final String FEEDBACK_DELAY_QUEUE = "feedback.delay.queue"; + + // 死信交换机 - 延迟队列的死信会转发到此交换机 + public static final String FEEDBACK_DLX_EXCHANGE = "feedback.dlx.exchange"; + + // 死信队列 - 最终消费者监听此队列 + public static final String FEEDBACK_DLX_QUEUE = "feedback.dlx.queue"; + + // 路由键 + public static final String FEEDBACK_ROUTING_KEY = "feedback.routing.key"; + + // 声明反馈交换机 + @Bean + DirectExchange feedbackExchange() { + return new DirectExchange(FEEDBACK_EXCHANGE, true, false); + } + + // 声明死信交换机 + @Bean + DirectExchange feedbackDlxExchange() { + return new DirectExchange(FEEDBACK_DLX_EXCHANGE, true, false); + } + + // 声明延迟队列,并绑定到死信交换机 + @Bean + Queue feedbackDelayQueue() { + return QueueBuilder.durable(FEEDBACK_DELAY_QUEUE) + .withArgument("x-dead-letter-exchange", FEEDBACK_DLX_EXCHANGE) + .withArgument("x-dead-letter-routing-key", FEEDBACK_ROUTING_KEY) + .build(); + } + + // 声明死信队列 + @Bean + Queue feedbackDlxQueue() { + return new Queue(FEEDBACK_DLX_QUEUE, true); + } + + // 绑定延迟队列到反馈交换机 + @Bean + Binding feedbackDelayBinding() { + return BindingBuilder.bind(feedbackDelayQueue()) + .to(feedbackExchange()) + .with(FEEDBACK_ROUTING_KEY); + } + + // 绑定死信队列到死信交换机 + @Bean + Binding feedbackDlxBinding() { + return BindingBuilder.bind(feedbackDlxQueue()) + .to(feedbackDlxExchange()) + .with(FEEDBACK_ROUTING_KEY); + } +} \ No newline at end of file diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/controller/FeedbackTicketController.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/controller/FeedbackTicketController.java new file mode 100644 index 0000000..86a61d2 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/controller/FeedbackTicketController.java @@ -0,0 +1,51 @@ +package com.luojia_channel.modules.feedback.controller; + +import com.luojia_channel.common.domain.Result; +import com.luojia_channel.common.domain.page.PageRequest; +import com.luojia_channel.common.domain.page.PageResponse; +import com.luojia_channel.modules.feedback.entity.FeedbackTicket; +import com.luojia_channel.modules.feedback.service.FeedbackTicketService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@RequestMapping("/feedback") +@Tag(name = "反馈工单模块", description = "反馈工单相关接口") +@RequiredArgsConstructor +public class FeedbackTicketController { + + private final FeedbackTicketService feedbackTicketService; + + @PostMapping + @Operation(summary = "创建反馈工单", description = "用户创建反馈工单") + public Result createFeedbackTicket(@RequestBody FeedbackTicket feedbackTicket) { + Long id = feedbackTicketService.createFeedbackTicket(feedbackTicket); + return Result.success(id); + } + + @PutMapping + @Operation(summary = "编辑反馈工单", description = "编辑已有的反馈工单") + public Result updateFeedbackTicket(@RequestBody FeedbackTicket feedbackTicket) { + feedbackTicketService.updateFeedbackTicket(feedbackTicket); + return Result.success(); + } + + @GetMapping("/personal") + @Operation(summary = "个人反馈工单查询", description = "查询当前用户的反馈工单") + public Result> getPersonalFeedbackTickets(@RequestParam Long userId) { + List tickets = feedbackTicketService.getPersonalFeedbackTickets(userId); + return Result.success(tickets); + } + + @GetMapping("/admin") + @Operation(summary = "管理员反馈工单分页查询", description = "管理员分页查询所有反馈工单") + public Result> getAdminFeedbackTickets(PageRequest request) { + PageResponse pageResponse = feedbackTicketService.getAdminFeedbackTickets(request); + return Result.success(pageResponse); + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketBasicInfoDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketBasicInfoDTO.java new file mode 100644 index 0000000..a89efee --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketBasicInfoDTO.java @@ -0,0 +1,2 @@ +package com.luojia_channel.modules.feedback.dto;public class FeedbackTicketBasicInfoDTO { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketPageQueryDTO.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketPageQueryDTO.java new file mode 100644 index 0000000..7cd3627 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/dto/FeedbackTicketPageQueryDTO.java @@ -0,0 +1,2 @@ +package com.luojia_channel.modules.feedback.dto;public class FeedbackTicketPageQueryDTO { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/entity/FeedbackTicket.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/entity/FeedbackTicket.java new file mode 100644 index 0000000..9c9c6c0 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/entity/FeedbackTicket.java @@ -0,0 +1,2 @@ +package com.luojia_channel.modules.feedback.entity;public class FeedbackTicket { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mapper/FeedbackTicketMapper.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mapper/FeedbackTicketMapper.java new file mode 100644 index 0000000..f0ea897 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mapper/FeedbackTicketMapper.java @@ -0,0 +1,10 @@ +package com.luojia_channel.modules.feedback.mapper; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.luojia_channel.modules.feedback.entity.FeedbackTicket; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface FeedbackTicketMapper extends BaseMapper { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/consumer/FeedbackMessageConsumer.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/consumer/FeedbackMessageConsumer.java new file mode 100644 index 0000000..8ecd5a3 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/consumer/FeedbackMessageConsumer.java @@ -0,0 +1,34 @@ +package com.luojia_channel.modules.feedback.mq.consumer; + +import com.luojia_channel.modules.feedback.config.FeedbackRabbitMQConfig; +import com.luojia_channel.modules.feedback.entity.FeedbackTicket; +import com.luojia_channel.modules.feedback.service.FeedbackTicketService; +import com.luojia_channel.modules.message.mq.MessageWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.stereotype.Component; + + +@Slf4j +@Component +@RequiredArgsConstructor +public class FeedbackMessageConsumer { + + private final FeedbackTicketService feedbackTicketService; + + @RabbitListener(queues = FeedbackRabbitMQConfig.FEEDBACK_DLX_QUEUE) + public void handleFeedbackMessage(MessageWrapper wrapper) { + try { + FeedbackTicket ticket = wrapper.getMessage(); + log.info("收到反馈工单延时消息,工单ID:{}", ticket.getId()); + + // 处理延时任务,例如更新工单状态 + feedbackTicketService.processDelayedFeedback(ticket.getId()); + + } catch (Exception e) { + log.error("处理反馈工单延时消息失败,消息ID:{}", wrapper.getUuid(), e); + throw e; + } + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/domain/DelayHandleTicketMessage.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/domain/DelayHandleTicketMessage.java new file mode 100644 index 0000000..45cab50 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/domain/DelayHandleTicketMessage.java @@ -0,0 +1,2 @@ +package com.luojia_channel.modules.feedback.mq.domain;public class DelayHandleTicketMessage { +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/producer/FeedbackMessageProducer.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/producer/FeedbackMessageProducer.java new file mode 100644 index 0000000..14cc61c --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/mq/producer/FeedbackMessageProducer.java @@ -0,0 +1,47 @@ +package com.luojia_channel.modules.feedback.mq.producer; + + +import com.luojia_channel.modules.feedback.config.FeedbackRabbitMQConfig; +import com.luojia_channel.modules.feedback.entity.FeedbackTicket; +import com.luojia_channel.modules.message.mq.AbstractSendProduceTemplate; +import com.luojia_channel.modules.message.mq.MessageWrapper; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Component; + + +@Slf4j +@Component +@RequiredArgsConstructor +public class FeedbackMessageProducer { + + private final RabbitTemplate rabbitTemplate; + + public void sendDelayMessage(FeedbackTicket ticket, Long delayTime) { + try { + // 构建消息包装器 + MessageWrapper wrapper = MessageWrapper.builder() + .keys("feedback_" + ticket.getId()) + .message(ticket) + .build(); + + // 发送消息到延迟队列,设置消息TTL(过期时间) + rabbitTemplate.convertAndSend( + FeedbackRabbitMQConfig.FEEDBACK_EXCHANGE, + FeedbackRabbitMQConfig.FEEDBACK_ROUTING_KEY, + wrapper, + message -> { + message.getMessageProperties().setExpiration(delayTime.toString()); + return message; + } + ); + + log.info("反馈工单延时消息发送成功,工单ID:{},延迟时间:{}ms", + ticket.getId(), delayTime); + } catch (Exception e) { + log.error("反馈工单延时消息发送失败,工单ID:{}", ticket.getId(), e); + throw e; + } + } +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/FeedbackTicketService.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/FeedbackTicketService.java new file mode 100644 index 0000000..cb985b0 --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/FeedbackTicketService.java @@ -0,0 +1,37 @@ +package com.luojia_channel.modules.feedback.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.luojia_channel.modules.feedback.entity.FeedbackTicket; +import com.luojia_channel.common.domain.page.PageRequest; +import com.luojia_channel.common.domain.page.PageResponse; + +import java.util.List; + +public interface FeedbackTicketService extends IService { + /** + * 创建反馈工单 + * @param feedbackTicket 反馈工单实体 + * @return 工单 ID + */ + Long createFeedbackTicket(FeedbackTicket feedbackTicket); + + /** + * 编辑反馈工单 + * @param feedbackTicket 反馈工单实体 + */ + void updateFeedbackTicket(FeedbackTicket feedbackTicket); + + /** + * 个人反馈工单查询 + * @param userId 用户 ID + * @return 反馈工单列表 + */ + List getPersonalFeedbackTickets(Long userId); + + /** + * 管理员反馈工单分页查询 + * @param request 分页查询参数 + * @return 分页结果 + */ + PageResponse getAdminFeedbackTickets(PageRequest request); +} diff --git a/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/impl/FeedbackTicketServiceImpl.java b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/impl/FeedbackTicketServiceImpl.java new file mode 100644 index 0000000..286369d --- /dev/null +++ b/珞珈岛-项目相关文件/luojia-island/service/src/main/java/com/luojia_channel/modules/feedback/service/impl/FeedbackTicketServiceImpl.java @@ -0,0 +1,2 @@ +package com.luojia_channel.modules.feedback.service.impl;public class FeedbackTicketServiceImpl { +}