消息推送代码

This commit is contained in:
zhoupeng committed 2026-08-14 18:39:06 +08:00
1 parent d2ade538e2
commit d473d5d04a
6 files changed
+158 -1

No files matched your search

@@ -106,6 +106,13 @@
<artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
</dependency>
<!-- 极光推送 -->
<dependency>
<groupId>cn.jpush.api</groupId>
<artifactId>jpush-client</artifactId>
<version>3.7.7</version>
</dependency>
<!-- 文字、图片风险认证 -->
<dependency>
<groupId>com.aliyun</groupId>
@@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.member.client.vo.chat.friend.ChatAddFriendReqVO;
import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendReqVO;
import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendResVO;
import cn.iocoder.yudao.module.member.service.opentype.OpenTypeService;
import cn.iocoder.yudao.module.member.service.push.MemberPushService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.validation.annotation.Validated;
@@ -27,6 +28,8 @@ public class AppChatController {
@Resource
private ChatApi chatApi;
@Resource
private MemberPushService memberPushService;
@PostMapping("/send-private-msg")
@Operation(summary = "发送私聊消息(有会员限制)")
@@ -35,7 +38,11 @@ public class AppChatController {
openTypeService.isUserCanSendMessage(sendId, body.getRecvId());
body.setSendId(sendId);
body.setTerminal(1);
return success(chatApi.send(body));
ChatPrivateMessageSendResVO result = chatApi.send(body);
if (result != null) {
memberPushService.pushPrivateMessage(body);
}
return success(result);
}
@GetMapping("/add-friend")
@@ -0,0 +1,20 @@
package cn.iocoder.yudao.module.member.framework.web.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("jpush")
@Data
public class JPushProperties {
private boolean enabled;
private String appKey;
private String masterSecret;
private boolean apnsProduction;
}
@@ -0,0 +1,12 @@
package cn.iocoder.yudao.module.member.service.push;
import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendReqVO;
public interface MemberPushService {
/**
* 推送私聊消息通知
*/
void pushPrivateMessage(ChatPrivateMessageSendReqVO message);
}
@@ -0,0 +1,105 @@
package cn.iocoder.yudao.module.member.service.push;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
import cn.iocoder.yudao.module.member.client.vo.chat.user.ChatPrivateMessageSendReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.push.MemberPushDeviceDO;
import cn.iocoder.yudao.module.member.framework.web.config.JPushProperties;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class MemberPushServiceImpl implements MemberPushService {
private static final int MAX_ALERT_LENGTH = 100;
@Resource
private MemberPushDeviceService pushDeviceService;
@Resource
private MemberUserApi memberUserApi;
@Resource
private JPushProperties jPushProperties;
@Override
public void pushPrivateMessage(ChatPrivateMessageSendReqVO message) {
if (!jPushProperties.isEnabled() || StrUtil.isBlank(jPushProperties.getAppKey())
|| StrUtil.isBlank(jPushProperties.getMasterSecret())) {
return;
}
List<MemberPushDeviceDO> devices = pushDeviceService.getByMemberId(message.getRecvId());
List<String> registrationIds = devices.stream()
.filter(device -> StrUtil.equalsIgnoreCase(device.getProvider(), "jpush"))
.map(MemberPushDeviceDO::getRegistrationId)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (CollUtil.isEmpty(registrationIds)) {
return;
}
MemberUserRespDTO sender = memberUserApi.getUser(message.getSendId());
String title = sender != null && StrUtil.isNotBlank(sender.getNickname()) ? sender.getNickname() : "新消息";
String alert = buildAlert(message);
PushPayload payload = PushPayload.newBuilder()
.setPlatform(Platform.android_ios())
.setAudience(Audience.registrationId(registrationIds))
.setNotification(Notification.newBuilder()
.setAlert(alert)
.addPlatformNotification(AndroidNotification.newBuilder().setTitle(title).build())
.addPlatformNotification(IosNotification.newBuilder().incrBadge(1).build())
.build())
.setMessage(Message.newBuilder().setTitle(title).setMsgContent(alert)
.addExtra("type", "private_message")
.addExtra("senderId", String.valueOf(message.getSendId()))
.addExtra("receiverId", String.valueOf(message.getRecvId()))
.addExtra("messageType", String.valueOf(message.getType()))
.build())
.setOptions(Options.newBuilder().setApnsProduction(jPushProperties.isApnsProduction()).build())
.build();
try {
JPushClient client = new JPushClient(jPushProperties.getMasterSecret(), jPushProperties.getAppKey());
PushResult result = client.sendPush(payload);
log.info("[pushPrivateMessage][sendId({}) recvId({}) registrationIds({}) msgId({}) 推送成功]",
message.getSendId(), message.getRecvId(), registrationIds.size(), result.msg_id);
} catch (Exception e) {
log.error("[pushPrivateMessage][sendId({}) recvId({}) 极光推送失败]",
message.getSendId(), message.getRecvId(), e);
}
}
private String buildAlert(ChatPrivateMessageSendReqVO message) {
if (message.getType() == null || message.getType() == 0) {
return StrUtil.maxLength(message.getContent(), MAX_ALERT_LENGTH);
}
switch (message.getType()) {
case 1:
return "[图片]";
case 2:
return "[文件]";
case 3:
return "[语音]";
case 4:
return "[视频]";
default:
return "您收到一条新消息";
}
}
}
@@ -366,6 +366,12 @@ yudao:
key: pLXUGAwK5305
customer: E77DF18BE109F454A5CD319E44BF5177
jpush:
enabled: ${JPUSH_ENABLED:true}
app-key: ${JPUSH_APP_KEY:d7773439aa8c579dc31a552f}
master-secret: ${JPUSH_MASTER_SECRET:a2ea6bb666a26ff1dd246ffa}
apns-production: ${JPUSH_APNS_PRODUCTION:true}
debug: false
# 插件配置 TODO 芋艿:【IOT】需要处理下
pf4j: