修改:私聊消息判断发送状态
This commit is contained in:
parent
2d052ea752
commit
77f3131ef3
|
@ -0,0 +1,28 @@
|
|||
package cn.iocoder.yudao.module.im.enums.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum ImMessageStatusEnum implements IntArrayValuable {
|
||||
|
||||
SENDING(1, "发送中"),
|
||||
SUCCESS(2, "发送成功"),
|
||||
FAILURE(3, "发送失败"),
|
||||
DELETED(4, "已删除"),
|
||||
RECALL(5, "已撤回");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageStatusEnum::getStatus).toArray();
|
||||
private final Integer status;
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +1,21 @@
|
|||
package cn.iocoder.yudao.module.im.enums.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* IM 消息的类型枚举
|
||||
*
|
||||
* <p>
|
||||
* 参考 <a href="https://doc.yunxin.163.com/messaging/docs/zg3NzA3NTA?platform=web#消息类型">“消息类型”</a> 文档
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ImMessageTypeEnum {
|
||||
public enum ImMessageTypeEnum implements IntArrayValuable {
|
||||
|
||||
TEXT(1, "文本"), // 消息内容为普通文本
|
||||
IMAGE(2, "图片"), // 消息内容为图片 URL 地址、尺寸、图片大小等信息
|
||||
|
@ -25,6 +28,7 @@ public enum ImMessageTypeEnum {
|
|||
NOTIFICATION(8, "通知"), // 主要用于群组、聊天室和超大群的事件通知,由服务端下发,客户端无法发送事件通知消息。通知类消息有在线、离线、漫游机制;没有通知栏提醒
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageTypeEnum::getType).toArray();
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
|
@ -34,4 +38,8 @@ public enum ImMessageTypeEnum {
|
|||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.message.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
@ -55,4 +56,7 @@ public class ImMessagePageReqVO extends PageParam {
|
|||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] createTime;
|
||||
|
||||
@Schema(description = "消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Integer messageStatus;
|
||||
|
||||
}
|
|
@ -1,8 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.message.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageTypeEnum;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
@ -46,6 +50,7 @@ public class ImMessageRespVO {
|
|||
|
||||
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("消息类型")
|
||||
@InEnum(ImMessageTypeEnum.class)
|
||||
private Integer contentType;
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
|
@ -64,4 +69,9 @@ public class ImMessageRespVO {
|
|||
@ExcelProperty("创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("消息状态")
|
||||
@InEnum(ImMessageStatusEnum.class)
|
||||
private Integer messageStatus;
|
||||
|
||||
}
|
|
@ -38,7 +38,7 @@ public class ImMessageSaveReqVO {
|
|||
@NotNull(message = "会话类型不能为空")
|
||||
private Integer conversationType;
|
||||
|
||||
@Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "会话标志 conversation_no = a_b", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotEmpty(message = "会话标志不能为空")
|
||||
private String conversationNo;
|
||||
|
||||
|
@ -57,4 +57,7 @@ public class ImMessageSaveReqVO {
|
|||
@NotNull(message = "消息来源 100-用户发送;200-系统发送(一般是通知);不能为空")
|
||||
private Integer sendFrom;
|
||||
|
||||
@Schema(description = "消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@NotNull(message = "消息状态不能为空")
|
||||
private Integer messageStatus;
|
||||
}
|
|
@ -73,4 +73,9 @@ public class ImMessageDO extends BaseDO {
|
|||
*/
|
||||
private Integer sendFrom;
|
||||
|
||||
/**
|
||||
* 消息状态 1 发送中、2 发送成功、3 发送失败、4 已删除、5 已撤回
|
||||
*/
|
||||
private Integer messageStatus;
|
||||
|
||||
}
|
|
@ -61,4 +61,12 @@ public interface ImMessageService {
|
|||
* @return id
|
||||
*/
|
||||
Long savePrivateMessage(ImSendMessage imSendMessage, Long fromUserId);
|
||||
|
||||
/**
|
||||
* 更新消息状态
|
||||
*
|
||||
* @param messageId 消息id
|
||||
* @param messageStatus 消息状态
|
||||
*/
|
||||
void updateMessageStatus(Long messageId, Integer messageStatus);
|
||||
}
|
|
@ -6,10 +6,12 @@ import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessagePageReqVO
|
|||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSaveReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.message.ImMessageMapper;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.hutool.core.date.TimeUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
|
@ -74,22 +76,35 @@ public class ImMessageServiceImpl implements ImMessageService {
|
|||
|
||||
|
||||
@Override
|
||||
public Long savePrivateMessage(ImSendMessage message, Long fromUserId) {
|
||||
public Long savePrivateMessage(ImSendMessage message, Long senderId) {
|
||||
ImMessageSaveReqVO imMessageSaveReqVO = new ImMessageSaveReqVO();
|
||||
imMessageSaveReqVO.setClientMessageId(message.getClientMessageId());
|
||||
imMessageSaveReqVO.setSenderId(fromUserId);
|
||||
imMessageSaveReqVO.setSenderId(senderId);
|
||||
imMessageSaveReqVO.setReceiverId(message.getReceiverId());
|
||||
//查询发送人昵称和发送人头像
|
||||
AdminUserRespDTO user = adminUserApi.getUser(fromUserId);
|
||||
AdminUserRespDTO user = adminUserApi.getUser(senderId);
|
||||
imMessageSaveReqVO.setSenderNickname(user.getNickname());
|
||||
imMessageSaveReqVO.setSenderAvatar(user.getAvatar());
|
||||
imMessageSaveReqVO.setConversationType(message.getConversationType());
|
||||
imMessageSaveReqVO.setContentType(message.getContentType());
|
||||
imMessageSaveReqVO.setConversationNo("1");
|
||||
imMessageSaveReqVO.setConversationNo(senderId + "_" + message.getReceiverId());
|
||||
imMessageSaveReqVO.setContent(message.getContent());
|
||||
//消息来源 100-用户发送;200-系统发送(一般是通知);不能为空
|
||||
imMessageSaveReqVO.setSendFrom(100);
|
||||
imMessageSaveReqVO.setSendTime(TimeUtil.now());
|
||||
imMessageSaveReqVO.setMessageStatus(ImMessageStatusEnum.SENDING.getStatus());
|
||||
return createMessage(imMessageSaveReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMessageStatus(Long messageId, Integer messageStatus) {
|
||||
//校验 id 是否存在
|
||||
validateMessageExists(messageId);
|
||||
//更新消息状态
|
||||
ImMessageDO imMessageDO = new ImMessageDO();
|
||||
imMessageDO.setId(messageId);
|
||||
imMessageDO.setMessageStatus(messageStatus);
|
||||
imMessageMapper.updateById(imMessageDO);
|
||||
}
|
||||
|
||||
}
|
|
@ -3,25 +3,31 @@ package cn.iocoder.yudao.module.im.websocket;
|
|||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener;
|
||||
import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender;
|
||||
import cn.iocoder.yudao.framework.websocket.core.session.WebSocketSessionManager;
|
||||
import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.ImInboxSaveReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceGeneratorRedisDao;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.service.conversation.ImConversationService;
|
||||
import cn.iocoder.yudao.module.im.service.inbox.ImInboxService;
|
||||
import cn.iocoder.yudao.module.im.service.message.ImMessageService;
|
||||
import cn.iocoder.yudao.module.im.websocket.message.ImReceiveMessage;
|
||||
import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* WebSocket 示例:单发消息
|
||||
* WebSocket im
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSendMessage> {
|
||||
|
||||
@Resource
|
||||
|
@ -34,6 +40,8 @@ public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSe
|
|||
private ImInboxService imInboxService;
|
||||
@Resource
|
||||
private SequenceGeneratorRedisDao sequenceGeneratorRedisDao;
|
||||
@Resource
|
||||
private WebSocketSessionManager webSocketSessionManager;
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocketSession session, ImSendMessage message) {
|
||||
|
@ -48,6 +56,14 @@ public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSe
|
|||
imInboxService.createInbox(new ImInboxSaveReqVO(fromUserId, messageId, sequenceGeneratorRedisDao.generateSequence(fromUserId)));
|
||||
|
||||
//3、推送消息
|
||||
// 3.1判断是否在线
|
||||
List<WebSocketSession> sessions = (List<WebSocketSession>) webSocketSessionManager.getSessionList(UserTypeEnum.ADMIN.getValue(), message.getReceiverId());
|
||||
if (sessions.isEmpty()) {
|
||||
//更新消息状态,为发送失败
|
||||
imMessageService.updateMessageStatus(messageId, ImMessageStatusEnum.FAILURE.getStatus());
|
||||
return;
|
||||
}
|
||||
//3.2发送
|
||||
ImReceiveMessage toMessage = new ImReceiveMessage();
|
||||
toMessage.setFromId(fromUserId);
|
||||
toMessage.setConversationType(ImConversationTypeEnum.PRIVATE.getType());
|
||||
|
@ -55,6 +71,9 @@ public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSe
|
|||
toMessage.setContent(message.getContent());
|
||||
webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), message.getReceiverId(), // 给指定用户
|
||||
"im-message-receive", toMessage);
|
||||
//4、更新消息状态,为发送成功
|
||||
imMessageService.updateMessageStatus(messageId, ImMessageStatusEnum.SUCCESS.getStatus());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue