From f06ca9839b49a93370ba6b871966de9479659e3a Mon Sep 17 00:00:00 2001 From: Jack <46790855@qq.com> Date: Sun, 22 Jun 2025 03:03:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20uni=20cloud=20push=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=8E=A8=E9=80=81=E5=85=AC=E5=85=B1=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/service/UniCloudPushService.java | 29 +++ .../service/impl/UniCloudPushServiceImpl.java | 207 ++++++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 mall-common/src/main/java/com/suisung/mall/common/service/UniCloudPushService.java create mode 100644 mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java diff --git a/mall-common/src/main/java/com/suisung/mall/common/service/UniCloudPushService.java b/mall-common/src/main/java/com/suisung/mall/common/service/UniCloudPushService.java new file mode 100644 index 00000000..aff3dea0 --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/service/UniCloudPushService.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.service; + +import cn.hutool.json.JSONObject; +import com.suisung.mall.common.service.impl.UniCloudPushServiceImpl; + +import java.util.List; + +public interface UniCloudPushService { + + /** + * 向多个客户端ID批量发送推送消息 + * + * @param clientIds 目标客户端ID列表 + * @param title 推送标题 + * @param content 推送内容 + * @param payload 附加数据(JSON对象) + * @return 推送结果响应对象 + * @throws UniCloudPushServiceImpl.UniCloudPushException 推送过程中发生的异常 + */ + UniCloudPushServiceImpl.PushResponse sendBatchPush(String cloudFunctionUrl, List clientIds, String title, String content, JSONObject payload); +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java b/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java new file mode 100644 index 00000000..dc8ac2fb --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/service/impl/UniCloudPushServiceImpl.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.service.impl; + +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.suisung.mall.common.service.UniCloudPushService; +import org.springframework.context.annotation.Lazy; +import org.springframework.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; +import org.springframework.web.client.RestTemplate; + +import javax.annotation.Resource; +import java.util.List; + +/** + * 调用 UniCloud 云函数 推送服务 + * 提供向多个客户端 ID 发送推送消息的功能 + */ +@Service +public class UniCloudPushServiceImpl implements UniCloudPushService { + // 请求常量定义 + private static final String ACTION_KEY = "action"; + private static final String CID_LIST_KEY = "cidList"; + private static final String MESSAGE_KEY = "message"; + private static final String TITLE_KEY = "title"; + private static final String CONTENT_KEY = "content"; + private static final String PAYLOAD_KEY = "payload"; + + @Lazy + @Resource + private RestTemplate restTemplate; + + + /** + * 向多个客户端ID批量发送推送消息 + * + * @param clientIds 目标客户端ID列表 + * @param title 推送标题 + * @param content 推送内容 + * @param payload 附加数据(JSON对象) + * @return 推送结果响应对象 + * @throws UniCloudPushException 推送过程中发生的异常 + */ + @Override + public PushResponse sendBatchPush(String cloudFunctionUrl, List clientIds, String title, String content, JSONObject payload) { + // 参数校验 + validatePushParams(clientIds, title, content); + + // 构建请求体 + JSONObject requestBody = buildPushRequest(clientIds, title, content, payload); + + try { + // 执行HTTP请求 + ResponseEntity response = executeHttpRequest(cloudFunctionUrl, requestBody); + + // 处理响应结果 + return processResponse(response); + } catch (RestClientException e) { + // 处理REST客户端异常 + throw new UniCloudPushException("推送请求发送失败", e); + } catch (Exception e) { + // 处理其他异常 + throw new UniCloudPushException("推送处理过程发生异常", e); + } + } + + /** + * 验证推送参数有效性 + */ + private void validatePushParams(List clientIds, String title, String content) throws IllegalArgumentException { + if (clientIds == null || clientIds.isEmpty()) { + throw new IllegalArgumentException("客户端ID列表不能为空"); + } + + if (title == null || title.trim().isEmpty()) { + throw new IllegalArgumentException("推送标题不能为空"); + } + + if (content == null || content.trim().isEmpty()) { + throw new IllegalArgumentException("推送内容不能为空"); + } + } + + /** + * 构建推送请求体 + */ + private JSONObject buildPushRequest(List clientIds, String title, String content, JSONObject payload) { + JSONObject requestBody = new JSONObject(); + requestBody.put(ACTION_KEY, "push"); + requestBody.put(CID_LIST_KEY, clientIds); + + JSONObject message = new JSONObject(); + message.put(TITLE_KEY, title); + message.put(CONTENT_KEY, content); + + if (payload != null) { + message.put(PAYLOAD_KEY, payload); + } + + requestBody.put(MESSAGE_KEY, message); + return requestBody; + } + + /** + * 执行HTTP POST请求 + */ + private ResponseEntity executeHttpRequest(String cloudFunctionUrl, JSONObject requestBody) { + // 设置请求头 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + // 创建请求实体 + HttpEntity requestEntity = new HttpEntity<>(requestBody.toString(), headers); + + // 执行POST请求 + return restTemplate.exchange( + cloudFunctionUrl, + HttpMethod.POST, + requestEntity, + String.class + ); + } + + /** + * 处理HTTP响应 + */ + private PushResponse processResponse(ResponseEntity response) { + if (response.getStatusCode() != HttpStatus.OK) { + throw new UniCloudPushException( + String.format("推送请求失败,状态码: %d,响应: %s", + response.getStatusCodeValue(), + response.getBody()) + ); + } + + String responseBody = response.getBody(); + if (responseBody == null || responseBody.trim().isEmpty()) { + throw new UniCloudPushException("推送响应内容为空"); + } + + // 解析响应JSON + JSONObject responseJson = JSONUtil.parseObj(responseBody); + + // 提取响应结果 + return new PushResponse( + responseJson.getBool("success"), + responseJson.getInt("code"), + responseJson.getStr("message"), + responseJson.getJSONObject("data") + ); + } + + /** + * 推送响应结果类 + */ + public static class PushResponse { + private final boolean success; + private final int code; + private final String message; + private final JSONObject data; + + public PushResponse(boolean success, int code, String message, JSONObject data) { + this.success = success; + this.code = code; + this.message = message; + this.data = data; + } + + // Getter方法 + public boolean isSuccess() { + return success; + } + + public int getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public JSONObject getData() { + return data; + } + } + + /** + * 自定义推送异常类 + */ + public static class UniCloudPushException extends RuntimeException { + public UniCloudPushException(String message) { + super(message); + } + + public UniCloudPushException(String message, Throwable cause) { + super(message, cause); + } + } +}