From b14754ec0a05e5f606e2b0393d6d65bb4c12d6a1 Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Wed, 17 Sep 2025 21:53:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(integration):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=9C=8D=E5=8A=A1=E7=9B=B8=E5=85=B3=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=92=8C=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 MessageController 类,实现消息列表查询和消息通道列表获取功能 - 新增 MessageClient 接口,用于调用消息服务的 Feign客户端 - 新增 ChannelsResponse、MessageListData 和 MessageRecordDTO 数据传输对象 - 新增 MessageIntegrationService 服务类,处理消息服务相关业务逻辑 --- .../controller/pc/MessageController.java | 60 +++++++++++++++++++ .../message/client/MessageClient.java | 29 +++++++++ .../message/dto/ChannelsResponse.java | 10 ++++ .../message/dto/MessageListData.java | 13 ++++ .../message/dto/MessageRecordDTO.java | 25 ++++++++ .../service/MessageIntegrationService.java | 57 ++++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 src/main/java/com/ycwl/basic/controller/pc/MessageController.java create mode 100644 src/main/java/com/ycwl/basic/integration/message/client/MessageClient.java create mode 100644 src/main/java/com/ycwl/basic/integration/message/dto/ChannelsResponse.java create mode 100644 src/main/java/com/ycwl/basic/integration/message/dto/MessageListData.java create mode 100644 src/main/java/com/ycwl/basic/integration/message/dto/MessageRecordDTO.java create mode 100644 src/main/java/com/ycwl/basic/integration/message/service/MessageIntegrationService.java diff --git a/src/main/java/com/ycwl/basic/controller/pc/MessageController.java b/src/main/java/com/ycwl/basic/controller/pc/MessageController.java new file mode 100644 index 00000000..318d2bc8 --- /dev/null +++ b/src/main/java/com/ycwl/basic/controller/pc/MessageController.java @@ -0,0 +1,60 @@ +package com.ycwl.basic.controller.pc; + +import com.ycwl.basic.integration.message.dto.ChannelsResponse; +import com.ycwl.basic.integration.message.dto.MessageListData; +import com.ycwl.basic.integration.message.service.MessageIntegrationService; +import com.ycwl.basic.utils.ApiResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequestMapping("/api/message/v1") +@RequiredArgsConstructor +public class MessageController { + + private final MessageIntegrationService messageService; + + @GetMapping("/messages") + public ApiResponse listMessages( + @RequestParam(defaultValue = "1") Integer page, + @RequestParam(defaultValue = "20") Integer pageSize, + @RequestParam(required = false) String channelId, + @RequestParam(required = false) String title, + @RequestParam(required = false) String content, + @RequestParam(required = false) String sendBiz, + @RequestParam(required = false) String sentAtStart, + @RequestParam(required = false) String sentAtEnd, + @RequestParam(required = false) String createdAtStart, + @RequestParam(required = false) String createdAtEnd + ) { + log.info("PC|消息列表查询 page={}, pageSize={}, channelId={}, title={}, sendBiz={}", page, pageSize, channelId, title, sendBiz); + if (pageSize > 100) { + pageSize = 100; + } + try { + MessageListData data = messageService.listMessages(page, pageSize, channelId, title, content, sendBiz, + sentAtStart, sentAtEnd, createdAtStart, createdAtEnd); + return ApiResponse.success(data); + } catch (Exception e) { + log.error("PC|消息列表查询失败", e); + return ApiResponse.fail("消息列表查询失败: " + e.getMessage()); + } + } + + @GetMapping("/channels") + public ApiResponse listChannels() { + log.info("PC|获取消息通道列表"); + try { + ChannelsResponse data = messageService.listChannels(); + return ApiResponse.success(data); + } catch (Exception e) { + log.error("PC|获取消息通道列表失败", e); + return ApiResponse.fail("获取消息通道列表失败: " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/ycwl/basic/integration/message/client/MessageClient.java b/src/main/java/com/ycwl/basic/integration/message/client/MessageClient.java new file mode 100644 index 00000000..4aca5eed --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/message/client/MessageClient.java @@ -0,0 +1,29 @@ +package com.ycwl.basic.integration.message.client; + +import com.ycwl.basic.integration.common.response.CommonResponse; +import com.ycwl.basic.integration.message.dto.ChannelsResponse; +import com.ycwl.basic.integration.message.dto.MessageListData; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +@FeignClient(name = "zt-message", contextId = "zt-message", path = "") +public interface MessageClient { + + @GetMapping("/messages") + CommonResponse listMessages( + @RequestParam(name = "page", defaultValue = "1") Integer page, + @RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize, + @RequestParam(name = "channelId", required = false) String channelId, + @RequestParam(name = "title", required = false) String title, + @RequestParam(name = "content", required = false) String content, + @RequestParam(name = "sendBiz", required = false) String sendBiz, + @RequestParam(name = "sentAtStart", required = false) String sentAtStart, + @RequestParam(name = "sentAtEnd", required = false) String sentAtEnd, + @RequestParam(name = "createdAtStart", required = false) String createdAtStart, + @RequestParam(name = "createdAtEnd", required = false) String createdAtEnd + ); + + @GetMapping("/channels") + CommonResponse listChannels(); +} diff --git a/src/main/java/com/ycwl/basic/integration/message/dto/ChannelsResponse.java b/src/main/java/com/ycwl/basic/integration/message/dto/ChannelsResponse.java new file mode 100644 index 00000000..f5b53c3f --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/message/dto/ChannelsResponse.java @@ -0,0 +1,10 @@ +package com.ycwl.basic.integration.message.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class ChannelsResponse { + private List channels; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/message/dto/MessageListData.java b/src/main/java/com/ycwl/basic/integration/message/dto/MessageListData.java new file mode 100644 index 00000000..ae1d51ce --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/message/dto/MessageListData.java @@ -0,0 +1,13 @@ +package com.ycwl.basic.integration.message.dto; + +import lombok.Data; + +import java.util.List; + +@Data +public class MessageListData { + private List list; + private String total; // string to avoid JS precision + private Integer page; + private Integer pageSize; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/message/dto/MessageRecordDTO.java b/src/main/java/com/ycwl/basic/integration/message/dto/MessageRecordDTO.java new file mode 100644 index 00000000..189cc446 --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/message/dto/MessageRecordDTO.java @@ -0,0 +1,25 @@ +package com.ycwl.basic.integration.message.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.Map; + +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class MessageRecordDTO { + private String id; // string to avoid JS precision + private String channelId; + private String title; + private String content; + private String target; + private Map extraJson; + private String sendReason; + private String sendBiz; + private String status; + private String errorMsg; + private Integer attempts; + private String sentAt; // RFC3339 or yyyy-MM-dd HH:mm:ss (pass-through) + private String createdAt; + private String updatedAt; +} \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/integration/message/service/MessageIntegrationService.java b/src/main/java/com/ycwl/basic/integration/message/service/MessageIntegrationService.java new file mode 100644 index 00000000..c642703a --- /dev/null +++ b/src/main/java/com/ycwl/basic/integration/message/service/MessageIntegrationService.java @@ -0,0 +1,57 @@ +package com.ycwl.basic.integration.message.service; + +import com.ycwl.basic.integration.common.exception.IntegrationException; +import com.ycwl.basic.integration.common.response.CommonResponse; +import com.ycwl.basic.integration.common.service.IntegrationFallbackService; +import com.ycwl.basic.integration.message.client.MessageClient; +import com.ycwl.basic.integration.message.dto.ChannelsResponse; +import com.ycwl.basic.integration.message.dto.MessageListData; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class MessageIntegrationService { + + private final MessageClient client; + private final IntegrationFallbackService fallbackService; + + private static final String SERVICE_NAME = "zt-message"; + + public MessageListData listMessages(Integer page, Integer pageSize, + String channelId, String title, String content, String sendBiz, + String sentAtStart, String sentAtEnd, + String createdAtStart, String createdAtEnd) { + log.debug("查询消息列表 page={}, pageSize={}, channelId={}, title={}, sendBiz={}", page, pageSize, channelId, title, sendBiz); + CommonResponse resp = client.listMessages(page, pageSize, channelId, title, content, sendBiz, + sentAtStart, sentAtEnd, createdAtStart, createdAtEnd); + return handleResponse(resp, "查询消息列表失败"); + } + + public ChannelsResponse listChannels() { + log.debug("查询消息通道列表"); + // 相对稳定的数据,使用fallback缓存 + return fallbackService.executeWithFallback( + SERVICE_NAME, + "channels", + () -> { + CommonResponse resp = client.listChannels(); + return handleResponse(resp, "查询通道列表失败"); + }, + ChannelsResponse.class + ); + } + + private T handleResponse(CommonResponse response, String errorMessage) { + if (response == null || !response.isSuccess()) { + String msg = response != null && response.getMessage() != null + ? response.getMessage() + : errorMessage; + Integer code = response != null ? response.getCode() : 5000; + throw new IntegrationException(code, msg, SERVICE_NAME); + } + return response.getData(); + } +}