修改消息通过腾讯im发送bug加模糊查询

This commit is contained in:
曹佳豪 2025-06-24 16:28:56 +08:00
parent 3a66394bbe
commit 297b0332da
9 changed files with 234 additions and 130 deletions

View File

@ -298,13 +298,8 @@ justauth:
# 腾讯云IM配置
tencent:
im:
# 腾讯云 SDKAppId
sdkappid: 1600080789
# 密钥
secretkey: 311b5309d714a20f7f5b54360ee21b1e24ec208ebcd25ce8f47d24753bccc091
# 签名过期时间(秒)
expire: 604800
# 管理员账号
admin: administrator
# API调用密钥
api-secret: 311b5309d714a20f7f5b54360ee21b1e24ec208ebcd25ce8f47d24753bccc091
enabled: true # 启用腾讯云IM
sdk-app-id: 1600080789 # 你的腾讯云 SDKAppID
secret-key: "311b5309d714a20f7f5b54360ee21b1e24ec208ebcd25ce8f47d24753bccc091" # 你的密钥
administrator: "administrator" # 管理员账号
expire-time: 604800 # UserSig 过期时间7天单位

View File

@ -113,7 +113,7 @@ public class LogAspect {
// 设置消耗时间
StopWatch stopWatch = KEY_CACHE.get();
stopWatch.stop();
operLog.setCostTime(stopWatch.getDuration().toMillis());
operLog.setCostTime(stopWatch.getTime());
// 发布事件保存数据库
SpringUtils.context().publishEvent(operLog);
} catch (Exception exp) {

View File

@ -67,7 +67,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
StopWatch stopWatch = KEY_CACHE.get();
if (ObjectUtil.isNotNull(stopWatch)) {
stopWatch.stop();
log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getDuration().toMillis());
log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
KEY_CACHE.remove();
}
}

View File

@ -8,14 +8,10 @@ import org.apache.rocketmq.spring.core.RocketMQListener;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.system.config.RocketMQConfig;
import org.dromara.system.domain.SysMessageUser;
import org.dromara.system.domain.vo.SysMessageVo;
import org.dromara.system.mapper.SysMessageUserMapper;
import org.dromara.system.websocket.MessageWebSocketServer;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* RocketMQ消息消费者
*
@ -32,7 +28,6 @@ import java.util.Date;
public class MessageRocketMQConsumer implements RocketMQListener<String> {
private final MessageWebSocketServer messageWebSocketServer;
private final SysMessageUserMapper messageUserMapper;
@Override
public void onMessage(String message) {
@ -53,18 +48,6 @@ public class MessageRocketMQConsumer implements RocketMQListener<String> {
}
if (userIdLong != null) {
// 保存消息用户关联记录
try {
SysMessageUser messageUser = new SysMessageUser();
messageUser.setMessageId(wrapper.getMessage().getId());
messageUser.setUserId(userIdLong);
messageUser.setIsRead(false);
messageUserMapper.insert(messageUser);
log.info("消息用户关联记录保存成功messageId: {}, userId: {}", wrapper.getMessage().getId(), userIdLong);
} catch (Exception e) {
log.error("保存消息用户关联记录失败", e);
}
// 发送WebSocket消息
messageWebSocketServer.sendMessage(userIdLong, JsonUtils.toJsonString(wrapper.getMessage()));
log.info("通过WebSocket发送消息成功userId: {}", userIdLong);

View File

@ -2,6 +2,8 @@ package org.dromara.system.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wzj.soopin.member.domain.po.Member;
import com.wzj.soopin.member.mapper.MemberMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotEmpty;
@ -31,6 +33,9 @@ import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.service.ISysMessageService;
import org.dromara.system.service.ISysMessageTemplateService;
import org.dromara.system.service.ISysUserService;
import org.dromara.common.satoken.utils.LoginHelper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -51,6 +56,7 @@ public class SysMessageController extends BaseController {
private final ISysMessageService messageService;
private final ISysUserService userService;
private final ISysMessageTemplateService templateService;
private final MemberMapper umsMemberMapper;
/**
* 获取当前用户ID
@ -107,12 +113,12 @@ public class SysMessageController extends BaseController {
return R.fail("未找到指定的消息模板");
}
}
// 验证消息内容是否为空
if (StringUtils.isBlank(bo.getContent())) {
return R.fail("消息内容不能为空");
}
// 验证发送范围是否为空
List<String> sendScope = bo.getSendScope();
if (sendScope == null || sendScope.isEmpty()) {
@ -129,37 +135,35 @@ public class SysMessageController extends BaseController {
if (sendScope == null || sendScope.isEmpty()) {
return R.fail("发送范围不能为空");
}
String scope = sendScope.get(0); // 获取第一个范围值
switch (logmess) {
case 1: // 指定角色
// 当logmess=1时sendScope接收的是角色ID或特殊标识
if ("all".equals(scope) || "expert".equals(scope) || "merchant".equals(scope) || "user".equals(scope)) {
if ("all".equals(scope)) {
// 全部会员用户查ums_member表
List<Member> members = umsMemberMapper.selectList(
new QueryWrapper<Member>().eq("status", 1)
);
userIdStrings = members.stream().map(m -> String.valueOf(m.getId())).toList();
} else if ("expert".equals(scope) || "merchant".equals(scope) || "user".equals(scope)) {
List<SysUserVo> users = userService.selectUserListByDept(null);
List<Long> userIds;
switch (scope) {
case "all":
// 全部用户
userIds = users.stream().map(SysUserVo::getUserId).toList();
break;
case "expert":
// 达人
userIds = users.stream()
.filter(user -> "expert".equals(user.getUserType()))
.map(SysUserVo::getUserId)
.toList();
break;
case "merchant":
// 商户
userIds = users.stream()
.filter(user -> "merchant".equals(user.getUserType()))
.map(SysUserVo::getUserId)
.toList();
break;
case "user":
// 普通用户
userIds = users.stream()
.filter(user -> "user".equals(user.getUserType()))
.map(SysUserVo::getUserId)
@ -220,14 +224,14 @@ public class SysMessageController extends BaseController {
if (sendScope == null || sendScope.isEmpty()) {
return R.fail("发送范围不能为空");
}
String scope = sendScope.get(0); // 获取第一个范围值
// 如果是群发消息类型则根据类型筛选用户
if ("all".equals(scope) || "expert".equals(scope) || "merchant".equals(scope) || "user".equals(scope)) {
List<SysUserVo> users = userService.selectUserListByDept(null);
List<Long> userIds;
switch (scope) {
case "all":
// 全部用户

View File

@ -14,6 +14,8 @@ import org.dromara.common.mybatis.core.domain.BaseEntity;
import org.dromara.system.domain.SysMessage;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
@ -85,16 +87,25 @@ public class SysMessageBo extends BaseAudit {
/** 备注 */
private String remark;
/** 创建时间-起始 */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
private LocalDateTime startTime;
/** 创建时间-结束 */
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", timezone = "UTC")
private LocalDateTime sendTime;
/**
* 转换为查询条件
*/
public LambdaQueryWrapper<SysMessage> toWrapper() {
LambdaQueryWrapper<SysMessage> lqw = new LambdaQueryWrapper<>();
lqw.like(StringUtils.isNotBlank(this.getTitle()), SysMessage::getTitle, this.getTitle())
.like(StringUtils.isNotBlank(this.getContent()), SysMessage::getContent, this.getContent())
.eq(StringUtils.isNotBlank(this.getMsgType()), SysMessage::getMsgType, this.getMsgType())
.eq(StringUtils.isNotBlank(this.getSubType()), SysMessage::getSubType, this.getSubType())
.eq(this.getSenderId() != null, SysMessage::getSenderId, this.getSenderId())
// .eq(StringUtils.isNotBlank(this.getStatus()), SysMessage::getStatus, this.getStatus())
.ge(this.getStartTime() != null, SysMessage::getCreateTime, this.getStartTime())
.le(this.getSendTime() != null, SysMessage::getCreateTime, this.getSendTime())
.orderByDesc(SysMessage::getCreateTime);
return lqw;
}

View File

@ -3,6 +3,7 @@ package org.dromara.system.event;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.json.utils.JsonUtils;
import org.dromara.system.config.RocketMQConfig;
import org.dromara.system.consumer.MessageRocketMQConsumer;
@ -61,7 +62,7 @@ public class MessageEventListener {
// 消息发送者可能是系统或管理员这里使用固定的管理员账号作为发送者
String fromUserId = "administrator";
String toUserId = userId; // 接收者是事件中的用户ID
String content = JsonUtils.toJsonString(event.getMessage()); // 消息内容序列化为JSON
String content = event.getMessage().getContent(); // 只取content字段
// 处理消息变量替换如果有
Map<String, String> variables = new HashMap<>();
@ -127,7 +128,7 @@ public class MessageEventListener {
}
} else {
// 默认为单用户推送
tencentIMSendSuccess = tencentIMService.sendMessageToTencentIM(fromUserId, toUserId, content);
tencentIMSendSuccess = tencentIMService.sendMessageToTencentIM(fromUserId, toUserId, content);
}
if (tencentIMSendSuccess) {
@ -141,6 +142,7 @@ public class MessageEventListener {
// 无论腾讯IM是否发送成功都继续尝试通过RocketMQ发送消息
// 这样可以确保消息至少通过一种方式发送出去
/*
boolean rocketMQSendSuccess = false;
try {
rocketMQService.sendMessage(
@ -153,6 +155,8 @@ public class MessageEventListener {
} catch (Exception e) {
log.error("通过RocketMQ发送消息失败将尝试直接通过WebSocket发送", e);
}
*/
boolean rocketMQSendSuccess = false; // 直接设为false表示不走MQ
// 如果前两种方式都失败则尝试直接通过WebSocket发送
if (!tencentIMSendSuccess && !rocketMQSendSuccess && event.getUserId() != null) {

View File

@ -22,7 +22,10 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@ -128,6 +131,11 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
// 批量创建消息用户关联
int count = 0;
// 先过滤有效的用户ID
List<Long> validUserIds = new ArrayList<>();
Map<Long, String> userIdStrMap = new HashMap<>();
for (String userIdStr : userIds) {
if (StringUtils.isBlank(userIdStr)) {
continue;
@ -135,37 +143,61 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
try {
Long userId = Long.parseLong(userIdStr);
// 检查消息与用户关联是否已存在
LambdaQueryWrapper<SysMessageUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMessageUser::getMessageId, entity.getId())
.eq(SysMessageUser::getUserId, userId);
int existCount = Math.toIntExact(messageUserMapper.selectCount(queryWrapper));
// 只有当关联不存在时才创建
if (existCount == 0) {
SysMessageUser messageUser = new SysMessageUser();
messageUser.setMessageId(entity.getId());
messageUser.setUserId(userId);
messageUser.setIsRead(false);
int rows = messageUserMapper.insert(messageUser);
if (rows > 0) {
count++;
validUserIds.add(userId);
userIdStrMap.put(userId, userIdStr);
} catch (NumberFormatException e) {
log.error("无法将String类型的用户ID转换为Long: {}", userIdStr);
}
}
// 一次性查询所有已存在的关联记录
if (!validUserIds.isEmpty()) {
LambdaQueryWrapper<SysMessageUser> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SysMessageUser::getMessageId, entity.getId())
.in(SysMessageUser::getUserId, validUserIds);
List<SysMessageUser> existingRecords = messageUserMapper.selectList(queryWrapper);
// 创建已存在用户ID的集合
Set<Long> existingUserIds = existingRecords.stream()
.map(SysMessageUser::getUserId)
.collect(Collectors.toSet());
log.info("已存在的消息关联记录数: {}", existingUserIds.size());
// 对不存在关联的用户批量插入
for (Long userId : validUserIds) {
if (!existingUserIds.contains(userId)) {
try {
SysMessageUser messageUser = new SysMessageUser();
messageUser.setMessageId(entity.getId());
messageUser.setUserId(userId);
messageUser.setIsRead(false);
int rows = messageUserMapper.insert(messageUser);
if (rows > 0) {
count++;
}
} catch (Exception e) {
log.error("创建消息用户关联失败: messageId={}, userId={}, error={}",
entity.getId(), userId, e.getMessage());
}
} else {
log.info("消息与用户关联已存在,跳过创建: messageId={}, userId={}", entity.getId(), userId);
// 已存在也计入成功数量
count++;
}
// 无论关联是否新建都发送事件通知
SysMessageVo messageVo = MapstructUtils.convert(entity, SysMessageVo.class);
eventPublisher.publishEvent(MessageEvent.createWithStringUserId(this, messageVo, userIdStr));
} catch (NumberFormatException e) {
log.error("无法将String类型的用户ID转换为Long: {}", userIdStr);
}
}
// 最后只发送一次批量事件通知
if (count > 0) {
SysMessageVo messageVo = MapstructUtils.convert(entity, SysMessageVo.class);
// 为所有有效用户ID组装一个逗号分隔的字符串
String batchUserIds = validUserIds.stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
// 发布一个批量事件在MessageEvent和MessageEventListener中进行处理
eventPublisher.publishEvent(MessageEvent.createWithStringUserId(this, messageVo, batchUserIds));
}
return count;
}

View File

@ -1,6 +1,7 @@
package org.dromara.system.service.impl;
import com.alibaba.fastjson.JSONObject;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.dromara.system.service.ITencentIMService;
import org.springframework.beans.factory.annotation.Value;
@ -8,9 +9,17 @@ import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.Deflater;
import java.util.Base64;
import com.wzj.soopin.member.util.TLSSigAPIv2;
/**
* 腾讯IM服务实现类
@ -21,20 +30,30 @@ import java.util.regex.Pattern;
@Service("systemTencentIMService")
public class TencentIMServiceImpl implements ITencentIMService {
@Value("${tencent.im.sdkappid}")
@Value("${tencent.im.sdk-app-id}")
private long sdkAppId;
@Value("${tencent.im.secretkey}")
@Value("${tencent.im.secret-key}")
private String secretKey;
@Value("${tencent.im.admin}")
@Value("${tencent.im.administrator}")
private String adminAccount;
@Value("${tencent.im.expire-time:180}")
private int expireTime;
private final RestTemplate restTemplate = new RestTemplate();
// 变量替换的正则表达式模式
private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$(\\w+)");
private TLSSigAPIv2 tlsSigApi;
@PostConstruct
private void initTlsSigApi() {
this.tlsSigApi = new TLSSigAPIv2(sdkAppId, secretKey);
}
/**
* 生成用户签名
*
@ -42,28 +61,84 @@ public class TencentIMServiceImpl implements ITencentIMService {
* @return 用户签名
*/
private String generateUserSig(String userId) {
// 注意: 这里需要实现腾讯云IM SDK的TLSSigAPIv2签名生成
// 参考腾讯云文档: https://cloud.tencent.com/document/product/269/32688
// 实现方法:
// 1. 导入腾讯云IM SDK依赖
// 2. 使用sdkAppId和secretKey生成签名
// 示例代码:
// TLSSigAPIv2 tlsSigApi = new TLSSigAPIv2(sdkAppId, secretKey);
// return tlsSigApi.genUserSig(userId, 86400); // 有效期设为1天(86400秒)
log.info("生成用户签名: {}", userId);
// 当前为模拟实现实际项目中请替换为真实签名生成逻辑
// 直接调用官方TLSSigAPIv2生成
return tlsSigApi.genUserSig("administrator", expireTime);
}
/**
* 生成 tls 票据
*
* @param sdkappid 应用的 appid
* @param userId 用户id
* @param expire 有效期 时间戳 单位秒
* @param priKeyContent 私钥文件内容
* @return 通过 base64 编码的 tls 票据
*/
private String genTLSSignature(long sdkappid, String userId, long expire, String priKeyContent) {
try {
// 临时返回一个固定值用于测试
// 注意这是临时方案正式环境必须替换为正确实现
return "eJyrVgrxDXFSsrS0MDA2MzY1NTawNDAzsTQ1sTCyMDI2NdRRKs9ILUpVsjKoLEgsKk7NswlPzYnIsagoyIgrsYl3Lg5IALITi5BkS1JzSlOLbMJKi32DKtNCglONDSNNXfMqk3wN0myrvVUYGBgYGZiaGBoamCgZ6hlYGOUb6Rmaq1QHAAD--wJe";
JSONObject sigDoc = new JSONObject();
sigDoc.put("TLS.ver", "2.0");
sigDoc.put("TLS.identifier", userId);
sigDoc.put("TLS.sdkappid", sdkappid);
sigDoc.put("TLS.expire", expire);
sigDoc.put("TLS.time", System.currentTimeMillis() / 1000);
String base64UserBuf = null;
if (null != userId) {
base64UserBuf = base64EncodeUrl(userId.getBytes(StandardCharsets.UTF_8));
sigDoc.put("TLS.userbuf", base64UserBuf);
}
String sig = hmacSHA256(sdkappid, userId, expire, priKeyContent, base64UserBuf);
if (sig.length() == 0) {
return "";
}
sigDoc.put("TLS.sig", sig);
Deflater compressor = new Deflater();
compressor.setInput(sigDoc.toString().getBytes(StandardCharsets.UTF_8));
compressor.finish();
byte[] compressedBytes = new byte[2048];
int compressedBytesLength = compressor.deflate(compressedBytes);
compressor.end();
return base64EncodeUrl(Arrays.copyOfRange(compressedBytes, 0, compressedBytesLength));
} catch (Exception e) {
log.error("生成用户签名异常", e);
return null;
log.error("生成tls票据异常", e);
return "";
}
}
/**
* 使用 HMAC-SHA256 生成签名
*/
private String hmacSHA256(long sdkappid, String userId, long expire, String priKeyContent, String base64UserBuf) {
try {
String contentToBeSigned = "TLS.identifier:" + "administrator" + "\n"
+ "TLS.sdkappid:" + sdkappid + "\n"
+ "TLS.time:" + System.currentTimeMillis() / 1000 + "\n"
+ "TLS.expire:" + expire + "\n";
if (null != base64UserBuf) {
contentToBeSigned += "TLS.userbuf:" + base64UserBuf + "\n";
}
byte[] byteKey = priKeyContent.getBytes(StandardCharsets.UTF_8);
Mac hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(byteKey, "HmacSHA256");
hmac.init(keySpec);
byte[] byteSig = hmac.doFinal(contentToBeSigned.getBytes(StandardCharsets.UTF_8));
return base64EncodeUrl(byteSig);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
return "";
}
}
/**
* 将字节数组使用 base64 编码URL 安全
*/
private String base64EncodeUrl(byte[] data) {
byte[] encodedBytes = Base64.getEncoder().encode(data);
String encodedStr = new String(encodedBytes);
return encodedStr.replace('+', '*').replace('/', '-').replace('=', '_');
}
/**
* 生成管理员签名
*
@ -92,17 +167,17 @@ public class TencentIMServiceImpl implements ITencentIMService {
Map<String, Object> requestBody = new HashMap<>();
requestBody.put("UserID", userId);
requestBody.put("Nick", userId);
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("创建腾讯IM账号结果: {}", response.getBody());
// 生成并返回用户签名
return generateUserSig(userId);
} catch (Exception e) {
@ -146,13 +221,13 @@ public class TencentIMServiceImpl implements ITencentIMService {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("发送消息到腾讯IM结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = JSONObject.parseObject(response.getBody());
return "OK".equals(responseJson.getString("ActionStatus"));
@ -161,7 +236,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
return false;
}
}
@Override
public boolean pushToAll(String title, String desc, boolean offlinePush, String ext) {
try {
@ -181,12 +256,12 @@ public class TencentIMServiceImpl implements ITencentIMService {
Map<String, Object> msgContent = new HashMap<>();
msgContent.put("Title", title);
msgContent.put("Desc", desc);
// 构建消息体
Map<String, Object> msgBody = new HashMap<>();
msgBody.put("MsgType", "TIMCustomElem");
msgBody.put("MsgContent", msgContent);
// 如果有扩展字段添加到消息内容中
if (ext != null && !ext.isEmpty()) {
msgContent.put("Ext", ext);
@ -197,7 +272,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
requestBody.put("From_Account", adminAccount);
requestBody.put("MsgRandom", Integer.parseInt(random));
requestBody.put("MsgBody", new Object[]{msgBody});
// 设置离线推送信息
if (offlinePush) {
Map<String, Object> offlinePushInfo = new HashMap<>();
@ -211,13 +286,13 @@ public class TencentIMServiceImpl implements ITencentIMService {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("全员推送消息结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = JSONObject.parseObject(response.getBody());
return "OK".equals(responseJson.getString("ActionStatus"));
@ -226,7 +301,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
return false;
}
}
@Override
public boolean pushByAttributes(String title, String desc, Map<String, Object> attributes, boolean offlinePush, String ext) {
try {
@ -246,12 +321,12 @@ public class TencentIMServiceImpl implements ITencentIMService {
Map<String, Object> msgContent = new HashMap<>();
msgContent.put("Title", title);
msgContent.put("Desc", desc);
// 构建消息体
Map<String, Object> msgBody = new HashMap<>();
msgBody.put("MsgType", "TIMCustomElem");
msgBody.put("MsgContent", msgContent);
// 如果有扩展字段添加到消息内容中
if (ext != null && !ext.isEmpty()) {
msgContent.put("Ext", ext);
@ -264,7 +339,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
requestBody.put("MsgBody", new Object[]{msgBody});
requestBody.put("AttrNames", attributes.keySet().toArray(new String[0]));
requestBody.put("AttrValues", attributes.values().toArray());
// 设置离线推送信息
if (offlinePush) {
Map<String, Object> offlinePushInfo = new HashMap<>();
@ -278,13 +353,13 @@ public class TencentIMServiceImpl implements ITencentIMService {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("属性推送消息结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = JSONObject.parseObject(response.getBody());
return "OK".equals(responseJson.getString("ActionStatus"));
@ -293,7 +368,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
return false;
}
}
@Override
public boolean pushByTags(String title, String desc, List<String> tags, boolean offlinePush, String ext) {
try {
@ -313,12 +388,12 @@ public class TencentIMServiceImpl implements ITencentIMService {
Map<String, Object> msgContent = new HashMap<>();
msgContent.put("Title", title);
msgContent.put("Desc", desc);
// 构建消息体
Map<String, Object> msgBody = new HashMap<>();
msgBody.put("MsgType", "TIMCustomElem");
msgBody.put("MsgContent", msgContent);
// 如果有扩展字段添加到消息内容中
if (ext != null && !ext.isEmpty()) {
msgContent.put("Ext", ext);
@ -330,7 +405,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
requestBody.put("MsgRandom", Integer.parseInt(random));
requestBody.put("MsgBody", new Object[]{msgBody});
requestBody.put("TagList", tags);
// 设置离线推送信息
if (offlinePush) {
Map<String, Object> offlinePushInfo = new HashMap<>();
@ -344,13 +419,13 @@ public class TencentIMServiceImpl implements ITencentIMService {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("标签推送消息结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = JSONObject.parseObject(response.getBody());
return "OK".equals(responseJson.getString("ActionStatus"));
@ -359,7 +434,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
return false;
}
}
@Override
public boolean pushToUsers(String title, String desc, List<String> userIds, boolean offlinePush, String ext) {
try {
@ -379,12 +454,12 @@ public class TencentIMServiceImpl implements ITencentIMService {
Map<String, Object> msgContent = new HashMap<>();
msgContent.put("Title", title);
msgContent.put("Desc", desc);
// 构建消息体
Map<String, Object> msgBody = new HashMap<>();
msgBody.put("MsgType", "TIMCustomElem");
msgBody.put("MsgContent", msgContent);
// 如果有扩展字段添加到消息内容中
if (ext != null && !ext.isEmpty()) {
msgContent.put("Ext", ext);
@ -396,7 +471,7 @@ public class TencentIMServiceImpl implements ITencentIMService {
requestBody.put("To_Account", userIds);
requestBody.put("MsgRandom", Integer.parseInt(random));
requestBody.put("MsgBody", new Object[]{msgBody});
// 设置离线推送信息
if (offlinePush) {
Map<String, Object> offlinePushInfo = new HashMap<>();
@ -410,13 +485,13 @@ public class TencentIMServiceImpl implements ITencentIMService {
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// 发送请求
HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
log.info("指定用户推送消息结果: {}", response.getBody());
// 解析响应判断是否成功
JSONObject responseJson = JSONObject.parseObject(response.getBody());
return "OK".equals(responseJson.getString("ActionStatus"));
@ -425,23 +500,23 @@ public class TencentIMServiceImpl implements ITencentIMService {
return false;
}
}
@Override
public String processMessageVariables(String content, Map<String, String> variables) {
if (content == null || variables == null || variables.isEmpty()) {
return content;
}
Matcher matcher = VARIABLE_PATTERN.matcher(content);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String variableName = matcher.group(1);
String replacement = variables.getOrDefault(variableName, "$" + variableName);
matcher.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
matcher.appendTail(sb);
return sb.toString();
}
}
}