修改:代码优化
This commit is contained in:
parent
2b891cb432
commit
fa23ce144d
|
|
@ -6,7 +6,6 @@ import lombok.Getter;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @anhaohao:IM 前缀还是要的哈
|
||||
/**
|
||||
* IM 会话类型枚举
|
||||
* 参考 <a href="https://doc.rentsoft.cn/zh-Hans/sdks/enum/conversationType">“会话类型”</a> 文档
|
||||
|
|
@ -15,13 +14,13 @@ import java.util.Arrays;
|
|||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ConversationTypeEnum implements IntArrayValuable {
|
||||
public enum ImConversationTypeEnum implements IntArrayValuable {
|
||||
|
||||
SINGLE(1, "单聊"),
|
||||
GROUP(3, "群聊"),
|
||||
NOTIFICATION(4, "通知会话");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ConversationTypeEnum::getType).toArray();
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImConversationTypeEnum::getType).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
|
|
@ -33,25 +32,26 @@ public enum ConversationTypeEnum implements IntArrayValuable {
|
|||
*/
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成会话编号 TODO @anhaohao:方法注释,和下面参数之间,要有空格
|
||||
* @param fromUserId 发送者编号
|
||||
* @param receiverId 接收者编号
|
||||
* 生成会话编号
|
||||
*
|
||||
* @param fromUserId 发送者编号
|
||||
* @param receiverId 接收者编号
|
||||
* @param conversationType 会话类型
|
||||
* @return 会话编号
|
||||
*/
|
||||
public static String generateConversationNo(Long fromUserId, Long receiverId, Integer conversationType) {
|
||||
if (conversationType.equals(ConversationTypeEnum.SINGLE.getType())) {
|
||||
if (conversationType.equals(ImConversationTypeEnum.SINGLE.getType())) {
|
||||
return "s_" + fromUserId + "_" + receiverId;
|
||||
} else if (conversationType.equals(ConversationTypeEnum.GROUP.getType())) {
|
||||
} else if (conversationType.equals(ImConversationTypeEnum.GROUP.getType())) {
|
||||
return "g_" + receiverId;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return ARRAYS;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import lombok.Getter;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @anhaohao:IM 前缀还是要的哈
|
||||
/**
|
||||
* IM 消息的类型枚举
|
||||
* <p>
|
||||
|
|
@ -16,7 +15,7 @@ import java.util.Arrays;
|
|||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum MessageContentTypeEnum implements IntArrayValuable {
|
||||
public enum ImMessageContentTypeEnum implements IntArrayValuable {
|
||||
|
||||
TEXT(101, "文本消息"),
|
||||
PICTURE(102, "图片消息"),
|
||||
|
|
@ -57,7 +56,7 @@ public enum MessageContentTypeEnum implements IntArrayValuable {
|
|||
BURN_CHANGE(1701, "阅后即焚开启或关闭通知"),
|
||||
REVOKE(2101, "撤回消息通知");;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageContentTypeEnum::getType).toArray();
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageContentTypeEnum::getType).toArray();
|
||||
|
||||
/**
|
||||
* 类型
|
||||
|
|
@ -6,24 +6,22 @@ import lombok.RequiredArgsConstructor;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @anhaohao:IM 前缀还是要的哈
|
||||
/**
|
||||
* IM 消息的消息来源
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum MessageSourceEnum implements IntArrayValuable {
|
||||
public enum ImMessageSourceEnum implements IntArrayValuable {
|
||||
|
||||
USER_SEND(100, "用户发送"),
|
||||
SYSTEM_SEND(200, "系统发送");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageSourceEnum::getStatus).toArray();
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageSourceEnum::getSource).toArray();
|
||||
|
||||
// TODO @anhaohao:应该是 source
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private final Integer status;
|
||||
private final Integer source;
|
||||
/**
|
||||
* 名字
|
||||
*/
|
||||
|
|
@ -6,27 +6,21 @@ import lombok.RequiredArgsConstructor;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
// TODO @anhaohao:IM 前缀还是要的哈
|
||||
// TODO TODO 状态是这些哈,客户端的视角:
|
||||
//
|
||||
//- 草稿(预留) 0
|
||||
//- 发送中 1
|
||||
//- 发送成功 2
|
||||
//- 发送失败 3
|
||||
//- 已删除 4
|
||||
//- 已撤回 5
|
||||
/**
|
||||
* IM 消息的状态枚举
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum MessageStatusEnum implements IntArrayValuable {
|
||||
public enum ImMessageStatusEnum implements IntArrayValuable {
|
||||
|
||||
DRAFT(0, "草稿"),
|
||||
SENDING(1, "发送中"),
|
||||
SUCCEED(2, "发送成功"),
|
||||
FAILED(3, "发送失败");
|
||||
SUCCESS(2, "发送成功"),
|
||||
FAILURE(3, "发送失败"),
|
||||
DELETED(4, "已删除"),
|
||||
RECALL(5, "已撤回");
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MessageStatusEnum::getStatus).toArray();
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ImMessageStatusEnum::getStatus).toArray();
|
||||
|
||||
/**
|
||||
* 状态
|
||||
|
|
@ -2,10 +2,10 @@ package cn.iocoder.yudao.module.im.controller.admin.conversation;
|
|||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationRespVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
|
||||
import cn.iocoder.yudao.module.im.service.conversation.ConversationService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
|
|
@ -17,13 +17,13 @@ import org.springframework.web.bind.annotation.*;
|
|||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
// TODO @anhaohao:im 前缀少啦
|
||||
@Tag(name = "管理后台 - IM 会话")
|
||||
@RestController
|
||||
@RequestMapping("/im/conversation")
|
||||
@Validated
|
||||
public class ConversationController {
|
||||
public class ImConversationController {
|
||||
|
||||
@Resource
|
||||
private ConversationService conversationService;
|
||||
|
|
@ -31,23 +31,21 @@ public class ConversationController {
|
|||
@GetMapping("/list")
|
||||
@Operation(summary = "获得用户的会话列表")
|
||||
public CommonResult<List<ImConversationRespVO>> getConversationList() {
|
||||
List<ConversationDO> conversationList = conversationService.getConversationList();
|
||||
List<ImConversationDO> conversationList = conversationService.getConversationList();
|
||||
return success(BeanUtils.toBean(conversationList, ImConversationRespVO.class));
|
||||
}
|
||||
|
||||
// TODO @hao:这个接口,需要单独的 VO 哈;
|
||||
@PostMapping("/update-pinned")
|
||||
@Operation(summary = "置顶会话")
|
||||
public CommonResult<Boolean> updatePinned(@Valid @RequestBody ConversationPinnedReqVO updateReqVO) {
|
||||
conversationService.updatePinned(updateReqVO);
|
||||
public CommonResult<Boolean> updatePinned(@Valid @RequestBody ImConversationUpdatePinnedReqVO updateReqVO) {
|
||||
conversationService.updatePinned(getLoginUserId(),updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
// TODO @hao:这个接口,需要单独的 VO 哈;
|
||||
@PostMapping("/update-last-read-time")
|
||||
@Operation(summary = "更新最后已读时间")
|
||||
public CommonResult<Boolean> updateLastReadTime(@Valid @RequestBody ConversationLastTimeReqVO updateReqVO) {
|
||||
conversationService.updateLastReadTime(updateReqVO);
|
||||
public CommonResult<Boolean> updateLastReadTime(@Valid @RequestBody ImConversationUpdateLastReadTimeReqVO updateReqVO) {
|
||||
conversationService.updateLastReadTime(getLoginUserId(),updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.conversation.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @anhaohao:改成 ConversationUpdateLastReadTimeReqVO,项目目前都是动名词哈。更新置顶
|
||||
@Schema(description = "管理后台 - 会话最后已读时间 Request VO")
|
||||
@Data
|
||||
public class ConversationLastTimeReqVO {
|
||||
|
||||
// TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来
|
||||
@Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2")
|
||||
@NotEmpty(message = "会话标志不能为空")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "最后已读时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-01 00:00:00")
|
||||
@NotNull(message = "最后已读时间不能为空")
|
||||
private LocalDateTime lastReadTime;
|
||||
|
||||
// TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户
|
||||
@Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Long targetId;
|
||||
|
||||
@Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了
|
||||
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.conversation.vo;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @anhaohao:改成 ConversationUpdatePinnedReqVO,项目目前都是动名词哈。更新置顶
|
||||
@Schema(description = "管理后台 - 会话置顶 Request VO")
|
||||
@Data
|
||||
public class ConversationPinnedReqVO {
|
||||
|
||||
// TODO @anhaohao:no 不用传递哈。因为 userId + targetId 可以推出来
|
||||
@Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "s_1_2")
|
||||
@NotEmpty(message = "会话标志不能为空")
|
||||
private String no;
|
||||
|
||||
@Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "是否置顶不能为空")
|
||||
private Boolean pinned;
|
||||
|
||||
// TODO @anhaohao:userId 不用传递,因为 token 已经能解析出当前用户
|
||||
@Schema(description = "所属用户", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Long targetId;
|
||||
|
||||
@Schema(description = "会话类型",requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer type; // 枚举 ConversationTypeEnum TODO ,这里可以使用 @InEnum 校验,这样这个注释就不用写了
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.conversation.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 会话最后已读时间 Request VO")
|
||||
@Data
|
||||
public class ImConversationUpdateLastReadTimeReqVO {
|
||||
|
||||
@Schema(description = "最后已读时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-01 00:00:00")
|
||||
@NotNull(message = "最后已读时间不能为空")
|
||||
private LocalDateTime lastReadTime;
|
||||
|
||||
@Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Long targetId;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(value = ImConversationTypeEnum.class, message = "会话类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.conversation.vo;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - 会话置顶 Request VO")
|
||||
@Data
|
||||
public class ImConversationUpdatePinnedReqVO {
|
||||
|
||||
@Schema(description = "是否置顶", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "是否置顶不能为空")
|
||||
private Boolean pinned;
|
||||
|
||||
@Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Long targetId;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(value = ImConversationTypeEnum.class, message = "会话类型必须是 {value}")
|
||||
private Integer type;
|
||||
|
||||
}
|
||||
|
|
@ -25,8 +25,8 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO;
|
||||
import cn.iocoder.yudao.module.im.service.group.ImGroupService;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
|
||||
import cn.iocoder.yudao.module.im.service.group.GroupService;
|
||||
|
||||
// TODO @芋艿:得看看 create、update、delete、get、page 这几个接口,要保留哪些
|
||||
@Tag(name = "管理后台 - 群")
|
||||
|
|
@ -36,20 +36,20 @@ import cn.iocoder.yudao.module.im.service.group.ImGroupService;
|
|||
public class ImGroupController {
|
||||
|
||||
@Resource
|
||||
private ImGroupService imGroupService;
|
||||
private GroupService groupService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建群")
|
||||
@PreAuthorize("@ss.hasPermission('im:group:create')")
|
||||
public CommonResult<Long> createGroup(@Valid @RequestBody ImGroupSaveReqVO createReqVO) {
|
||||
return success(imGroupService.createGroup(createReqVO));
|
||||
return success(groupService.createGroup(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "更新群")
|
||||
@PreAuthorize("@ss.hasPermission('im:group:update')")
|
||||
public CommonResult<Boolean> updateGroup(@Valid @RequestBody ImGroupSaveReqVO updateReqVO) {
|
||||
imGroupService.updateGroup(updateReqVO);
|
||||
groupService.updateGroup(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ public class ImGroupController {
|
|||
@Parameter(name = "id", description = "编号", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('im:group:delete')")
|
||||
public CommonResult<Boolean> deleteGroup(@RequestParam("id") Long id) {
|
||||
imGroupService.deleteGroup(id);
|
||||
groupService.deleteGroup(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ public class ImGroupController {
|
|||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('im:group:query')")
|
||||
public CommonResult<ImGroupRespVO> getGroup(@RequestParam("id") Long id) {
|
||||
GroupDO group = imGroupService.getGroup(id);
|
||||
ImGroupDO group = groupService.getGroup(id);
|
||||
return success(BeanUtils.toBean(group, ImGroupRespVO.class));
|
||||
}
|
||||
|
||||
|
|
@ -75,22 +75,8 @@ public class ImGroupController {
|
|||
@Operation(summary = "获得群分页")
|
||||
@PreAuthorize("@ss.hasPermission('im:group:query')")
|
||||
public CommonResult<PageResult<ImGroupRespVO>> getGroupPage(@Valid ImGroupPageReqVO pageReqVO) {
|
||||
PageResult<GroupDO> pageResult = imGroupService.getGroupPage(pageReqVO);
|
||||
PageResult<ImGroupDO> pageResult = groupService.getGroupPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ImGroupRespVO.class));
|
||||
}
|
||||
|
||||
// TODO @anhaohao:导出可以先不做哈;
|
||||
@GetMapping("/export-excel")
|
||||
@Operation(summary = "导出群 Excel")
|
||||
@PreAuthorize("@ss.hasPermission('im:group:export')")
|
||||
@OperateLog(type = EXPORT)
|
||||
public void exportGroupExcel(@Valid ImGroupPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<GroupDO> list = imGroupService.getGroupPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "群.xls", "数据", ImGroupRespVO.class,
|
||||
BeanUtils.toBean(list, ImGroupRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberRespVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
|
|
@ -66,7 +66,7 @@ public class ImGroupMemberController {
|
|||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('im:group-member:query')")
|
||||
public CommonResult<ImGroupMemberRespVO> getGroupMember(@RequestParam("id") Long id) {
|
||||
GroupMemberDO groupMember = groupMemberService.getGroupMember(id);
|
||||
ImGroupMemberDO groupMember = groupMemberService.getGroupMember(id);
|
||||
return success(BeanUtils.toBean(groupMember, ImGroupMemberRespVO.class));
|
||||
}
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ public class ImGroupMemberController {
|
|||
@Operation(summary = "获得群成员分页")
|
||||
@PreAuthorize("@ss.hasPermission('im:group-member:query')")
|
||||
public CommonResult<PageResult<ImGroupMemberRespVO>> getGroupMemberPage(@Valid ImGroupMemberPageReqVO pageReqVO) {
|
||||
PageResult<GroupMemberDO> pageResult = groupMemberService.getGroupMemberPage(pageReqVO);
|
||||
PageResult<ImGroupMemberDO> pageResult = groupMemberService.getGroupMemberPage(pageReqVO);
|
||||
return success(BeanUtils.toBean(pageResult, ImGroupMemberRespVO.class));
|
||||
}
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ public class ImGroupMemberController {
|
|||
public void exportGroupMemberExcel(@Valid ImGroupMemberPageReqVO pageReqVO,
|
||||
HttpServletResponse response) throws IOException {
|
||||
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||
List<GroupMemberDO> list = groupMemberService.getGroupMemberPage(pageReqVO).getList();
|
||||
List<ImGroupMemberDO> list = groupMemberService.getGroupMemberPage(pageReqVO).getList();
|
||||
// 导出 Excel
|
||||
ExcelUtils.write(response, "群成员.xls", "数据", ImGroupMemberRespVO.class,
|
||||
BeanUtils.toBean(list, ImGroupMemberRespVO.class));
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.inbox.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @anhaohao:im 前缀哈
|
||||
@Schema(description = "管理后台 - 收件箱保存消息 Request VO")
|
||||
@Data
|
||||
public class InboxSaveMessageReqVO {
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer conversationType; // 对应 ImConversationTypeEnum 枚举
|
||||
|
||||
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long fromId; // 根据 conversationType 区分
|
||||
|
||||
@Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
private String senderNickname;
|
||||
|
||||
@Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String senderAvatar;
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
|
||||
private Long receiverId;
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
|
||||
private Long messageId;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer contentType; // 参见 ImMessageTypeEnum 枚举
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
// @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
// private Long sequence;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/**
|
||||
* @author anhaohao
|
||||
* @since 2024/3/31 下午10:41
|
||||
*/
|
||||
package cn.iocoder.yudao.module.im.controller.admin.inbox.vo;
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendRespVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import cn.iocoder.yudao.module.im.service.message.MessageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - IM 消息")
|
||||
@RestController
|
||||
@RequestMapping("/im/message")
|
||||
@Validated
|
||||
public class ImMessageController {
|
||||
|
||||
@Resource
|
||||
private MessageService messageService;
|
||||
|
||||
@PostMapping("/send")
|
||||
@Operation(summary = "发送消息")
|
||||
public CommonResult<ImMessageSendRespVO> sendMessage(@Valid @RequestBody ImMessageSendReqVO imMessageSendReqVO) {
|
||||
ImMessageDO message = messageService.sendMessage(getLoginUserId(), imMessageSendReqVO);
|
||||
return success(BeanUtils.toBean(message, ImMessageSendRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/pull")
|
||||
@Operation(summary = "消息列表-拉取大于 sequence 的消息列表")
|
||||
@Parameter(name = "sequence", description = "序号", required = true, example = "1")
|
||||
@Parameter(name = "size", description = "条数", required = true, example = "10")
|
||||
public CommonResult<List<ImMessageRespVO>> pullMessageList(@RequestParam("sequence") Long sequence,
|
||||
@RequestParam("size") Integer size) {
|
||||
List<ImMessageDO> messages = messageService.pullMessageList(getLoginUserId(), sequence, size);
|
||||
return success(BeanUtils.toBean(messages, ImMessageRespVO.class));
|
||||
}
|
||||
|
||||
@GetMapping("/list")
|
||||
@Operation(summary = "消息列表-根据接收人和发送时间进行分页查询")
|
||||
public CommonResult<List<ImMessageRespVO>> getMessageList(@Valid ImMessageListReqVO listReqVO) {
|
||||
List<ImMessageDO> messagePage = messageService.getMessageList(getLoginUserId(), listReqVO);
|
||||
return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.service.message.MessageService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||
|
||||
@Tag(name = "管理后台 - IM 消息")
|
||||
@RestController
|
||||
@RequestMapping("/im/message")
|
||||
@Validated
|
||||
public class MessageController {
|
||||
|
||||
@Resource
|
||||
private MessageService messageService;
|
||||
|
||||
@PostMapping("/send")
|
||||
@Operation(summary = "发送消息")
|
||||
public CommonResult<SendMessageRespVO> sendMessage(@Valid @RequestBody SendMessageReqVO message) {
|
||||
return success(messageService.sendMessage(getLoginUserId(), message));
|
||||
}
|
||||
|
||||
// TODO @anhaohao:我在想,这个接口,改成叫 pullMessageList,会不会更好理解?拉取消息列表
|
||||
@GetMapping("/list-by-sequence")
|
||||
@Operation(summary = "拉取大于 sequence 的消息列表")
|
||||
@Parameter(name = "sequence", description = "序号", required = true, example = "1")
|
||||
@Parameter(name = "size", description = "条数", required = true, example = "10")
|
||||
public CommonResult<List<MessageReqVO>> getMessageListBySequence(@RequestParam("sequence") Long sequence,
|
||||
@RequestParam("size") Integer size) {
|
||||
List<MessageDO> messages = messageService.getMessageListBySequence(getLoginUserId(), sequence, size);
|
||||
return success(BeanUtils.toBean(messages, MessageReqVO.class));
|
||||
}
|
||||
|
||||
// TODO @anhaohao:直接叫 getMessageList,不叫历史哈;因为它只是给用户叫历史,对系统来说,就是消息列表
|
||||
@GetMapping("/history")
|
||||
@Operation(summary = "查询聊天记录-根据会话标志和发送时间进行分页查询")
|
||||
public CommonResult<List<MessageReqVO>> getHistoryMessage(@Valid MessagePageReqVO pageReqVO) {
|
||||
//根据会话标志和发送时间进行分页查询
|
||||
List<MessageDO> messagePage = messageService.getHistoryMessage(pageReqVO);
|
||||
return success(BeanUtils.toBean(messagePage, MessageReqVO.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
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.conversation.ImConversationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||
|
||||
@Schema(description = "管理后台 - 消息列表 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class ImMessageListReqVO {
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
|
||||
@NotNull(message = "接收人编号不能为空")
|
||||
private Long receiverId;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@InEnum(value = ImConversationTypeEnum.class,message = "会话类型必须是 {value}")
|
||||
@NotNull(message = "会话类型不能为空")
|
||||
private Integer conversationType;
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,42 +1,47 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.inbox.vo;
|
||||
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.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 收件箱保存消息 Request VO")
|
||||
@Schema(description = "管理后台 - 消息 Response VO")
|
||||
@Data
|
||||
public class InboxSendMessageReqVO {
|
||||
public class ImMessageRespVO {
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer conversationType; // 对应 ImConversationTypeEnum 枚举
|
||||
@InEnum(value = ImConversationTypeEnum.class)
|
||||
private Integer conversationType;
|
||||
|
||||
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long fromId; // 根据 conversationType 区分
|
||||
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long senderId;
|
||||
|
||||
@Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
private String senderNickname;
|
||||
|
||||
@Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://www.iocoder.cn/xxx.jpg")
|
||||
private String senderAvatar;
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
private Long receiverId;
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
|
||||
private Long messageId;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer contentType; // 参见 ImMessageTypeEnum 枚举
|
||||
@InEnum(value = ImMessageContentTypeEnum.class)
|
||||
private Integer contentType;
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好")
|
||||
private String content;
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00")
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Long sequence;
|
||||
|
||||
}
|
||||
|
|
@ -1,40 +1,36 @@
|
|||
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.MessageContentTypeEnum;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
// TODO @anhaohao:MessageSendReqVO,消息发送
|
||||
|
||||
// TODO @anhaohao:不应该有 excel 相关的注解
|
||||
|
||||
@Schema(description = "管理后台 - 发送消息 Request VO")
|
||||
@Data
|
||||
@ExcelIgnoreUnannotated
|
||||
public class SendMessageReqVO {
|
||||
public class ImMessageSendReqVO {
|
||||
|
||||
@Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331")
|
||||
@ExcelProperty("客户端消息编号 uuid,用于排重")
|
||||
@NotNull(message = "客户端消息编号不能为空")
|
||||
private String clientMessageId;
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
|
||||
@ExcelProperty("接收人编号")
|
||||
@NotNull(message = "接收人编号不能为空")
|
||||
private Long receiverId;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
|
||||
@ExcelProperty("会话类型")
|
||||
@InEnum(value = ImConversationTypeEnum.class)
|
||||
@NotNull(message = "会话类型不能为空")
|
||||
private Integer conversationType;
|
||||
|
||||
@Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@ExcelProperty("消息类型")
|
||||
@InEnum(MessageContentTypeEnum.class)
|
||||
@InEnum(ImMessageContentTypeEnum.class)
|
||||
@NotNull(message = "消息类型不能为空")
|
||||
private Integer contentType;
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("消息内容")
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好")
|
||||
@NotNull(message = "消息内容不能为空")
|
||||
private String content;
|
||||
|
||||
}
|
||||
|
|
@ -10,13 +10,11 @@ import java.time.LocalDateTime;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
// TODO @anhaohao:MessageSendRespVO,消息发送结果
|
||||
|
||||
@Schema(description = "管理后台 - 发送消息 Response VO")
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class SendMessageRespVO {
|
||||
public class ImMessageSendRespVO {
|
||||
|
||||
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12")
|
||||
private Long id;
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.controller.admin.message.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.ToString;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
// TODO @anhaohao:这个类,不要交 Page,而是消息列表,MessageListReqVO
|
||||
@Schema(description = "管理后台 - 消息分页 Request VO")
|
||||
@Data
|
||||
@ToString(callSuper = true)
|
||||
public class MessagePageReqVO {
|
||||
|
||||
// TODO @anhaohao:还是传递 targetId 和 conversationType,我们要弱化 no 的概念;
|
||||
|
||||
@Schema(description = "会话标志", requiredMode = Schema.RequiredMode.REQUIRED, example = "g_1000")
|
||||
private String conversationNo;
|
||||
|
||||
// TODO @anhaohao:应该不传递时间范围,而是传递分页的时间,然后根据时间,查询消息
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27")
|
||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||
private LocalDateTime[] sendTime;
|
||||
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
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.MessageContentTypeEnum;
|
||||
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||
|
||||
// TODO @anhaohao:MessageRespVO 消息响应 Response VO
|
||||
// TODO @anahaohao:每个 example 都写下;啊哈,漏了地方,要补下;因为 http mock 的时候,可以根据它去生成
|
||||
@Schema(description = "管理后台 - 消息 Request VO")
|
||||
@Data
|
||||
public class MessageReqVO {
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer conversationType; // 对应 ImConversationTypeEnum 枚举
|
||||
|
||||
// TODO @anhaohao:这个应该是 senderId
|
||||
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long fromId; // 根据 conversationType 区分
|
||||
|
||||
@Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
|
||||
private String senderNickname;
|
||||
|
||||
@Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String senderAvatar;
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494")
|
||||
private Long receiverId;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer contentType; // 参见 ImMessageTypeEnum 枚举
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long sequence;
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.conversation;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
|
@ -9,7 +9,6 @@ import lombok.*;
|
|||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @anhaohao:还是有 IM 前缀哈
|
||||
/**
|
||||
* IM 会话 DO
|
||||
*
|
||||
|
|
@ -23,7 +22,7 @@ import java.time.LocalDateTime;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ConversationDO extends BaseDO {
|
||||
public class ImConversationDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
|
@ -39,7 +38,7 @@ public class ConversationDO extends BaseDO {
|
|||
/**
|
||||
* 会话类型
|
||||
* <p>
|
||||
* 枚举 {@link ConversationTypeEnum}
|
||||
* 枚举 {@link ImConversationTypeEnum}
|
||||
*/
|
||||
private Integer type;
|
||||
/**
|
||||
|
|
@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
|||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
// TODO @anhaohao:还是要有 IM
|
||||
/**
|
||||
* IM 群信息 DO
|
||||
*
|
||||
|
|
@ -20,7 +19,7 @@ import lombok.*;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GroupDO extends BaseDO {
|
||||
public class ImGroupDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
|
@ -4,7 +4,6 @@ import lombok.*;
|
|||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
|
||||
// TODO @anhaohao:还是要有 IM
|
||||
/**
|
||||
* IM 群成员 DO
|
||||
*
|
||||
|
|
@ -18,7 +17,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class GroupMemberDO extends BaseDO {
|
||||
public class ImGroupMemberDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.inbox;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
|
||||
// TODO @anhaohao:还是要有 IM
|
||||
// TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列;
|
||||
|
||||
/**
|
||||
* IM 收件箱 DO
|
||||
*
|
||||
|
|
@ -22,7 +22,7 @@ import lombok.*;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class InboxDO extends BaseDO {
|
||||
public class ImInboxDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
|
@ -31,14 +31,14 @@ public class InboxDO extends BaseDO {
|
|||
private Long id;
|
||||
/**
|
||||
* 用户编号
|
||||
*
|
||||
* TODO @hao:写下 userId 和 messageId 的关联字段
|
||||
* <p>
|
||||
* 关联 {@link ImMessageDO#getSenderId()} 或者 {@link ImMessageDO#getReceiverId()}
|
||||
*/
|
||||
private Long userId;
|
||||
/**
|
||||
* 消息编号
|
||||
*
|
||||
* 关联 {@link MessageDO#getId()}
|
||||
* <p>
|
||||
* 关联 {@link ImMessageDO#getId()}
|
||||
*/
|
||||
private Long messageId;
|
||||
/**
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageSourceEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageSourceEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
|
||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
|
@ -12,7 +12,6 @@ import lombok.*;
|
|||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
// TODO @anhaohao:还是要有 IM
|
||||
/**
|
||||
* IM 消息 DO
|
||||
*
|
||||
|
|
@ -26,7 +25,7 @@ import java.time.LocalDateTime;
|
|||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MessageDO extends BaseDO {
|
||||
public class ImMessageDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* 编号
|
||||
|
|
@ -60,24 +59,24 @@ public class MessageDO extends BaseDO {
|
|||
*/
|
||||
private String senderAvatar;
|
||||
/**
|
||||
* 会话类型 枚举 {@link ConversationTypeEnum}
|
||||
* 会话类型 枚举 {@link ImConversationTypeEnum}
|
||||
*/
|
||||
private Integer conversationType;
|
||||
/**
|
||||
* 会话标志
|
||||
*
|
||||
* 生成规则:{@link ConversationTypeEnum#generateConversationNo(Long, Long, Integer)} 方法
|
||||
* <p>
|
||||
* 生成规则:{@link ImConversationTypeEnum#generateConversationNo(Long, Long, Integer)} 方法
|
||||
*/
|
||||
private String conversationNo;
|
||||
/**
|
||||
* 消息类型
|
||||
*
|
||||
* 枚举 {@link MessageContentTypeEnum}
|
||||
* <p>
|
||||
* 枚举 {@link ImMessageContentTypeEnum}
|
||||
*/
|
||||
private Integer contentType;
|
||||
/**
|
||||
* 消息内容
|
||||
*
|
||||
* <p>
|
||||
* JSON 格式 对应 dal/dataobject/message/content 包
|
||||
*/
|
||||
private String content;
|
||||
|
|
@ -87,14 +86,14 @@ public class MessageDO extends BaseDO {
|
|||
private LocalDateTime sendTime;
|
||||
/**
|
||||
* 消息来源
|
||||
*
|
||||
* 枚举 {@link MessageSourceEnum}
|
||||
* <p>
|
||||
* 枚举 {@link ImMessageSourceEnum}
|
||||
*/
|
||||
private Integer sendFrom;
|
||||
/**
|
||||
* 消息状态
|
||||
*
|
||||
* 枚举 {@link MessageStatusEnum}
|
||||
* <p>
|
||||
* 枚举 {@link ImMessageStatusEnum}
|
||||
*/
|
||||
private Integer messageStatus;
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
|
@ -8,7 +8,7 @@ import lombok.NoArgsConstructor;
|
|||
// TODO @anhaohao:要有 IM;
|
||||
// TODO @芋艿:后续要挪到 api 包下,主要是给外部接口使用
|
||||
/**
|
||||
* 语音消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 语音消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 名片消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 名片消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author anhaohao
|
||||
* @since 2024/3/23 下午5:53
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 文件消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 文件消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 图片消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 图片消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 地址位置消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 地址位置消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 文本消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 文本消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package cn.iocoder.yudao.module.im.dal.dataobject.message.content;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 视频消息的 {@link MessageDO 字段 content} 的内容
|
||||
* 视频消息的 {@link ImMessageDO 字段 content} 的内容
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
package cn.iocoder.yudao.module.im.dal.mysql.conversation;
|
||||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
|
|
@ -11,9 +10,9 @@ import org.apache.ibatis.annotations.Mapper;
|
|||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ConversationMapper extends BaseMapperX<ConversationDO> {
|
||||
public interface ConversationMapper extends BaseMapperX<ImConversationDO> {
|
||||
|
||||
default ConversationDO selectByNo(String no){
|
||||
return selectOne(ConversationDO::getNo, no);
|
||||
default ImConversationDO selectByNo(String no){
|
||||
return selectOne(ImConversationDO::getNo, no);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package cn.iocoder.yudao.module.im.dal.mysql.group;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
|
||||
|
||||
/**
|
||||
* 群 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface GroupMapper extends BaseMapperX<ImGroupDO> {
|
||||
|
||||
default PageResult<ImGroupDO> selectPage(ImGroupPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ImGroupDO>()
|
||||
.likeIfPresent(ImGroupDO::getGroupName, reqVO.getGroupName())
|
||||
.eqIfPresent(ImGroupDO::getOwnerId, reqVO.getOwnerId())
|
||||
.eqIfPresent(ImGroupDO::getHeadImage, reqVO.getHeadImage())
|
||||
.eqIfPresent(ImGroupDO::getHeadImageThumb, reqVO.getHeadImageThumb())
|
||||
.eqIfPresent(ImGroupDO::getNotice, reqVO.getNotice())
|
||||
.eqIfPresent(ImGroupDO::getRemark, reqVO.getRemark())
|
||||
.betweenIfPresent(ImGroupDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(ImGroupDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.dal.mysql.group;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
|
||||
|
||||
/**
|
||||
* 群 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ImGroupMapper extends BaseMapperX<GroupDO> {
|
||||
|
||||
default PageResult<GroupDO> selectPage(ImGroupPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<GroupDO>()
|
||||
.likeIfPresent(GroupDO::getGroupName, reqVO.getGroupName())
|
||||
.eqIfPresent(GroupDO::getOwnerId, reqVO.getOwnerId())
|
||||
.eqIfPresent(GroupDO::getHeadImage, reqVO.getHeadImage())
|
||||
.eqIfPresent(GroupDO::getHeadImageThumb, reqVO.getHeadImageThumb())
|
||||
.eqIfPresent(GroupDO::getNotice, reqVO.getNotice())
|
||||
.eqIfPresent(GroupDO::getRemark, reqVO.getRemark())
|
||||
.betweenIfPresent(GroupDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(GroupDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package cn.iocoder.yudao.module.im.dal.mysql.groupmember;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 群成员 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface GroupMemberMapper extends BaseMapperX<ImGroupMemberDO> {
|
||||
|
||||
default PageResult<ImGroupMemberDO> selectPage(ImGroupMemberPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<ImGroupMemberDO>()
|
||||
.eqIfPresent(ImGroupMemberDO::getGroupId, reqVO.getGroupId())
|
||||
.eqIfPresent(ImGroupMemberDO::getUserId, reqVO.getUserId())
|
||||
.likeIfPresent(ImGroupMemberDO::getNickname, reqVO.getNickname())
|
||||
.eqIfPresent(ImGroupMemberDO::getAvatar, reqVO.getAvatar())
|
||||
.likeIfPresent(ImGroupMemberDO::getAliasName, reqVO.getAliasName())
|
||||
.eqIfPresent(ImGroupMemberDO::getRemark, reqVO.getRemark())
|
||||
.betweenIfPresent(ImGroupMemberDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(ImGroupMemberDO::getId));
|
||||
}
|
||||
|
||||
default List<ImGroupMemberDO> selectListByGroupId(Long groupId) {
|
||||
return selectList(new LambdaQueryWrapperX<ImGroupMemberDO>().eq(ImGroupMemberDO::getGroupId, groupId));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.dal.mysql.groupmember;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 群成员 Mapper
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface ImGroupMemberMapper extends BaseMapperX<GroupMemberDO> {
|
||||
|
||||
default PageResult<GroupMemberDO> selectPage(ImGroupMemberPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<GroupMemberDO>()
|
||||
.eqIfPresent(GroupMemberDO::getGroupId, reqVO.getGroupId())
|
||||
.eqIfPresent(GroupMemberDO::getUserId, reqVO.getUserId())
|
||||
.likeIfPresent(GroupMemberDO::getNickname, reqVO.getNickname())
|
||||
.eqIfPresent(GroupMemberDO::getAvatar, reqVO.getAvatar())
|
||||
.likeIfPresent(GroupMemberDO::getAliasName, reqVO.getAliasName())
|
||||
.eqIfPresent(GroupMemberDO::getRemark, reqVO.getRemark())
|
||||
.betweenIfPresent(GroupMemberDO::getCreateTime, reqVO.getCreateTime())
|
||||
.orderByDesc(GroupMemberDO::getId));
|
||||
}
|
||||
|
||||
default List<GroupMemberDO> selectListByGroupId(Long groupId) {
|
||||
return selectList(new LambdaQueryWrapperX<GroupMemberDO>().eq(GroupMemberDO::getGroupId, groupId));
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.im.dal.mysql.inbox;
|
|||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -13,27 +13,14 @@ import java.util.List;
|
|||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface InboxMapper extends BaseMapperX<InboxDO> {
|
||||
public interface InboxMapper extends BaseMapperX<ImInboxDO> {
|
||||
|
||||
// TODO @anhaohao:返回 List<InboxDO> ,转换成 messageId 交给上层;dao 尽量通用
|
||||
default List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) {
|
||||
return selectList(new LambdaQueryWrapperX<InboxDO>()
|
||||
.gt(InboxDO::getUserId, userId)
|
||||
.gt(InboxDO::getSequence, sequence)
|
||||
.orderByAsc(InboxDO::getSequence)
|
||||
.last("limit 0," + size)) // TODO @anhaohao:这里 limit 就可以了,不用从 limit 0 开始;
|
||||
.stream()
|
||||
.map(InboxDO::getMessageId)
|
||||
.toList();
|
||||
default List<ImInboxDO> selectListByUserIdAndSequence(Long userId, Long sequence, Integer size) {
|
||||
return selectList(new LambdaQueryWrapperX<ImInboxDO>()
|
||||
.gt(ImInboxDO::getUserId, userId)
|
||||
.gt(ImInboxDO::getSequence, sequence)
|
||||
.orderByAsc(ImInboxDO::getSequence)
|
||||
.last("LIMIT " + size));
|
||||
}
|
||||
|
||||
// default PageResult<InboxDO> selectPage(ImInboxPageReqVO reqVO) {
|
||||
// return selectPage(reqVO, new LambdaQueryWrapperX<InboxDO>()
|
||||
// .eqIfPresent(InboxDO::getUserId, reqVO.getUserId())
|
||||
// .eqIfPresent(InboxDO::getMessageId, reqVO.getMessageId())
|
||||
// .eqIfPresent(InboxDO::getSequence, reqVO.getSequence())
|
||||
// .betweenIfPresent(InboxDO::getCreateTime, reqVO.getCreateTime())
|
||||
// .orderByDesc(InboxDO::getId));
|
||||
// }
|
||||
|
||||
}
|
||||
|
|
@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.im.dal.mysql.message;
|
|||
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -16,13 +13,12 @@ import java.util.List;
|
|||
* @author 芋道源码
|
||||
*/
|
||||
@Mapper
|
||||
public interface MessageMapper extends BaseMapperX<MessageDO> {
|
||||
public interface MessageMapper extends BaseMapperX<ImMessageDO> {
|
||||
|
||||
default List<MessageDO> getHistoryMessage(MessagePageReqVO pageReqVO) {
|
||||
return selectList(new LambdaQueryWrapperX<MessageDO>()
|
||||
.eqIfPresent(MessageDO::getConversationNo, pageReqVO.getConversationNo())
|
||||
.betweenIfPresent(MessageDO::getSendTime, pageReqVO.getSendTime())
|
||||
.orderByAsc(MessageDO::getSendTime));
|
||||
default List<ImMessageDO> selectMessageList(ImMessageDO message) {
|
||||
return selectList(new LambdaQueryWrapperX<ImMessageDO>()
|
||||
.eqIfPresent(ImMessageDO::getConversationNo, message.getConversationNo())
|
||||
.eqIfPresent(ImMessageDO::getSendTime, message.getSendTime())
|
||||
.orderByAsc(ImMessageDO::getSendTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
package cn.iocoder.yudao.module.im.dal.redis.inbox;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import org.redisson.api.RedissonClient;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
|
|
@ -15,7 +14,7 @@ import static cn.iocoder.yudao.module.im.dal.redis.RedisKeyConstants.INBOX_SEQUE
|
|||
* @author anhaohao
|
||||
*/
|
||||
@Repository
|
||||
public class SequenceRedisDao {
|
||||
public class SequenceRedisDAO {
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String, Long> redisTemplate;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
package cn.iocoder.yudao.module.im.service.conversation;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -18,20 +18,22 @@ public interface ConversationService {
|
|||
*
|
||||
* @return 会话列表
|
||||
*/
|
||||
List<ConversationDO> getConversationList();
|
||||
List<ImConversationDO> getConversationList();
|
||||
|
||||
/**
|
||||
* 置顶会话
|
||||
*
|
||||
* @param loginUserId 登录用户编号
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updatePinned(ConversationPinnedReqVO updateReqVO);
|
||||
void updatePinned(Long loginUserId, ImConversationUpdatePinnedReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 更新最后已读时间
|
||||
*
|
||||
* @param loginUserId 登录用户编号
|
||||
* @param updateReqVO 更新信息
|
||||
*/
|
||||
void updateLastReadTime(ConversationLastTimeReqVO updateReqVO);
|
||||
void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO);
|
||||
|
||||
}
|
||||
|
|
@ -1,10 +1,10 @@
|
|||
package cn.iocoder.yudao.module.im.service.conversation;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationLastTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ConversationPinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ConversationDO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.conversation.ConversationMapper;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.service.inbox.InboxService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
|
@ -27,50 +27,50 @@ public class ConversationServiceImpl implements ConversationService {
|
|||
private InboxService inboxService;
|
||||
|
||||
@Override
|
||||
public List<ConversationDO> getConversationList() {
|
||||
public List<ImConversationDO> getConversationList() {
|
||||
return conversationMapper.selectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePinned(ConversationPinnedReqVO updateReqVO) {
|
||||
// TODO @hao:updateTop 和 updateLastReadTime 使用独立的逻辑实现,不使用统一的 ImConversationSaveReqVO;
|
||||
// TODO 大体步骤建议:
|
||||
// 1. 先 getOrderCreateConversation,查询会话,不存在则插入;
|
||||
// 2. 更新对应的字段
|
||||
// 3. 做对应更新的 notify 推送
|
||||
ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo());
|
||||
public void updatePinned(Long loginUserId, ImConversationUpdatePinnedReqVO updateReqVO) {
|
||||
// 1. 获得会话编号
|
||||
String no = ImConversationTypeEnum.generateConversationNo(loginUserId, updateReqVO.getTargetId(), updateReqVO.getType());
|
||||
// 2. 查询会话
|
||||
ImConversationDO conversation = conversationMapper.selectByNo(no);
|
||||
if (conversation == null) {
|
||||
ConversationDO conversationDO = new ConversationDO();
|
||||
// TODO @hao:no 不是前端传递哈,后端生成;另外,其实可以把 insert 写成一个公用方法;get会话,拿不到就 insert;接着处理 update 操作;首次多 update 一次,无所谓的;没多少量的
|
||||
conversationDO.setNo(updateReqVO.getNo());
|
||||
conversationDO.setPinned(updateReqVO.getPinned());
|
||||
conversationDO.setUserId(updateReqVO.getUserId());
|
||||
conversationDO.setTargetId(updateReqVO.getTargetId());
|
||||
conversationDO.setType(updateReqVO.getType());
|
||||
conversationMapper.insert(conversationDO);
|
||||
} else {
|
||||
// 更新 TODO @anhaohao:这里不要 toBean,因为这里逻辑偏 toc,new ConversationDO 对象,然后逐个 set 需要的值;
|
||||
ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class);
|
||||
conversationMapper.updateById(updateObj);
|
||||
// 2.1. 不存在,则插入
|
||||
conversation = insertConversation(no, loginUserId, updateReqVO.getTargetId(), updateReqVO.getType());
|
||||
}
|
||||
// 3. 更新会话
|
||||
conversation.setPinned(updateReqVO.getPinned());
|
||||
conversationMapper.updateById(conversation);
|
||||
// 4. 做对应更新的 notify 推送
|
||||
}
|
||||
|
||||
private ImConversationDO insertConversation(String no, Long userId, Long targetId, Integer type) {
|
||||
ImConversationDO imConversationDO = new ImConversationDO();
|
||||
imConversationDO.setNo(no);
|
||||
imConversationDO.setUserId(userId);
|
||||
imConversationDO.setTargetId(targetId);
|
||||
imConversationDO.setType(type);
|
||||
conversationMapper.insert(imConversationDO);
|
||||
return imConversationDO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateLastReadTime(ConversationLastTimeReqVO updateReqVO) {
|
||||
ConversationDO conversation = conversationMapper.selectByNo(updateReqVO.getNo());
|
||||
public void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO) {
|
||||
// 1. 获得会话编号
|
||||
String no = ImConversationTypeEnum.generateConversationNo(loginUserId, updateReqVO.getTargetId(), updateReqVO.getType());
|
||||
// 2. 查询会话
|
||||
ImConversationDO conversation = conversationMapper.selectByNo(no);
|
||||
if (conversation == null) {
|
||||
ConversationDO conversationDO = new ConversationDO();
|
||||
conversationDO.setNo(updateReqVO.getNo());
|
||||
conversationDO.setLastReadTime(updateReqVO.getLastReadTime());
|
||||
conversationDO.setUserId(updateReqVO.getUserId());
|
||||
conversationDO.setTargetId(updateReqVO.getTargetId());
|
||||
conversationDO.setType(updateReqVO.getType());
|
||||
conversationMapper.insert(conversationDO);
|
||||
} else {
|
||||
// 更新
|
||||
ConversationDO updateObj = BeanUtils.toBean(updateReqVO, ConversationDO.class);
|
||||
conversationMapper.updateById(updateObj);
|
||||
// 2.1. 不存在,则插入
|
||||
conversation = insertConversation(no, loginUserId, updateReqVO.getTargetId(), updateReqVO.getType());
|
||||
}
|
||||
// 3. 更新会话
|
||||
conversation.setLastReadTime(updateReqVO.getLastReadTime());
|
||||
conversationMapper.updateById(conversation);
|
||||
// 4. 做对应更新的 notify 推送
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ package cn.iocoder.yudao.module.im.service.group;
|
|||
|
||||
import jakarta.validation.*;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
|
||||
/**
|
||||
|
|
@ -10,7 +10,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface ImGroupService {
|
||||
public interface GroupService {
|
||||
|
||||
/**
|
||||
* 创建群
|
||||
|
|
@ -40,7 +40,7 @@ public interface ImGroupService {
|
|||
* @param id 编号
|
||||
* @return 群
|
||||
*/
|
||||
GroupDO getGroup(Long id);
|
||||
ImGroupDO getGroup(Long id);
|
||||
|
||||
/**
|
||||
* 获得群分页
|
||||
|
|
@ -48,6 +48,6 @@ public interface ImGroupService {
|
|||
* @param pageReqVO 分页查询
|
||||
* @return 群分页
|
||||
*/
|
||||
PageResult<GroupDO> getGroupPage(ImGroupPageReqVO pageReqVO);
|
||||
PageResult<ImGroupDO> getGroupPage(ImGroupPageReqVO pageReqVO);
|
||||
|
||||
}
|
||||
|
|
@ -5,11 +5,11 @@ import jakarta.annotation.Resource;
|
|||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.group.vo.*;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.group.ImGroupMapper;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.group.GroupMapper;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
|
||||
|
|
@ -21,16 +21,16 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
|
|||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class ImGroupServiceImpl implements ImGroupService {
|
||||
public class GroupServiceImpl implements GroupService {
|
||||
|
||||
@Resource
|
||||
private ImGroupMapper imGroupMapper;
|
||||
private GroupMapper groupMapper;
|
||||
|
||||
@Override
|
||||
public Long createGroup(ImGroupSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
GroupDO group = BeanUtils.toBean(createReqVO, GroupDO.class);
|
||||
imGroupMapper.insert(group);
|
||||
ImGroupDO group = BeanUtils.toBean(createReqVO, ImGroupDO.class);
|
||||
groupMapper.insert(group);
|
||||
// 返回
|
||||
return group.getId();
|
||||
}
|
||||
|
|
@ -40,8 +40,8 @@ public class ImGroupServiceImpl implements ImGroupService {
|
|||
// 校验存在
|
||||
validateGroupExists(updateReqVO.getId());
|
||||
// 更新
|
||||
GroupDO updateObj = BeanUtils.toBean(updateReqVO, GroupDO.class);
|
||||
imGroupMapper.updateById(updateObj);
|
||||
ImGroupDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupDO.class);
|
||||
groupMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -49,23 +49,23 @@ public class ImGroupServiceImpl implements ImGroupService {
|
|||
// 校验存在
|
||||
validateGroupExists(id);
|
||||
// 删除
|
||||
imGroupMapper.deleteById(id);
|
||||
groupMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateGroupExists(Long id) {
|
||||
if (imGroupMapper.selectById(id) == null) {
|
||||
if (groupMapper.selectById(id) == null) {
|
||||
throw exception(GROUP_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupDO getGroup(Long id) {
|
||||
return imGroupMapper.selectById(id);
|
||||
public ImGroupDO getGroup(Long id) {
|
||||
return groupMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GroupDO> getGroupPage(ImGroupPageReqVO pageReqVO) {
|
||||
return imGroupMapper.selectPage(pageReqVO);
|
||||
public PageResult<ImGroupDO> getGroupPage(ImGroupPageReqVO pageReqVO) {
|
||||
return groupMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.im.service.groupmember;
|
|||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -43,7 +43,7 @@ public interface GroupMemberService {
|
|||
* @param id 编号
|
||||
* @return 群成员
|
||||
*/
|
||||
GroupMemberDO getGroupMember(Long id);
|
||||
ImGroupMemberDO getGroupMember(Long id);
|
||||
|
||||
/**
|
||||
* 获得群成员分页
|
||||
|
|
@ -51,7 +51,7 @@ public interface GroupMemberService {
|
|||
* @param pageReqVO 分页查询
|
||||
* @return 群成员分页
|
||||
*/
|
||||
PageResult<GroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO);
|
||||
PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO);
|
||||
|
||||
/**
|
||||
* 根据群组id查询群成员
|
||||
|
|
@ -59,5 +59,5 @@ public interface GroupMemberService {
|
|||
* @param groupId 群组id
|
||||
* @return 群成员列表
|
||||
*/
|
||||
List<GroupMemberDO> selectByGroupId(Long groupId);
|
||||
List<ImGroupMemberDO> selectByGroupId(Long groupId);
|
||||
}
|
||||
|
|
@ -5,11 +5,11 @@ import jakarta.annotation.Resource;
|
|||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.*;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.groupmember.GroupMemberMapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -26,13 +26,13 @@ import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*;
|
|||
public class GroupMemberServiceImpl implements GroupMemberService {
|
||||
|
||||
@Resource
|
||||
private ImGroupMemberMapper imGroupMemberMapper;
|
||||
private GroupMemberMapper groupMemberMapper;
|
||||
|
||||
@Override
|
||||
public Long createGroupMember(ImGroupMemberSaveReqVO createReqVO) {
|
||||
// 插入
|
||||
GroupMemberDO groupMember = BeanUtils.toBean(createReqVO, GroupMemberDO.class);
|
||||
imGroupMemberMapper.insert(groupMember);
|
||||
ImGroupMemberDO groupMember = BeanUtils.toBean(createReqVO, ImGroupMemberDO.class);
|
||||
groupMemberMapper.insert(groupMember);
|
||||
// 返回
|
||||
return groupMember.getId();
|
||||
}
|
||||
|
|
@ -42,8 +42,8 @@ public class GroupMemberServiceImpl implements GroupMemberService {
|
|||
// 校验存在
|
||||
validateGroupMemberExists(updateReqVO.getId());
|
||||
// 更新
|
||||
GroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, GroupMemberDO.class);
|
||||
imGroupMemberMapper.updateById(updateObj);
|
||||
ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class);
|
||||
groupMemberMapper.updateById(updateObj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -51,28 +51,28 @@ public class GroupMemberServiceImpl implements GroupMemberService {
|
|||
// 校验存在
|
||||
validateGroupMemberExists(id);
|
||||
// 删除
|
||||
imGroupMemberMapper.deleteById(id);
|
||||
groupMemberMapper.deleteById(id);
|
||||
}
|
||||
|
||||
private void validateGroupMemberExists(Long id) {
|
||||
if (imGroupMemberMapper.selectById(id) == null) {
|
||||
if (groupMemberMapper.selectById(id) == null) {
|
||||
throw exception(GROUP_MEMBER_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public GroupMemberDO getGroupMember(Long id) {
|
||||
return imGroupMemberMapper.selectById(id);
|
||||
public ImGroupMemberDO getGroupMember(Long id) {
|
||||
return groupMemberMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResult<GroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) {
|
||||
return imGroupMemberMapper.selectPage(pageReqVO);
|
||||
public PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) {
|
||||
return groupMemberMapper.selectPage(pageReqVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GroupMemberDO> selectByGroupId(Long groupId) {
|
||||
return imGroupMemberMapper.selectListByGroupId(groupId);
|
||||
public List<ImGroupMemberDO> selectByGroupId(Long groupId) {
|
||||
return groupMemberMapper.selectListByGroupId(groupId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package cn.iocoder.yudao.module.im.service.inbox;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -14,9 +14,9 @@ public interface InboxService {
|
|||
/**
|
||||
* 保存收件箱和发送消息
|
||||
*
|
||||
* @param inboxSaveMessageReqVO 收件箱保存消息 Request VO
|
||||
* @param imMessageDO 收件箱保存消息 Request VO
|
||||
*/
|
||||
void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessageReqVO);
|
||||
void saveInboxAndSendMessage(ImMessageDO imMessageDO);
|
||||
|
||||
/**
|
||||
* 获得大于 sequence 的消息ids
|
||||
|
|
|
|||
|
|
@ -2,18 +2,19 @@ package cn.iocoder.yudao.module.im.service.inbox;
|
|||
|
||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSendMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.inbox.InboxDO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.inbox.InboxMapper;
|
||||
import cn.iocoder.yudao.module.im.dal.redis.inbox.InboxLockRedisDAO;
|
||||
import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceRedisDao;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceRedisDAO;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService;
|
||||
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.dromara.hutool.core.date.DateUnit;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
|
|
@ -33,50 +34,60 @@ public class InboxServiceImpl implements InboxService {
|
|||
|
||||
@Resource
|
||||
private InboxMapper inboxMapper;
|
||||
|
||||
@Resource
|
||||
private SequenceRedisDao sequenceRedisDao; // 序列生成器Redis DAO
|
||||
private SequenceRedisDAO sequenceRedisDAO;
|
||||
@Resource
|
||||
private InboxLockRedisDAO inboxLockRedisDAO; // 收件箱的锁 Redis DAO
|
||||
private InboxLockRedisDAO inboxLockRedisDAO;
|
||||
|
||||
@Resource
|
||||
private WebSocketSenderApi webSocketSenderApi;
|
||||
@Resource
|
||||
private GroupMemberService groupMemberService;
|
||||
|
||||
// TODO @anhaohao:下面的逻辑,最好是,1. 保存收件箱 + 发送消息给用户; 2. xxx;这样看的人,会更有感觉哈;
|
||||
@Override
|
||||
public void saveInboxAndSendMessage(InboxSaveMessageReqVO inboxSaveMessage) {
|
||||
// 保存收件箱 + 发送消息给用户
|
||||
saveInboxAndSendMessageForUser(inboxSaveMessage.getFromId(), inboxSaveMessage);
|
||||
|
||||
if (inboxSaveMessage.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) {
|
||||
saveInboxAndSendMessageForUser(inboxSaveMessage.getReceiverId(), inboxSaveMessage);
|
||||
} else if (inboxSaveMessage.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) {
|
||||
List<GroupMemberDO> groupMembers = groupMemberService.selectByGroupId(inboxSaveMessage.getReceiverId());
|
||||
groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), inboxSaveMessage));
|
||||
public void saveInboxAndSendMessage(ImMessageDO message) {
|
||||
// 1. 保存收件箱 + 发送消息给发送人
|
||||
saveInboxAndSendMessageForUser(message.getSenderId(), message);
|
||||
// 2. 保存收件箱 + 发送消息给接收人
|
||||
if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) {
|
||||
// 2.1 如果是单聊,直接发送给接收人
|
||||
saveInboxAndSendMessageForUser(message.getReceiverId(), message);
|
||||
} else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) {
|
||||
// 2.2 如果是群聊,发送给群聊的所有人
|
||||
List<ImGroupMemberDO> groupMembers = groupMemberService.selectByGroupId(message.getReceiverId());
|
||||
groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), message));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) {
|
||||
return inboxMapper.selectMessageIdsByUserIdAndSequence(userId, sequence, size);
|
||||
List<ImInboxDO> imInboxDOS = inboxMapper.selectListByUserIdAndSequence(userId, sequence, size);
|
||||
return imInboxDOS.stream().map(ImInboxDO::getMessageId).toList();
|
||||
}
|
||||
|
||||
private void saveInboxAndSendMessageForUser(Long userId, InboxSaveMessageReqVO inboxSaveMessage) {
|
||||
inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> {
|
||||
Long userSequence = sequenceRedisDao.generateSequence(userId);
|
||||
// TODO @anhaohao:链式调用;
|
||||
InboxDO inbox = new InboxDO();
|
||||
inbox.setUserId(userId);
|
||||
inbox.setMessageId(inboxSaveMessage.getMessageId());
|
||||
inbox.setSequence(userSequence);
|
||||
inboxMapper.insert(inbox);
|
||||
|
||||
// TODO @anhaohao:是不是 send 不用在加锁里面哈?!
|
||||
// TODO @anhaohao:再进一步,是不是用 spring @async 可以并发推送噢
|
||||
InboxSendMessageReqVO message = BeanUtils.toBean(inboxSaveMessage, InboxSendMessageReqVO.class);
|
||||
message.setSequence(userSequence);
|
||||
webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, message);
|
||||
//TODO 多线程处理
|
||||
public void saveInboxAndSendMessageForUser(Long userId, ImMessageDO message) {
|
||||
inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> {
|
||||
// 1. 生成序列号
|
||||
Long userSequence = sequenceRedisDAO.generateSequence(userId);
|
||||
// 2. 保存收件箱
|
||||
ImInboxDO inbox = new ImInboxDO()
|
||||
.setUserId(userId)
|
||||
.setMessageId(message.getId())
|
||||
.setSequence(userSequence);
|
||||
inboxMapper.insert(inbox);
|
||||
// 3. 发送消息
|
||||
sendAsyncMessage(userId, message, userSequence);
|
||||
});
|
||||
}
|
||||
|
||||
@Async
|
||||
public void sendAsyncMessage(Long userId, ImMessageDO message, Long userSequence) {
|
||||
ImMessageRespVO messageRespVO = BeanUtils.toBean(message, ImMessageRespVO.class);
|
||||
messageRespVO.setSequence(userSequence);
|
||||
webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, messageRespVO);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
package cn.iocoder.yudao.module.im.service.message;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
|
@ -17,26 +16,28 @@ public interface MessageService {
|
|||
/**
|
||||
* 获得历史消息
|
||||
*
|
||||
* @param pageReqVO 分页查询
|
||||
* @param loginUserId 登录用户编号
|
||||
* @param listReqVO 分页查询
|
||||
* @return 消息分页
|
||||
*/
|
||||
List<MessageDO> getHistoryMessage(MessagePageReqVO pageReqVO);
|
||||
List<ImMessageDO> getMessageList(Long loginUserId, ImMessageListReqVO listReqVO);
|
||||
|
||||
/**
|
||||
* 拉取消息-大于 seq 的消息
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @param sequence 序列号
|
||||
* @param size 数量
|
||||
* @param loginUserId 登录用户编号
|
||||
* @param sequence 序列号
|
||||
* @param size 数量
|
||||
* @return 消息列表
|
||||
*/
|
||||
List<MessageDO> getMessageListBySequence(Long userId, Long sequence, Integer size);
|
||||
List<ImMessageDO> pullMessageList(Long loginUserId, Long sequence, Integer size);
|
||||
|
||||
/**
|
||||
* 发送消息
|
||||
*
|
||||
* @param loginUserId 登录用户编号
|
||||
* @param message 消息
|
||||
* @param message 消息
|
||||
* @return 消息编号
|
||||
*/
|
||||
SendMessageRespVO sendMessage(Long loginUserId, SendMessageReqVO message);
|
||||
ImMessageDO sendMessage(Long loginUserId, ImMessageSendReqVO message);
|
||||
}
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
package cn.iocoder.yudao.module.im.service.message;
|
||||
|
||||
import cn.iocoder.yudao.module.im.controller.admin.inbox.vo.InboxSaveMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.MessagePageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.SendMessageRespVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.GroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.MessageDO;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO;
|
||||
import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO;
|
||||
import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO;
|
||||
import cn.iocoder.yudao.module.im.dal.mysql.message.MessageMapper;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageSourceEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageSourceEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum;
|
||||
import cn.iocoder.yudao.module.im.service.groupmember.GroupMemberService;
|
||||
import cn.iocoder.yudao.module.im.service.inbox.InboxService;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
|
|
@ -38,92 +37,66 @@ public class MessageServiceImpl implements MessageService {
|
|||
@Resource
|
||||
private MessageMapper messageMapper;
|
||||
@Resource
|
||||
private InboxService inboxService;
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
@Resource
|
||||
private InboxService inboxService;
|
||||
@Resource
|
||||
private GroupMemberService groupMemberService;
|
||||
|
||||
@Override
|
||||
public List<MessageDO> getHistoryMessage(MessagePageReqVO pageReqVO) {
|
||||
return messageMapper.getHistoryMessage(pageReqVO);
|
||||
public List<ImMessageDO> getMessageList(Long loginUserId, ImMessageListReqVO listReqVO) {
|
||||
// 1. 获得会话编号
|
||||
String no = ImConversationTypeEnum.generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType());
|
||||
// 2. 查询历史消息
|
||||
ImMessageDO message = new ImMessageDO()
|
||||
.setSendTime(listReqVO.getSendTime())
|
||||
.setConversationNo(no);
|
||||
return messageMapper.selectMessageList(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MessageDO> getMessageListBySequence(Long userId, Long sequence, Integer size) {
|
||||
public List<ImMessageDO> pullMessageList(Long userId, Long sequence, Integer size) {
|
||||
List<Long> messageIds = inboxService.selectMessageIdsByUserIdAndSequence(userId, sequence, size);
|
||||
return messageMapper.selectBatchIds(messageIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SendMessageRespVO sendMessage(Long fromUserId, SendMessageReqVO message) {
|
||||
// 保存消息
|
||||
// TODO @anhaohao:InboxSaveMessageReqVO 不用 new 出来传递到 saveMessage 方法里;
|
||||
InboxSaveMessageReqVO inboxSaveMessageReqVO = new InboxSaveMessageReqVO();
|
||||
SendMessageRespVO sendMessageRespVO = saveMessage(fromUserId, message, inboxSaveMessageReqVO);
|
||||
|
||||
// 保存收件箱 + 发送消息给用户
|
||||
// TODO @anhaohao:考虑到少定义一些 VO,直接传递 MessageDO 就完事了;反正这两者也是强耦合的;
|
||||
inboxService.saveInboxAndSendMessage(inboxSaveMessageReqVO);
|
||||
return sendMessageRespVO;
|
||||
public ImMessageDO sendMessage(Long fromUserId, ImMessageSendReqVO imMessageSendReqVO) {
|
||||
// 1. 保存消息
|
||||
ImMessageDO message = saveMessage(fromUserId, imMessageSendReqVO);
|
||||
// 2. 保存到收件箱,并发送消息
|
||||
inboxService.saveInboxAndSendMessage(message);
|
||||
return message;
|
||||
}
|
||||
|
||||
// TODO @anhaohao:这个方法,是不是定义成 private 哈;然后返回是 MessageDO 对象,设置最上面的 sendMessage 也是这个。最终 controller 转成 SendMessageRespVO
|
||||
public SendMessageRespVO saveMessage(Long fromUserId, SendMessageReqVO message, InboxSaveMessageReqVO inboxSaveMessageReqVO) {
|
||||
// 需要校验 receiverId 存在
|
||||
private ImMessageDO saveMessage(Long fromUserId, ImMessageSendReqVO message) {
|
||||
// 1. 校验接收人是否存在
|
||||
validateReceiverIdExists(message);
|
||||
// 查询发送人昵称和发送人头像
|
||||
// 2. 查询发送人信息
|
||||
AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId);
|
||||
// 使用链式调用创建 MessageDO 对象
|
||||
// TODO @anhaohao:一部分字段,可以 beanutils tobean 搞定;
|
||||
// TODO @anhaohao:链式 set 的时候,要把相同的放在一行;例如说,setSenderNickname、setSenderAvatar;本质上,就是为了“同类”在一行,阅读起来简单;
|
||||
MessageDO messageDO = new MessageDO()
|
||||
.setClientMessageId(message.getClientMessageId())
|
||||
// 3. 保存消息
|
||||
ImMessageDO imMessageDO = BeanUtil.copyProperties(message, ImMessageDO.class)
|
||||
.setSenderNickname(fromUser.getNickname()).setSenderAvatar(fromUser.getAvatar())
|
||||
.setSenderId(fromUserId)
|
||||
.setReceiverId(message.getReceiverId())
|
||||
.setSenderNickname(fromUser.getNickname())
|
||||
.setSenderAvatar(fromUser.getAvatar())
|
||||
.setConversationType(message.getConversationType())
|
||||
.setContentType(message.getContentType())
|
||||
.setConversationNo(ConversationTypeEnum.generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType()))
|
||||
.setContent(message.getContent())
|
||||
.setSendFrom(MessageSourceEnum.USER_SEND.getStatus())
|
||||
.setSendTime(TimeUtil.now())
|
||||
.setMessageStatus(MessageStatusEnum.SENDING.getStatus());
|
||||
messageMapper.insert(messageDO);
|
||||
|
||||
// 设置 InboxSaveMessageReqVO 对象
|
||||
inboxSaveMessageReqVO.setConversationType(message.getConversationType())
|
||||
.setFromId(fromUserId)
|
||||
.setReceiverId(message.getReceiverId())
|
||||
.setMessageId(messageDO.getId())
|
||||
.setContentType(message.getContentType())
|
||||
.setContent(message.getContent())
|
||||
.setSendTime(messageDO.getSendTime())
|
||||
.setSenderNickname(fromUser.getNickname())
|
||||
.setSenderAvatar(fromUser.getAvatar());
|
||||
|
||||
// 返回 SendMessageRespVO 对象
|
||||
return new SendMessageRespVO(messageDO.getId(), messageDO.getSendTime());
|
||||
.setConversationNo(ImConversationTypeEnum.generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType()))
|
||||
.setSendFrom(ImMessageSourceEnum.USER_SEND.getSource())
|
||||
.setMessageStatus(ImMessageStatusEnum.SENDING.getStatus())
|
||||
.setSendTime(TimeUtil.now());
|
||||
messageMapper.insert(imMessageDO);
|
||||
return imMessageDO;
|
||||
}
|
||||
|
||||
// TODO @anhaohao:validateReceiver,更简单一点哈;不仅仅校验存在,未来还可以校验,自己是不是有好友关系、群聊是否在群聊里面等等
|
||||
private void validateReceiverIdExists(SendMessageReqVO message) {
|
||||
// TODO @anhaohao:这个不要这里校验,交给 validator 校验掉
|
||||
if (message.getReceiverId() == null) {
|
||||
throw exception(MESSAGE_RECEIVER_NOT_EXISTS);
|
||||
}
|
||||
if (message.getConversationType().equals(ConversationTypeEnum.SINGLE.getType())) {
|
||||
// TODO @anhaohao:// 之后要空一个空格,中英文协作习惯,中文和英文之间,不能连着;最后也不用 ;哈
|
||||
//校验用户是否存在;
|
||||
private void validateReceiverIdExists(ImMessageSendReqVO message) {
|
||||
if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) {
|
||||
// 校验用户是否存在
|
||||
AdminUserRespDTO receiverUser = adminUserApi.getUser(message.getReceiverId());
|
||||
if (receiverUser == null) {
|
||||
throw exception(MESSAGE_RECEIVER_NOT_EXISTS);
|
||||
}
|
||||
} else if (message.getConversationType().equals(ConversationTypeEnum.GROUP.getType())) {
|
||||
//校验群聊是否存在;
|
||||
List<GroupMemberDO> groupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId());
|
||||
if (groupMemberDOS.isEmpty()) {
|
||||
} else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) {
|
||||
// 校验群聊是否存在
|
||||
List<ImGroupMemberDO> imGroupMemberDOS = groupMemberService.selectByGroupId(message.getReceiverId());
|
||||
if (imGroupMemberDOS.isEmpty()) {
|
||||
throw exception(MESSAGE_RECEIVER_NOT_EXISTS);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.websocket;
|
||||
|
||||
import cn.iocoder.yudao.framework.websocket.core.listener.WebSocketMessageListener;
|
||||
import cn.iocoder.yudao.framework.websocket.core.util.WebSocketFrameworkUtils;
|
||||
import cn.iocoder.yudao.module.im.websocket.message.ImSendMessage;
|
||||
import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
// TODO @hao:消息发送,使用 http 上行。因为在 cloud 框架下,我们比较难去 Listener。因为 im-server 不会自己启动 websocket 路径
|
||||
|
||||
/**
|
||||
* WebSocket im
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ImWebSocketMessageListener implements WebSocketMessageListener<ImSendMessage> {
|
||||
|
||||
public static final String IM_MESSAGE_RECEIVE = "im-message-receive";
|
||||
@Resource
|
||||
private WebSocketSenderApi webSocketSenderApi; // WebSocket消息发送器
|
||||
|
||||
/**
|
||||
* 处理WebSocket消息
|
||||
*
|
||||
* @param session WebSocket会话
|
||||
* @param message 发送的IM消息
|
||||
*/
|
||||
@Override
|
||||
public void onMessage(WebSocketSession session, ImSendMessage message) {
|
||||
Long fromUserId = WebSocketFrameworkUtils.getLoginUserId(session); // 获取登录用户ID
|
||||
log.info(message.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型
|
||||
*
|
||||
* @return 类型
|
||||
*/
|
||||
@Override
|
||||
public String getType() {
|
||||
return "im-message-send";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.websocket.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 消息发送 receive")
|
||||
@Data
|
||||
public class ImReceiveMessage {
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(ConversationTypeEnum.class)
|
||||
private Integer conversationType;
|
||||
|
||||
// TODO @anhaohao:我们应该是 senderId;因为它和 receiverId 是相对应的哈。
|
||||
@Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long fromId; // 根据 conversationType 区分
|
||||
|
||||
// TODO @hao:昵称和头像,也直接发给接收人好了;
|
||||
|
||||
@Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454")
|
||||
private Long messageId;
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
private Integer contentType; // 参见 ImMessageTypeEnum 枚举
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
@Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Long sequence;
|
||||
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
package cn.iocoder.yudao.module.im.websocket.message;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.conversation.ConversationTypeEnum;
|
||||
import cn.iocoder.yudao.module.im.enums.message.MessageContentTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Schema(description = "管理后台 - IM 消息发送 send")
|
||||
@Data
|
||||
public class ImSendMessage {
|
||||
|
||||
@Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331")
|
||||
private String clientMessageId;
|
||||
|
||||
@Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(ConversationTypeEnum.class)
|
||||
private Integer conversationType;
|
||||
|
||||
@Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
|
||||
private Long receiverId; // 根据 conversationType 区分
|
||||
|
||||
@Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@InEnum(MessageContentTypeEnum.class)
|
||||
private Integer contentType;
|
||||
|
||||
@Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String content;
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue