Commit b4ad4ff1 by Future

支持双向撤销,删除消息修改

parent 31427855
...@@ -2,13 +2,14 @@ package com.wecloud.im.controller; ...@@ -2,13 +2,14 @@ package com.wecloud.im.controller;
import com.wecloud.im.param.GetReadersParam; import com.wecloud.im.param.GetReadersParam;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.MsgDeleteParam;
import com.wecloud.im.param.add.ImMsgRecall; import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
import com.wecloud.im.service.ImMessageService; import com.wecloud.im.service.ImMessageService;
import com.wecloud.im.vo.ImMessageOfflineListVo; import com.wecloud.im.vo.ImMessageOfflineListVo;
import com.wecloud.im.vo.OfflineMsgDto; import com.wecloud.im.vo.OfflineMsgDto;
import com.wecloud.im.vo.ReaderList; import com.wecloud.im.vo.ReaderList;
import com.wecloud.im.vo.ReaderVo; import io.geekidea.springbootplus.framework.common.api.ApiCode;
import io.geekidea.springbootplus.framework.common.api.ApiResult; import io.geekidea.springbootplus.framework.common.api.ApiResult;
import io.geekidea.springbootplus.framework.common.controller.BaseController; import io.geekidea.springbootplus.framework.common.controller.BaseController;
import io.geekidea.springbootplus.framework.core.pagination.Paging; import io.geekidea.springbootplus.framework.core.pagination.Paging;
...@@ -17,6 +18,7 @@ import io.geekidea.springbootplus.framework.log.enums.OperationLogType; ...@@ -17,6 +18,7 @@ import io.geekidea.springbootplus.framework.log.enums.OperationLogType;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
...@@ -51,6 +53,21 @@ public class ImMessageController extends BaseController { ...@@ -51,6 +53,21 @@ public class ImMessageController extends BaseController {
} }
/** /**
* 删除消息
*/
@PostMapping("/delete")
@ApiOperation(value = "删除消息", notes = "单条消息与批量消息删除共用")
public ApiResult<Boolean> deleteMsg(@RequestBody MsgDeleteParam param) {
if(param == null) {
return ApiResult.fail(ApiCode.PARAMETER_EXCEPTION, null);
}
if (CollectionUtils.isEmpty(param.getMsgIds())) {
return ApiResult.fail("请选择要删除");
}
return imMessageService.deleteMsg(param);
}
/**
* 修改消息体 * 修改消息体
*/ */
@PostMapping("/updateMsgById") @PostMapping("/updateMsgById")
...@@ -90,61 +107,5 @@ public class ImMessageController extends BaseController { ...@@ -90,61 +107,5 @@ public class ImMessageController extends BaseController {
return ApiResult.ok(readerList); return ApiResult.ok(readerList);
} }
//
// /**
// * 添加消息存储表
// */
// @PostMapping("/add")
// @OperationLog(name = "添加消息存储表", type = OperationLogType.ADD)
// @ApiOperation(value = "添加消息存储表")
// public ApiResult<Boolean> addImMessage(@Validated(Add.class) @RequestBody ImMessage imMessage) throws Exception {
// boolean flag = imMessageService.saveImMessage(imMessage);
// return ApiResult.result(flag);
// }
//
// /**
// * 修改消息存储表
// */
// @PostMapping("/update")
// @OperationLog(name = "修改消息存储表", type = OperationLogType.UPDATE)
// @ApiOperation(value = "修改消息存储表")
// public ApiResult<Boolean> updateImMessage(@Validated(Update.class) @RequestBody ImMessage imMessage) throws Exception {
// boolean flag = imMessageService.updateImMessage(imMessage);
// return ApiResult.result(flag);
// }
//
// /**
// * 删除消息存储表
// */
// @PostMapping("/delete/{id}")
// @OperationLog(name = "删除消息存储表", type = OperationLogType.DELETE)
// @ApiOperation(value = "删除消息存储表")
// public ApiResult<Boolean> deleteImMessage(@PathVariable("id") Long id) throws Exception {
// boolean flag = imMessageService.deleteImMessage(id);
// return ApiResult.result(flag);
// }
//
// /**
// * 获取消息存储表详情
// */
// @GetMapping("/info/{id}")
// @OperationLog(name = "消息存储表详情", type = OperationLogType.INFO)
// @ApiOperation(value = "消息存储表详情")
// public ApiResult<ImMessageQueryVo> getImMessage(@PathVariable("id") Long id) throws Exception {
// ImMessageQueryVo imMessageQueryVo = imMessageService.getImMessageById(id);
// return ApiResult.ok(imMessageQueryVo);
// }
//
// /**
// * 消息存储表分页列表
// */
// @PostMapping("/getPageList")
// @OperationLog(name = "消息存储表分页列表", type = OperationLogType.PAGE)
// @ApiOperation(value = "消息存储表分页列表")
// public ApiResult<Paging<ImMessageQueryVo>> getImMessagePageList(@Validated @RequestBody ImMessagePageParam imMessagePageParam) throws Exception {
// Paging<ImMessageQueryVo> paging = imMessageService.getImMessagePageList(imMessagePageParam);
// return ApiResult.ok(paging);
// }
} }
...@@ -76,4 +76,7 @@ public class ImMessage extends BaseEntity { ...@@ -76,4 +76,7 @@ public class ImMessage extends BaseEntity {
@ApiModelProperty("消息类型") @ApiModelProperty("消息类型")
private Integer msgType; private Integer msgType;
@ApiModelProperty("是否删除 1-未删除 2-已删除")
private Integer isDelete;
} }
...@@ -24,6 +24,10 @@ import java.util.Map; ...@@ -24,6 +24,10 @@ import java.util.Map;
public class ImMessageOnlineSend extends BaseEntity { public class ImMessageOnlineSend extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* 消息类型
* @see com.wecloud.im.ws.enums.MsgTypeEnum
*/
@ApiModelProperty("消息类型") @ApiModelProperty("消息类型")
private Integer type; private Integer type;
......
package com.wecloud.im.param;
import com.wecloud.im.ws.model.request.PushVO;
import io.geekidea.springbootplus.framework.common.entity.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
/**
* @Author wenzhida
* @Date 2022/2/16 10:21
* @Description 消息删除入参
*/
@Data
@EqualsAndHashCode(callSuper = true)
@ApiModel(value = "消息删除入参")
public class MsgDeleteParam extends BaseEntity {
private static final long serialVersionUID = 3930222684211662765L;
@ApiModelProperty("消息id列表")
private List<Long> msgIds;
@ApiModelProperty("自定义推送字段")
private PushVO push;
}
...@@ -7,6 +7,7 @@ import com.wecloud.im.param.ChatContentVo; ...@@ -7,6 +7,7 @@ import com.wecloud.im.param.ChatContentVo;
import com.wecloud.im.param.GetReadersParam; import com.wecloud.im.param.GetReadersParam;
import com.wecloud.im.param.ImClientSimpleDto; import com.wecloud.im.param.ImClientSimpleDto;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.MsgDeleteParam;
import com.wecloud.im.param.add.ImMsgRecall; import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgSendToOnlineClient; import com.wecloud.im.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
...@@ -54,6 +55,13 @@ public interface ImMessageService extends BaseService<ImMessage> { ...@@ -54,6 +55,13 @@ public interface ImMessageService extends BaseService<ImMessage> {
ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall); ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall);
/** /**
* 删除消息
* @param param
* @return
*/
ApiResult<Boolean> deleteMsg(MsgDeleteParam param);
/**
* 修改消息体 * 修改消息体
* *
* @param imMsgUpdate * @param imMsgUpdate
......
...@@ -18,6 +18,7 @@ import com.wecloud.im.param.ChatContentVo; ...@@ -18,6 +18,7 @@ import com.wecloud.im.param.ChatContentVo;
import com.wecloud.im.param.GetReadersParam; import com.wecloud.im.param.GetReadersParam;
import com.wecloud.im.param.ImClientSimpleDto; import com.wecloud.im.param.ImClientSimpleDto;
import com.wecloud.im.param.ImHistoryMessagePageParam; import com.wecloud.im.param.ImHistoryMessagePageParam;
import com.wecloud.im.param.MsgDeleteParam;
import com.wecloud.im.param.add.ImMsgRecall; import com.wecloud.im.param.add.ImMsgRecall;
import com.wecloud.im.param.add.ImMsgSendToOnlineClient; import com.wecloud.im.param.add.ImMsgSendToOnlineClient;
import com.wecloud.im.param.add.ImMsgUpdate; import com.wecloud.im.param.add.ImMsgUpdate;
...@@ -31,6 +32,7 @@ import com.wecloud.im.vo.ImMessageOfflineListVo; ...@@ -31,6 +32,7 @@ import com.wecloud.im.vo.ImMessageOfflineListVo;
import com.wecloud.im.vo.OfflineMsgDto; import com.wecloud.im.vo.OfflineMsgDto;
import com.wecloud.im.vo.ReaderList; import com.wecloud.im.vo.ReaderList;
import com.wecloud.im.vo.ReaderVo; import com.wecloud.im.vo.ReaderVo;
import com.wecloud.im.ws.enums.MsgTypeEnum;
import com.wecloud.im.ws.enums.WsResponseCmdEnum; import com.wecloud.im.ws.enums.WsResponseCmdEnum;
import com.wecloud.im.ws.model.WsResponse; import com.wecloud.im.ws.model.WsResponse;
import com.wecloud.im.ws.model.request.PushVO; import com.wecloud.im.ws.model.request.PushVO;
...@@ -196,20 +198,18 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -196,20 +198,18 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall) { public ApiResult<Boolean> updateMsgWithdrawById(ImMsgRecall imMsgRecall) {
ImClient imClientSender = imClientService.getCurentClient(); ImClient currentClient = imClientService.getCurentClient();
// 查询imApplication // 查询imApplication
ImApplication imApplication = imApplicationService.getCacheById(imClientSender.getFkAppid()); ImApplication imApplication = imApplicationService.getCacheById(currentClient.getFkAppid());
if (imApplication == null) { if (imApplication == null) {
log.info("imApplication为空"); return ApiResult.fail("查无应用信息");
return ApiResult.fail();
} }
// 判断该消息是否是该客户端发送
ImMessage messageById = this.getById(imMsgRecall.getMsgId()); ImMessage messageById = this.getById(imMsgRecall.getMsgId());
if (!messageById.getSender().equals(imClientSender.getId())) { // 判断该消息是否是该客户端发送 todo 单向撤回、双向撤回开关可配置
log.error("判断该消息是否是该客户端发送"); Boolean withdrawOther = true;
return ApiResult.fail(); if (!withdrawOther && !messageById.getSender().equals(currentClient.getId())) {
return ApiResult.fail("不可撤回别人发送的消息");
} }
if (messageById.getWithdraw()) { if (messageById.getWithdraw()) {
return ApiResult.ok(); return ApiResult.ok();
...@@ -223,18 +223,15 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -223,18 +223,15 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
boolean saveOk = this.updateById(messageById); boolean saveOk = this.updateById(messageById);
if (saveOk) { if (saveOk) {
// 查询该会话所有成员 // 查询该会话所有成员
List<ImConversationMembers> membersList = imConversationMembersService.list( List<ImConversationMembers> membersList = imConversationMembersService.list(
new QueryWrapper<ImConversationMembers>().lambda() new QueryWrapper<ImConversationMembers>().lambda()
.eq(ImConversationMembers::getFkConversationId, messageById.getFkConversationId()) .eq(ImConversationMembers::getFkConversationId, messageById.getFkConversationId())
.notIn(ImConversationMembers::getFkClientId, imClientSender.getId()) .notIn(ImConversationMembers::getFkClientId, currentClient.getId())
); );
if (membersList.isEmpty()) { if (membersList.isEmpty()) {
log.info("membersList为空,toConversationId:" + messageById.getFkConversationId()); log.info("membersList为空,toConversationId:" + messageById.getFkConversationId());
return ApiResult.fail(); return ApiResult.fail("该会话成员列表为空");
} }
// 遍历发送 // 遍历发送
for (ImConversationMembers conversationMembers : membersList) { for (ImConversationMembers conversationMembers : membersList) {
...@@ -262,8 +259,9 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -262,8 +259,9 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
// 封装响应的实体 // 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend(); ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(messageById, imMessageOnlineSend); BeanUtils.copyProperties(messageById, imMessageOnlineSend);
imMessageOnlineSend.setType(MsgTypeEnum.MSG_WITHDRAW.getUriCode());
imMessageOnlineSend.setMsgId(messageById.getId()); imMessageOnlineSend.setMsgId(messageById.getId());
imMessageOnlineSend.setSender(imClientSender.getClientId()); imMessageOnlineSend.setSender(currentClient.getClientId());
imMessageOnlineSend.setContent(null); imMessageOnlineSend.setContent(null);
imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId()); imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId());
imMessageOnlineSend.setWithdraw(Boolean.TRUE); imMessageOnlineSend.setWithdraw(Boolean.TRUE);
...@@ -294,6 +292,100 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes ...@@ -294,6 +292,100 @@ public class ImMessageServiceImpl extends BaseServiceImpl<ImMessageMapper, ImMes
} }
@Override @Override
public ApiResult<Boolean> deleteMsg(MsgDeleteParam param) {
ImClient currentClient = imClientService.getCurentClient();
// 查询imApplication
ImApplication imApplication = imApplicationService.getCacheById(currentClient.getFkAppid());
if (imApplication == null) {
return ApiResult.fail("查无应用信息");
}
// todo 单向撤回、双向撤回开关可配置
Boolean deleteOther = true;
List<ImMessage> imMessageList = this.listByIds(param.getMsgIds());
if (CollectionUtils.isEmpty(imMessageList)) {
return ApiResult.fail("查无消息");
}
for (ImMessage message : imMessageList) {
// 判断该消息是否是该客户端发送
if (!deleteOther && !message.getSender().equals(currentClient.getId())) {
return ApiResult.fail("不可删除别人发送的消息");
}
if (message.getIsDelete() == 2) {
continue;
}
// 修改消息体
message.setIsDelete(2);
message.setUpdateDate(new Date());
boolean saveOk = this.updateById(message);
if (saveOk) {
// 查询该会话所有成员
List<ImConversationMembers> membersList = imConversationMembersService.list(
new QueryWrapper<ImConversationMembers>().lambda()
.eq(ImConversationMembers::getFkConversationId, message.getFkConversationId())
.notIn(ImConversationMembers::getFkClientId, currentClient.getId())
);
if (membersList.isEmpty()) {
log.info("membersList为空,toConversationId:" + message.getFkConversationId());
return ApiResult.fail("该会话成员列表为空");
}
// 遍历发送
for (ImConversationMembers conversationMembers : membersList) {
// // 保存收件箱
// long imInboxId = SnowflakeUtil.getId();
// ImInbox imInbox = new ImInbox();
// imInbox.setId(imInboxId);
// imInbox.setCreateTime(new Date());
// imInbox.setFkAppid(imApplication.getId());
// imInbox.setReceiver(conversationMembers.getFkClientId());
// imInbox.setFkMsgId(messageId);
// imInbox.setReadMsgStatus(0);
// imInbox.setReceiverMsgStatus(0);
// imInbox.setFkConversationId(toConversationId);
// imInboxService.save(imInbox);
// 查询接收方
ImClient imClientReceiver = imClientService.getOne(new QueryWrapper<ImClient>().lambda()
.eq(ImClient::getFkAppid, imApplication.getId())
.eq(ImClient::getId, conversationMembers.getFkClientId()));
if (imClientReceiver == null) {
continue;
}
// 封装响应的实体
ImMessageOnlineSend imMessageOnlineSend = new ImMessageOnlineSend();
BeanUtils.copyProperties(message, imMessageOnlineSend);
imMessageOnlineSend.setType(MsgTypeEnum.MSG_DELETE.getUriCode());
imMessageOnlineSend.setMsgId(message.getId());
imMessageOnlineSend.setSender(currentClient.getClientId());
imMessageOnlineSend.setContent(null);
imMessageOnlineSend.setConversationId(conversationMembers.getFkConversationId());
imMessageOnlineSend.setEvent(Boolean.TRUE);
// 向接收方推送
WsResponse<ImMessageOnlineSend> responseModel = new WsResponse<>();
responseModel.setCmd(WsResponseCmdEnum.ONLINE_EVENT_MSG.getCmdCode());
ApiResult<Boolean> result = ApiResult.result(ApiCode.SUCCESS);
responseModel.setCode(result.getCode());
responseModel.setMsg(result.getMessage());
responseModel.setData(imMessageOnlineSend);
responseModel.setReqId(null);
channelSender.sendMsg(responseModel, imClientReceiver.getId());
// 获取自定义推送字段
PushVO pushVO = param.getPush();
// 异步推送系统通知消息
asyncPush.push(pushVO, imClientReceiver, imApplication);
}
return ApiResult.ok();
} else {
return ApiResult.fail("删除消息错误,稍后重试");
}
}
return ApiResult.ok();
}
@Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public ApiResult<Boolean> updateMsgById(ImMsgUpdate imMsgUpdate) { public ApiResult<Boolean> updateMsgById(ImMsgUpdate imMsgUpdate) {
......
...@@ -29,6 +29,12 @@ public enum MsgTypeEnum { ...@@ -29,6 +29,12 @@ public enum MsgTypeEnum {
// 成为新群主 -1013 // 成为新群主 -1013
CONVERSATION_NEW_CREATOR(-1013), CONVERSATION_NEW_CREATOR(-1013),
// 消息撤回 -1016
MSG_WITHDRAW(-1016),
// 消息删除 -1017
MSG_DELETE(-1017),
; ;
private final int uriCode; private final int uriCode;
......
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
WHERE im_inbox.fk_conversation_id = #{conversationId} WHERE im_inbox.fk_conversation_id = #{conversationId}
AND im_inbox.receiver = #{clientId} AND im_inbox.receiver = #{clientId}
AND im_inbox.receiver_msg_status = 0 AND im_inbox.receiver_msg_status = 0
AND im_message.is_delete = 1
</select> </select>
<select id="getHistoryMsgConversationId" resultType="com.wecloud.im.vo.OfflineMsgDto"> <select id="getHistoryMsgConversationId" resultType="com.wecloud.im.vo.OfflineMsgDto">
SELECT im_message.id AS msgId, SELECT im_message.id AS msgId,
...@@ -69,7 +70,7 @@ ...@@ -69,7 +70,7 @@
AND receiver_msg_status = 0) AS not_receiver_count AND receiver_msg_status = 0) AS not_receiver_count
FROM `im_message` FROM `im_message`
INNER JOIN `im_client` ON `im_client`.id = `im_message`.sender INNER JOIN `im_client` ON `im_client`.id = `im_message`.sender
WHERE fk_conversation_id = #{param.conversationId} WHERE fk_conversation_id = #{param.conversationId} and im_message.is_delete = 1
<if test="param.msgIdStart != null"> <if test="param.msgIdStart != null">
AND im_message.id > #{param.msgIdStart} AND im_message.id > #{param.msgIdStart}
</if> </if>
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
AS not_receiver_count AS not_receiver_count
from im_message msg INNER JOIN `im_client` client ON client.id = msg.sender from im_message msg INNER JOIN `im_client` client ON client.id = msg.sender
where where
(msg.fk_conversation_id = #{lastestMsg.conversationId} and msg.id > #{lastestMsg.lastestReceiveMsgId} ) (and msg.is_delete = 1 and msg.fk_conversation_id = #{lastestMsg.conversationId} and msg.id > #{lastestMsg.lastestReceiveMsgId} )
</foreach> </foreach>
......
-- 在feature-cluster 2021年12月22日之后,需要执行的的sql增量脚本 -- 在feature-cluster 2021年12月22日之后,需要执行的的sql增量脚本
...@@ -62,4 +62,6 @@ CREATE TABLE `im_friend_recommend` ...@@ -62,4 +62,6 @@ CREATE TABLE `im_friend_recommend`
-- 2022年01月21日17:31:16 何威 将type参数上移一层 -- 2022年01月21日17:31:16 何威 将type参数上移一层
ALTER TABLE `im_message` ALTER TABLE `im_message`
ADD COLUMN`msg_type` int(2) NULL DEFAULT NULL COMMENT '消息类型' AFTER`send_status`; ADD COLUMN`msg_type` int(2) NULL DEFAULT NULL COMMENT '消息类型' AFTER`send_status`;
\ No newline at end of file
ALTER TABLE im_message ADD COLUMN is_delete tinyint NOT NULL DEFAULT '1' COMMENT '是否删除 1-未删除 2-删除';
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment