Commit 0ac1f0cc28e3bf1c6f100a98878064c792674b84
1 parent
2d277765
📝 refactor(controller): 移除不必要的导入和注解,优化会话和群成员响应对象
Showing
19 changed files
with
2 additions
and
871 deletions
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java
| ... | ... | @@ -8,9 +8,6 @@ import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversatio |
| 8 | 8 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; |
| 9 | 9 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| 10 | 10 | import cn.iocoder.yudao.module.im.service.conversation.ImConversationService; |
| 11 | -import cn.iocoder.yudao.module.im.service.message.ImMessageService; | |
| 12 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 13 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 14 | 11 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | 12 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | 13 | import jakarta.annotation.Resource; |
| ... | ... | @@ -32,28 +29,12 @@ public class ImConversationController { |
| 32 | 29 | @Resource |
| 33 | 30 | private ImConversationService imConversationService; |
| 34 | 31 | |
| 35 | - @Resource | |
| 36 | - private ImMessageService imMessageService; | |
| 37 | - | |
| 38 | - @Resource | |
| 39 | - AdminUserApi adminUserApi; | |
| 40 | - | |
| 32 | + // TODO @芋艿:头像和昵称的聚合应交给前端完成 | |
| 41 | 33 | @GetMapping("/list") |
| 42 | 34 | @Operation(summary = "获得用户的会话列表") |
| 43 | 35 | public CommonResult<List<ImConversationRespVO>> getConversationList() { |
| 44 | 36 | List<ImConversationDO> conversationList = imConversationService.getConversationList(getLoginUserId()); |
| 45 | 37 | List<ImConversationRespVO> imConversationRespVOList = BeanUtils.toBean(conversationList, ImConversationRespVO.class); |
| 46 | - // TODO @dylan:这块,交给前端聚合哈。im 这块,我们重前端,后端更多解决消息的通信和存储。 | |
| 47 | - imConversationRespVOList.forEach(item -> { | |
| 48 | - // 处理个人图像和昵称 | |
| 49 | - Long receiverId = item.getTargetId(); | |
| 50 | - AdminUserRespDTO receiverUser = adminUserApi.getUser(receiverId); | |
| 51 | - if (receiverUser != null) { | |
| 52 | - item.setAvatar(receiverUser.getAvatar()); | |
| 53 | - item.setNickname(receiverUser.getNickname()); | |
| 54 | - } | |
| 55 | - | |
| 56 | - }); | |
| 57 | 38 | return success(imConversationRespVOList); |
| 58 | 39 | } |
| 59 | 40 | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/group/vo/ImGroupRespVO.java
| ... | ... | @@ -2,46 +2,35 @@ package cn.iocoder.yudao.module.im.controller.admin.group.vo; |
| 2 | 2 | |
| 3 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | 4 | import lombok.*; |
| 5 | -import com.alibaba.excel.annotation.*; | |
| 6 | 5 | |
| 7 | 6 | import java.time.LocalDateTime; |
| 8 | 7 | |
| 9 | -// TODO @AI:不需要导出的注解; | |
| 10 | 8 | @Schema(description = "管理后台 - 群 Response VO") |
| 11 | 9 | @Data |
| 12 | -@ExcelIgnoreUnannotated | |
| 13 | 10 | public class ImGroupRespVO { |
| 14 | 11 | |
| 15 | 12 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1003") |
| 16 | - @ExcelProperty("编号") | |
| 17 | 13 | private Long id; |
| 18 | 14 | |
| 19 | 15 | @Schema(description = "群名称", example = "芋艿") |
| 20 | - @ExcelProperty("群名称") | |
| 21 | 16 | private String name; |
| 22 | 17 | |
| 23 | 18 | @Schema(description = "群主用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "31460") |
| 24 | - @ExcelProperty("群主用户编号") | |
| 25 | 19 | private Long ownerUserId; |
| 26 | 20 | |
| 27 | 21 | @Schema(description = "群头像") |
| 28 | - @ExcelProperty("群头像") | |
| 29 | 22 | private String avatar; |
| 30 | 23 | |
| 31 | 24 | @Schema(description = "群公告") |
| 32 | - @ExcelProperty("群公告") | |
| 33 | 25 | private String notice; |
| 34 | 26 | |
| 35 | 27 | @Schema(description = "是否封禁") |
| 36 | - @ExcelProperty("是否封禁") | |
| 37 | 28 | private Boolean banned; |
| 38 | 29 | |
| 39 | 30 | @Schema(description = "是否解散") |
| 40 | - @ExcelProperty("是否解散") | |
| 41 | 31 | private Boolean dissolved; |
| 42 | 32 | |
| 43 | 33 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 44 | - @ExcelProperty("创建时间") | |
| 45 | 34 | private LocalDateTime createTime; |
| 46 | 35 | |
| 47 | 36 | } |
| 48 | 37 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/ImGroupMemberController.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.groupmember; |
| 2 | 2 | |
| 3 | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | -import cn.iocoder.yudao.framework.common.pojo.PageParam; | |
| 5 | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 7 | -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; | |
| 8 | 6 | import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; |
| 9 | 7 | import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberRespVO; |
| 10 | 8 | import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO; |
| 11 | 9 | import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; |
| 12 | -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; | |
| 10 | +import cn.iocoder.yudao.module.im.service.group.ImGroupMemberService; | |
| 13 | 11 | import io.swagger.v3.oas.annotations.Operation; |
| 14 | 12 | import io.swagger.v3.oas.annotations.Parameter; |
| 15 | 13 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 16 | 14 | import jakarta.annotation.Resource; |
| 17 | -import jakarta.servlet.http.HttpServletResponse; | |
| 18 | 15 | import jakarta.validation.Valid; |
| 19 | 16 | import org.springframework.security.access.prepost.PreAuthorize; |
| 20 | 17 | import org.springframework.validation.annotation.Validated; |
| 21 | 18 | import org.springframework.web.bind.annotation.*; |
| 22 | 19 | |
| 23 | -import java.io.IOException; | |
| 24 | -import java.util.List; | |
| 25 | - | |
| 26 | 20 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | 21 | |
| 28 | 22 | // TODO @芋艿:得看看 create、update、delete、get、page 这几个接口,要保留哪些 |
| ... | ... | @@ -76,16 +70,4 @@ public class ImGroupMemberController { |
| 76 | 70 | return success(BeanUtils.toBean(pageResult, ImGroupMemberRespVO.class)); |
| 77 | 71 | } |
| 78 | 72 | |
| 79 | - @GetMapping("/export-excel") | |
| 80 | - @Operation(summary = "导出群成员 Excel") | |
| 81 | - @PreAuthorize("@ss.hasPermission('im:group-member:export')") | |
| 82 | - public void exportGroupMemberExcel(@Valid ImGroupMemberPageReqVO pageReqVO, | |
| 83 | - HttpServletResponse response) throws IOException { | |
| 84 | - pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE); | |
| 85 | - List<ImGroupMemberDO> list = imGroupMemberService.getGroupMemberPage(pageReqVO).getList(); | |
| 86 | - // 导出 Excel | |
| 87 | - ExcelUtils.write(response, "群成员.xls", "数据", ImGroupMemberRespVO.class, | |
| 88 | - BeanUtils.toBean(list, ImGroupMemberRespVO.class)); | |
| 89 | - } | |
| 90 | - | |
| 91 | 73 | } |
| 92 | 74 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/groupmember/vo/ImGroupMemberRespVO.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.groupmember.vo; |
| 2 | 2 | |
| 3 | -import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | |
| 4 | -import com.alibaba.excel.annotation.ExcelProperty; | |
| 5 | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 6 | 4 | import lombok.Data; |
| 7 | 5 | |
| 8 | 6 | import java.time.LocalDateTime; |
| 9 | 7 | |
| 10 | -// TODO @AI:去掉部分导出字段 | |
| 11 | 8 | @Schema(description = "管理后台 - 群成员 Response VO") |
| 12 | 9 | @Data |
| 13 | -@ExcelIgnoreUnannotated | |
| 14 | 10 | public class ImGroupMemberRespVO { |
| 15 | 11 | |
| 16 | 12 | @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "17071") |
| 17 | - @ExcelProperty("编号") | |
| 18 | 13 | private Long id; |
| 19 | 14 | |
| 20 | 15 | @Schema(description = "群编号", example = "13279") |
| 21 | - @ExcelProperty("群编号") | |
| 22 | 16 | private Long groupId; |
| 23 | 17 | |
| 24 | 18 | @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "21730") |
| 25 | - @ExcelProperty("用户编号") | |
| 26 | 19 | private Long userId; |
| 27 | 20 | |
| 28 | 21 | @Schema(description = "组内显示名", example = "芋艿") |
| 29 | - @ExcelProperty("组内显示名") | |
| 30 | 22 | private String displayUserName; |
| 31 | 23 | |
| 32 | 24 | @Schema(description = "群显示备注", example = "核心群") |
| 33 | - @ExcelProperty("群显示备注") | |
| 34 | 25 | private String displayGroupName; |
| 35 | 26 | |
| 36 | 27 | @Schema(description = "是否免打扰") |
| 37 | - @ExcelProperty("是否免打扰") | |
| 38 | 28 | private Boolean muted; |
| 39 | 29 | |
| 40 | 30 | @Schema(description = "成员状态", example = "0") |
| 41 | - @ExcelProperty("成员状态") | |
| 42 | 31 | private Integer status; |
| 43 | 32 | |
| 44 | 33 | @Schema(description = "入群时间") |
| 45 | - @ExcelProperty("入群时间") | |
| 46 | 34 | private LocalDateTime joinTime; |
| 47 | 35 | |
| 48 | 36 | @Schema(description = "退群时间") |
| 49 | - @ExcelProperty("退群时间") | |
| 50 | 37 | private LocalDateTime quitTime; |
| 51 | 38 | |
| 52 | 39 | @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 53 | - @ExcelProperty("创建时间") | |
| 54 | 40 | private LocalDateTime createTime; |
| 55 | 41 | |
| 56 | 42 | } |
| 57 | 43 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/ImMessageController.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.CommonResult; | |
| 4 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 5 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.*; | |
| 6 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 7 | -import cn.iocoder.yudao.module.im.service.message.ImMessageService; | |
| 8 | -import io.swagger.v3.oas.annotations.Operation; | |
| 9 | -import io.swagger.v3.oas.annotations.Parameter; | |
| 10 | -import io.swagger.v3.oas.annotations.tags.Tag; | |
| 11 | -import jakarta.annotation.Resource; | |
| 12 | -import jakarta.validation.Valid; | |
| 13 | -import org.springframework.validation.annotation.Validated; | |
| 14 | -import org.springframework.web.bind.annotation.*; | |
| 15 | - | |
| 16 | -import java.util.List; | |
| 17 | - | |
| 18 | -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | |
| 19 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 20 | - | |
| 21 | -@Tag(name = "管理后台 - IM 消息") | |
| 22 | -@RestController | |
| 23 | -@RequestMapping("/im/message") | |
| 24 | -@Validated | |
| 25 | -public class ImMessageController { | |
| 26 | - | |
| 27 | - @Resource | |
| 28 | - private ImMessageService imMessageService; | |
| 29 | - | |
| 30 | - @PostMapping("/send") | |
| 31 | - @Operation(summary = "发送消息") | |
| 32 | - public CommonResult<ImMessageSendRespVO> sendMessage(@Valid @RequestBody ImMessageSendReqVO imMessageSendReqVO) { | |
| 33 | - ImMessageDO message = imMessageService.sendMessage(getLoginUserId(), imMessageSendReqVO); | |
| 34 | - return success(BeanUtils.toBean(message, ImMessageSendRespVO.class)); | |
| 35 | - } | |
| 36 | - | |
| 37 | - @GetMapping("/pull") | |
| 38 | - @Operation(summary = "消息列表-拉取大于 sequence 的消息列表") | |
| 39 | - @Parameter(name = "sequence", description = "序号", required = true, example = "1") | |
| 40 | - @Parameter(name = "size", description = "条数", required = true, example = "10") | |
| 41 | - public CommonResult<List<ImMessageRespVO>> pullMessageList(@RequestParam("sequence") Long sequence, | |
| 42 | - @RequestParam("size") Integer size) { | |
| 43 | - List<ImMessageDO> messages = imMessageService.pullMessageList(getLoginUserId(), sequence, size); | |
| 44 | - return success(BeanUtils.toBean(messages, ImMessageRespVO.class)); | |
| 45 | - } | |
| 46 | - | |
| 47 | - @GetMapping("/list") | |
| 48 | - @Operation(summary = "消息列表-根据接收人和发送时间进行分页查询") | |
| 49 | - public CommonResult<List<ImMessageRespVO>> getMessageList(@Valid ImMessageListReqVO listReqVO) { | |
| 50 | - | |
| 51 | - Long loginUserId = getLoginUserId(); | |
| 52 | - List<ImMessageDO> messagePage = imMessageService.getMessageList(listReqVO, loginUserId); | |
| 53 | - return success(BeanUtils.toBean(messagePage, ImMessageRespVO.class)); | |
| 54 | - } | |
| 55 | - | |
| 56 | -} | |
| 57 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListByNoReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message.vo; | |
| 2 | - | |
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | -import jakarta.validation.constraints.NotNull; | |
| 5 | -import lombok.Data; | |
| 6 | -import lombok.ToString; | |
| 7 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | - | |
| 9 | -import java.time.LocalDateTime; | |
| 10 | - | |
| 11 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | |
| 12 | - | |
| 13 | -// TODO @dylan:看看,是不是融合到 ImMessageListReqVO 里 | |
| 14 | -@Schema(description = "管理后台 - 消息列表 Request VO") | |
| 15 | -@Data | |
| 16 | -@ToString(callSuper = true) | |
| 17 | -public class ImMessageListByNoReqVO { | |
| 18 | - | |
| 19 | - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") | |
| 20 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | |
| 21 | - private LocalDateTime sendTime; | |
| 22 | - | |
| 23 | - @Schema(description = "会话编号编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") | |
| 24 | - @NotNull(message = "会话编号不能为空") | |
| 25 | - private String conversationNo ; | |
| 26 | - | |
| 27 | -} | |
| 28 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageListReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 5 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 6 | -import jakarta.validation.constraints.NotNull; | |
| 7 | -import lombok.Data; | |
| 8 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 9 | - | |
| 10 | -import java.time.LocalDateTime; | |
| 11 | - | |
| 12 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY; | |
| 13 | - | |
| 14 | -@Schema(description = "管理后台 - 消息列表 Request VO") | |
| 15 | -@Data | |
| 16 | -public class ImMessageListReqVO { | |
| 17 | - | |
| 18 | - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") | |
| 19 | - @NotNull(message = "接收人编号不能为空") | |
| 20 | - private Long receiverId; | |
| 21 | - | |
| 22 | - // TODO @dylan:这个是不是不用传递呀。因为 http 连接,有当前的 userid 呀 | |
| 23 | - @Schema(description = "会话所属人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") | |
| 24 | - @NotNull(message = "会话所属人编号不能为空") | |
| 25 | - private Long userId; | |
| 26 | - | |
| 27 | - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 28 | - @InEnum(value = ImConversationTypeEnum.class,message = "会话类型必须是 {value}") | |
| 29 | - @NotNull(message = "会话类型不能为空") | |
| 30 | - private Integer conversationType; | |
| 31 | - | |
| 32 | - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") | |
| 33 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY) | |
| 34 | - private LocalDateTime sendTime; | |
| 35 | - | |
| 36 | -} | |
| 37 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 5 | -import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum; | |
| 6 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 7 | -import lombok.Data; | |
| 8 | - | |
| 9 | -import java.time.LocalDateTime; | |
| 10 | - | |
| 11 | -@Schema(description = "管理后台 - 消息 Response VO") | |
| 12 | -@Data | |
| 13 | -public class ImMessageRespVO { | |
| 14 | - | |
| 15 | - @Schema(description = "消息编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12454") | |
| 16 | - private Long id; | |
| 17 | - | |
| 18 | - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 19 | - @InEnum(value = ImConversationTypeEnum.class) | |
| 20 | - private Integer conversationType; | |
| 21 | - | |
| 22 | - @Schema(description = "发送人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 23 | - private Long senderId; | |
| 24 | - | |
| 25 | - @Schema(description = "发送人昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四") | |
| 26 | - private String senderNickname; | |
| 27 | - | |
| 28 | - @Schema(description = "发送人头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "http://www.iocoder.cn/xxx.jpg") | |
| 29 | - private String senderAvatar; | |
| 30 | - | |
| 31 | - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 32 | - private Long receiverId; | |
| 33 | - | |
| 34 | - @Schema(description = "内容类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 35 | - @InEnum(value = ImMessageContentTypeEnum.class) | |
| 36 | - private Integer contentType; | |
| 37 | - | |
| 38 | - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好") | |
| 39 | - private String content; | |
| 40 | - | |
| 41 | - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") | |
| 42 | - private LocalDateTime sendTime; | |
| 43 | - | |
| 44 | - @Schema(description = "序号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 45 | - private Long sequence; | |
| 46 | - | |
| 47 | -} | |
| 48 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendReqVO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message.vo; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.validation.InEnum; | |
| 4 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 5 | -import cn.iocoder.yudao.module.im.enums.message.ImMessageContentTypeEnum; | |
| 6 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 7 | -import jakarta.validation.constraints.NotNull; | |
| 8 | -import lombok.Data; | |
| 9 | - | |
| 10 | -@Schema(description = "管理后台 - 发送消息 Request VO") | |
| 11 | -@Data | |
| 12 | -public class ImMessageSendReqVO { | |
| 13 | - | |
| 14 | - @Schema(description = "客户端消息编号 uuid,用于排重", requiredMode = Schema.RequiredMode.REQUIRED, example = "3331") | |
| 15 | - @NotNull(message = "客户端消息编号不能为空") | |
| 16 | - private String clientMessageId; | |
| 17 | - | |
| 18 | - @Schema(description = "接收人编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "32494") | |
| 19 | - @NotNull(message = "接收人编号不能为空") | |
| 20 | - private Long receiverId; | |
| 21 | - | |
| 22 | - @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 23 | - @InEnum(value = ImConversationTypeEnum.class) | |
| 24 | - @NotNull(message = "会话类型不能为空") | |
| 25 | - private Integer conversationType; | |
| 26 | - | |
| 27 | - // TODO @dylan:这个是不是不用传递呀。因为 http 连接,有当前的 userid 呀 | |
| 28 | - @Schema(description = "会话所属用户id", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 29 | - @NotNull(message = "会话所属用户id") | |
| 30 | - private Long conversationUserId; | |
| 31 | - | |
| 32 | - @Schema(description = "消息类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 33 | - @InEnum(ImMessageContentTypeEnum.class) | |
| 34 | - @NotNull(message = "消息类型不能为空") | |
| 35 | - private Integer contentType; | |
| 36 | - | |
| 37 | - @Schema(description = "消息内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "你好") | |
| 38 | - @NotNull(message = "消息内容不能为空") | |
| 39 | - private String content; | |
| 40 | - | |
| 41 | -} | |
| 42 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/message/vo/ImMessageSendRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.controller.admin.message.vo; | |
| 2 | - | |
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | |
| 4 | -import lombok.AllArgsConstructor; | |
| 5 | -import lombok.Data; | |
| 6 | -import lombok.NoArgsConstructor; | |
| 7 | -import org.springframework.format.annotation.DateTimeFormat; | |
| 8 | - | |
| 9 | -import java.time.LocalDateTime; | |
| 10 | - | |
| 11 | -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | |
| 12 | - | |
| 13 | -@Schema(description = "管理后台 - 发送消息 Response VO") | |
| 14 | -@Data | |
| 15 | -@AllArgsConstructor | |
| 16 | -@NoArgsConstructor | |
| 17 | -public class ImMessageSendRespVO { | |
| 18 | - | |
| 19 | - @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "12") | |
| 20 | - private Long id; | |
| 21 | - | |
| 22 | - @Schema(description = "发送时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2024-03-27 12:00:00") | |
| 23 | - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | |
| 24 | - private LocalDateTime sendTime; | |
| 25 | - | |
| 26 | -} | |
| 27 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/dataobject/inbox/ImInboxDO.java deleted
| 1 | -package cn.iocoder.yudao.module.im.dal.dataobject.inbox; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | |
| 4 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 5 | -import com.baomidou.mybatisplus.annotation.KeySequence; | |
| 6 | -import com.baomidou.mybatisplus.annotation.TableId; | |
| 7 | -import com.baomidou.mybatisplus.annotation.TableName; | |
| 8 | -import lombok.*; | |
| 9 | - | |
| 10 | -// TODO 我们要不要改成 ImMessageQueue 队列?从理解上,概念上,可能都更清晰一点哈。每个用户一个消息队列; | |
| 11 | - | |
| 12 | -/** | |
| 13 | - * IM 收件箱 DO | |
| 14 | - * | |
| 15 | - * @author 芋道源码 | |
| 16 | - */ | |
| 17 | -@TableName("im_inbox") | |
| 18 | -@KeySequence("im_inbox_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | |
| 19 | -@Data | |
| 20 | -@EqualsAndHashCode(callSuper = true) | |
| 21 | -@ToString(callSuper = true) | |
| 22 | -@Builder | |
| 23 | -@NoArgsConstructor | |
| 24 | -@AllArgsConstructor | |
| 25 | -public class ImInboxDO extends BaseDO { | |
| 26 | - | |
| 27 | - /** | |
| 28 | - * 编号 | |
| 29 | - */ | |
| 30 | - @TableId | |
| 31 | - private Long id; | |
| 32 | - /** | |
| 33 | - * 用户编号 | |
| 34 | - * <p> | |
| 35 | - * 关联 {@link ImMessageDO#getSenderId()} 或者 {@link ImMessageDO#getReceiverId()} | |
| 36 | - */ | |
| 37 | - private Long userId; | |
| 38 | - /** | |
| 39 | - * 消息编号 | |
| 40 | - * <p> | |
| 41 | - * 关联 {@link ImMessageDO#getId()} | |
| 42 | - */ | |
| 43 | - private Long messageId; | |
| 44 | - /** | |
| 45 | - * 序号,按照 user 递增 | |
| 46 | - */ | |
| 47 | - private Long sequence; | |
| 48 | - | |
| 49 | -} | |
| 50 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/inbox/ImInboxMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.im.dal.mysql.inbox; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 5 | -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; | |
| 6 | -import org.apache.ibatis.annotations.Mapper; | |
| 7 | - | |
| 8 | -import java.util.List; | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * IM 收件箱 Mapper | |
| 12 | - * | |
| 13 | - * @author 芋道源码 | |
| 14 | - */ | |
| 15 | -@Mapper | |
| 16 | -public interface ImInboxMapper extends BaseMapperX<ImInboxDO> { | |
| 17 | - | |
| 18 | - default List<ImInboxDO> selectListByUserIdAndSequence(Long userId, Long sequence, Integer size) { | |
| 19 | - return selectList(new LambdaQueryWrapperX<ImInboxDO>() | |
| 20 | - .eq(ImInboxDO::getUserId, userId) | |
| 21 | -// .gtIfPresent() // TODO @hao:可以用这个,简化下面的 .gt(sequence != null, ImInboxDO::getSequence, sequence) | |
| 22 | - .gt(sequence != null, ImInboxDO::getSequence, sequence) | |
| 23 | - .orderByDesc(ImInboxDO::getSequence) | |
| 24 | - .last("LIMIT " + size)); | |
| 25 | - } | |
| 26 | - | |
| 27 | -} | |
| 28 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/message/ImMessageMapper.java deleted
| 1 | -package cn.iocoder.yudao.module.im.dal.mysql.message; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | |
| 4 | -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | |
| 5 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 6 | -import org.apache.ibatis.annotations.Mapper; | |
| 7 | - | |
| 8 | -import java.util.List; | |
| 9 | - | |
| 10 | -// TODO @hao:IM 前缀 | |
| 11 | -/** | |
| 12 | - * 消息 Mapper | |
| 13 | - * | |
| 14 | - * @author 芋道源码 | |
| 15 | - */ | |
| 16 | -@Mapper | |
| 17 | -public interface ImMessageMapper extends BaseMapperX<ImMessageDO> { | |
| 18 | - | |
| 19 | - default List<ImMessageDO> selectMessageList(ImMessageDO message) { | |
| 20 | - return selectList(new LambdaQueryWrapperX<ImMessageDO>() | |
| 21 | - .eqIfPresent(ImMessageDO::getConversationNo, message.getConversationNo()) | |
| 22 | - .eqIfPresent(ImMessageDO::getSendTime, message.getSendTime()) | |
| 23 | - .orderByAsc(ImMessageDO::getSendTime)); | |
| 24 | - } | |
| 25 | -} | |
| 26 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberService.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.groupmember; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 4 | -import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberPageReqVO; | |
| 5 | -import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.ImGroupMemberSaveReqVO; | |
| 6 | -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | |
| 7 | -import jakarta.validation.Valid; | |
| 8 | - | |
| 9 | -import java.util.List; | |
| 10 | - | |
| 11 | -/** | |
| 12 | - * 群成员 Service 接口 | |
| 13 | - * | |
| 14 | - * @author 芋道源码 | |
| 15 | - */ | |
| 16 | -public interface ImGroupMemberService { | |
| 17 | - | |
| 18 | - /** | |
| 19 | - * 创建群成员 | |
| 20 | - * | |
| 21 | - * @param createReqVO 创建信息 | |
| 22 | - * @return 编号 | |
| 23 | - */ | |
| 24 | - Long createGroupMember(@Valid ImGroupMemberSaveReqVO createReqVO); | |
| 25 | - | |
| 26 | - /** | |
| 27 | - * 更新群成员 | |
| 28 | - * | |
| 29 | - * @param updateReqVO 更新信息 | |
| 30 | - */ | |
| 31 | - void updateGroupMember(@Valid ImGroupMemberSaveReqVO updateReqVO); | |
| 32 | - | |
| 33 | - /** | |
| 34 | - * 删除群成员 | |
| 35 | - * | |
| 36 | - * @param id 编号 | |
| 37 | - */ | |
| 38 | - void deleteGroupMember(Long id); | |
| 39 | - | |
| 40 | - /** | |
| 41 | - * 获得群成员 | |
| 42 | - * | |
| 43 | - * @param id 编号 | |
| 44 | - * @return 群成员 | |
| 45 | - */ | |
| 46 | - ImGroupMemberDO getGroupMember(Long id); | |
| 47 | - | |
| 48 | - /** | |
| 49 | - * 获得群成员分页 | |
| 50 | - * | |
| 51 | - * @param pageReqVO 分页查询 | |
| 52 | - * @return 群成员分页 | |
| 53 | - */ | |
| 54 | - PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO); | |
| 55 | - | |
| 56 | - /** | |
| 57 | - * 根据群组id查询群成员 | |
| 58 | - * | |
| 59 | - * @param groupId 群组id | |
| 60 | - * @return 群成员列表 | |
| 61 | - */ | |
| 62 | - List<ImGroupMemberDO> selectByGroupId(Long groupId); | |
| 63 | - | |
| 64 | - /** | |
| 65 | - * 根据群编号和用户编号查询群成员 | |
| 66 | - * | |
| 67 | - * @param groupId 群编号 | |
| 68 | - * @param userId 用户编号 | |
| 69 | - * @return 群成员 | |
| 70 | - */ | |
| 71 | - ImGroupMemberDO getGroupMember(Long groupId, Long userId); | |
| 72 | - | |
| 73 | - /** | |
| 74 | - * 查询用户所在的所有群的成员记录 | |
| 75 | - * | |
| 76 | - * @param userId 用户编号 | |
| 77 | - * @return 群成员记录列表 | |
| 78 | - */ | |
| 79 | - List<ImGroupMemberDO> getGroupMembersByUserId(Long userId); | |
| 80 | -} | |
| 81 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/groupmember/ImGroupMemberServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.groupmember; | |
| 2 | - | |
| 3 | -import org.springframework.stereotype.Service; | |
| 4 | -import jakarta.annotation.Resource; | |
| 5 | -import org.springframework.validation.annotation.Validated; | |
| 6 | - | |
| 7 | -import cn.iocoder.yudao.module.im.controller.admin.groupmember.vo.*; | |
| 8 | -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | |
| 9 | -import cn.iocoder.yudao.framework.common.pojo.PageResult; | |
| 10 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 11 | - | |
| 12 | -import cn.iocoder.yudao.module.im.dal.mysql.groupmember.ImGroupMemberMapper; | |
| 13 | - | |
| 14 | -import java.util.List; | |
| 15 | - | |
| 16 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 17 | -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.*; | |
| 18 | - | |
| 19 | -/** | |
| 20 | - * 群成员 Service 实现类 | |
| 21 | - * | |
| 22 | - * @author 芋道源码 | |
| 23 | - */ | |
| 24 | -@Service | |
| 25 | -@Validated | |
| 26 | -public class ImGroupMemberServiceImpl implements ImGroupMemberService { | |
| 27 | - | |
| 28 | - @Resource | |
| 29 | - private ImGroupMemberMapper imGroupMemberMapper; | |
| 30 | - | |
| 31 | - @Override | |
| 32 | - public Long createGroupMember(ImGroupMemberSaveReqVO createReqVO) { | |
| 33 | - // 插入 | |
| 34 | - ImGroupMemberDO groupMember = BeanUtils.toBean(createReqVO, ImGroupMemberDO.class); | |
| 35 | - imGroupMemberMapper.insert(groupMember); | |
| 36 | - // 返回 | |
| 37 | - return groupMember.getId(); | |
| 38 | - } | |
| 39 | - | |
| 40 | - @Override | |
| 41 | - public void updateGroupMember(ImGroupMemberSaveReqVO updateReqVO) { | |
| 42 | - // 校验存在 | |
| 43 | - validateGroupMemberExists(updateReqVO.getId()); | |
| 44 | - // 更新 | |
| 45 | - ImGroupMemberDO updateObj = BeanUtils.toBean(updateReqVO, ImGroupMemberDO.class); | |
| 46 | - imGroupMemberMapper.updateById(updateObj); | |
| 47 | - } | |
| 48 | - | |
| 49 | - @Override | |
| 50 | - public void deleteGroupMember(Long id) { | |
| 51 | - // 校验存在 | |
| 52 | - validateGroupMemberExists(id); | |
| 53 | - // 删除 | |
| 54 | - imGroupMemberMapper.deleteById(id); | |
| 55 | - } | |
| 56 | - | |
| 57 | - private void validateGroupMemberExists(Long id) { | |
| 58 | - if (imGroupMemberMapper.selectById(id) == null) { | |
| 59 | - throw exception(GROUP_MEMBER_NOT_EXISTS); | |
| 60 | - } | |
| 61 | - } | |
| 62 | - | |
| 63 | - @Override | |
| 64 | - public ImGroupMemberDO getGroupMember(Long id) { | |
| 65 | - return imGroupMemberMapper.selectById(id); | |
| 66 | - } | |
| 67 | - | |
| 68 | - @Override | |
| 69 | - public PageResult<ImGroupMemberDO> getGroupMemberPage(ImGroupMemberPageReqVO pageReqVO) { | |
| 70 | - return imGroupMemberMapper.selectPage(pageReqVO); | |
| 71 | - } | |
| 72 | - | |
| 73 | - @Override | |
| 74 | - public List<ImGroupMemberDO> selectByGroupId(Long groupId) { | |
| 75 | - return imGroupMemberMapper.selectListByGroupId(groupId); | |
| 76 | - } | |
| 77 | - | |
| 78 | - @Override | |
| 79 | - public ImGroupMemberDO getGroupMember(Long groupId, Long userId) { | |
| 80 | - return imGroupMemberMapper.selectByGroupIdAndUserId(groupId, userId); | |
| 81 | - } | |
| 82 | - | |
| 83 | - @Override | |
| 84 | - public List<ImGroupMemberDO> getGroupMembersByUserId(Long userId) { | |
| 85 | - return imGroupMemberMapper.selectListByUserId(userId); | |
| 86 | - } | |
| 87 | - | |
| 88 | -} | |
| 89 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxService.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.inbox; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 4 | - | |
| 5 | -import java.util.List; | |
| 6 | - | |
| 7 | -/** | |
| 8 | - * IM 收件箱 Service 接口 | |
| 9 | - * | |
| 10 | - * @author 芋道源码 | |
| 11 | - */ | |
| 12 | -public interface ImInboxService { | |
| 13 | - | |
| 14 | - /** | |
| 15 | - * 保存收件箱和发送消息 | |
| 16 | - * | |
| 17 | - * @param imMessageDO 收件箱保存消息 Request VO | |
| 18 | - */ | |
| 19 | - void saveInboxAndSendMessage(ImMessageDO imMessageDO); | |
| 20 | - | |
| 21 | - /** | |
| 22 | - * 获得大于 sequence 的消息 ids | |
| 23 | - * | |
| 24 | - * @param userId 用户编号 | |
| 25 | - * @param sequence 序列号 | |
| 26 | - * @param size 数量 | |
| 27 | - * @return 消息编号列表 | |
| 28 | - */ | |
| 29 | - List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size); | |
| 30 | - | |
| 31 | -} | |
| 32 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/inbox/ImInboxServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.inbox; | |
| 2 | - | |
| 3 | -import cn.hutool.core.date.DateUnit; | |
| 4 | -import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 5 | -import cn.iocoder.yudao.framework.common.util.object.BeanUtils; | |
| 6 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageRespVO; | |
| 7 | -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | |
| 8 | -import cn.iocoder.yudao.module.im.dal.dataobject.inbox.ImInboxDO; | |
| 9 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 10 | -import cn.iocoder.yudao.module.im.dal.mysql.inbox.ImInboxMapper; | |
| 11 | -import cn.iocoder.yudao.module.im.dal.redis.inbox.InboxLockRedisDAO; | |
| 12 | -import cn.iocoder.yudao.module.im.dal.redis.inbox.SequenceRedisDAO; | |
| 13 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 14 | -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; | |
| 15 | -import cn.iocoder.yudao.module.infra.api.websocket.WebSocketSenderApi; | |
| 16 | -import jakarta.annotation.Resource; | |
| 17 | -import org.springframework.scheduling.annotation.Async; | |
| 18 | -import org.springframework.stereotype.Service; | |
| 19 | -import org.springframework.validation.annotation.Validated; | |
| 20 | - | |
| 21 | -import java.util.List; | |
| 22 | - | |
| 23 | -/** | |
| 24 | - * 收件箱 Service 实现类 | |
| 25 | - * | |
| 26 | - * @author 芋道源码 | |
| 27 | - */ | |
| 28 | -@Service | |
| 29 | -@Validated | |
| 30 | -public class ImInboxServiceImpl implements ImInboxService { | |
| 31 | - | |
| 32 | - private static final Long INBOX_LOCK_TIMEOUT = 120 * DateUnit.SECOND.getMillis(); | |
| 33 | - private static final String IM_MESSAGE_RECEIVE = "im-message-receive"; | |
| 34 | - | |
| 35 | - @Resource | |
| 36 | - private ImInboxMapper imInboxMapper; | |
| 37 | - | |
| 38 | - @Resource | |
| 39 | - private SequenceRedisDAO sequenceRedisDAO; | |
| 40 | - @Resource | |
| 41 | - private InboxLockRedisDAO inboxLockRedisDAO; | |
| 42 | - | |
| 43 | - @Resource | |
| 44 | - private WebSocketSenderApi webSocketSenderApi; | |
| 45 | - @Resource | |
| 46 | - private ImGroupMemberService imGroupMemberService; | |
| 47 | - | |
| 48 | - @Override | |
| 49 | - public void saveInboxAndSendMessage(ImMessageDO message) { | |
| 50 | - // 1. 保存收件箱 + 发送消息给发送人 | |
| 51 | - saveInboxAndSendMessageForUser(message.getSenderId(), message); | |
| 52 | - // 2. 保存收件箱 + 发送消息给接收人 | |
| 53 | - if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) { | |
| 54 | - // 2.1 如果是单聊,直接发送给接收人 | |
| 55 | - saveInboxAndSendMessageForUser(message.getReceiverId(), message); | |
| 56 | - } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { | |
| 57 | - // 2.2 如果是群聊,发送给群聊的所有人 | |
| 58 | - List<ImGroupMemberDO> groupMembers = imGroupMemberService.selectByGroupId(message.getReceiverId()); | |
| 59 | - groupMembers.forEach(groupMemberDO -> saveInboxAndSendMessageForUser(groupMemberDO.getUserId(), message)); | |
| 60 | - } | |
| 61 | - } | |
| 62 | - | |
| 63 | - @Override | |
| 64 | - public List<Long> selectMessageIdsByUserIdAndSequence(Long userId, Long sequence, Integer size) { | |
| 65 | - List<ImInboxDO> imInboxDOS = imInboxMapper.selectListByUserIdAndSequence(userId, sequence, size); | |
| 66 | - return imInboxDOS.stream().map(ImInboxDO::getMessageId).toList(); | |
| 67 | - } | |
| 68 | - | |
| 69 | - | |
| 70 | - //TODO 多线程处理 | |
| 71 | - public void saveInboxAndSendMessageForUser(Long userId, ImMessageDO message) { | |
| 72 | - inboxLockRedisDAO.lock(userId, INBOX_LOCK_TIMEOUT, () -> { | |
| 73 | - // 1. 生成序列号 | |
| 74 | - Long userSequence = sequenceRedisDAO.generateSequence(userId); | |
| 75 | - // 2. 保存收件箱 | |
| 76 | - ImInboxDO inbox = new ImInboxDO() | |
| 77 | - .setUserId(userId) | |
| 78 | - .setMessageId(message.getId()) | |
| 79 | - .setSequence(userSequence); | |
| 80 | - imInboxMapper.insert(inbox); | |
| 81 | - // 3. 发送消息 | |
| 82 | - sendAsyncMessage(userId, message, userSequence); | |
| 83 | - }); | |
| 84 | - } | |
| 85 | - | |
| 86 | - @Async | |
| 87 | - public void sendAsyncMessage(Long userId, ImMessageDO message, Long userSequence) { | |
| 88 | - ImMessageRespVO messageRespVO = BeanUtils.toBean(message, ImMessageRespVO.class); | |
| 89 | - messageRespVO.setSequence(userSequence); | |
| 90 | - webSocketSenderApi.sendObject(UserTypeEnum.ADMIN.getValue(), userId, IM_MESSAGE_RECEIVE, messageRespVO); | |
| 91 | - } | |
| 92 | - | |
| 93 | -} | |
| 94 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageService.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.message; | |
| 2 | - | |
| 3 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListByNoReqVO; | |
| 4 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO; | |
| 5 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO; | |
| 6 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 7 | - | |
| 8 | -import java.util.List; | |
| 9 | - | |
| 10 | -/** | |
| 11 | - * 消息 Service 接口 | |
| 12 | - * | |
| 13 | - * @author 芋道源码 | |
| 14 | - */ | |
| 15 | -public interface ImMessageService { | |
| 16 | - | |
| 17 | - /** | |
| 18 | - * 获得历史消息 | |
| 19 | - * | |
| 20 | - * @param listReqVO 分页查询 | |
| 21 | - * @return 消息分页 | |
| 22 | - */ | |
| 23 | - List<ImMessageDO> getMessageList(ImMessageListReqVO listReqVO, Long loginUserId); | |
| 24 | - | |
| 25 | - /** | |
| 26 | - * 获得历史消息 | |
| 27 | - * | |
| 28 | - * @param listReqVO 分页查询 | |
| 29 | - * @return 消息分页 | |
| 30 | - */ | |
| 31 | - List<ImMessageDO> getMessageListByConversationNo(ImMessageListByNoReqVO listReqVO); | |
| 32 | - | |
| 33 | - /** | |
| 34 | - * 拉取消息-大于 seq 的消息 | |
| 35 | - * | |
| 36 | - * @param loginUserId 登录用户编号 | |
| 37 | - * @param sequence 序列号 | |
| 38 | - * @param size 数量 | |
| 39 | - * @return 消息列表 | |
| 40 | - */ | |
| 41 | - List<ImMessageDO> pullMessageList(Long loginUserId, Long sequence, Integer size); | |
| 42 | - | |
| 43 | - /** | |
| 44 | - * 发送消息 | |
| 45 | - * | |
| 46 | - * @param loginUserId 登录用户编号 | |
| 47 | - * @param message 消息 | |
| 48 | - * @return 消息编号 | |
| 49 | - */ | |
| 50 | - ImMessageDO sendMessage(Long loginUserId, ImMessageSendReqVO message); | |
| 51 | -} | |
| 52 | 0 | \ No newline at end of file |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java deleted
| 1 | -package cn.iocoder.yudao.module.im.service.message; | |
| 2 | - | |
| 3 | -import cn.hutool.core.bean.BeanUtil; | |
| 4 | -import cn.hutool.core.collection.CollUtil; | |
| 5 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListByNoReqVO; | |
| 6 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageListReqVO; | |
| 7 | -import cn.iocoder.yudao.module.im.controller.admin.message.vo.ImMessageSendReqVO; | |
| 8 | -import cn.iocoder.yudao.module.im.dal.dataobject.group.ImGroupMemberDO; | |
| 9 | -import cn.iocoder.yudao.module.im.dal.dataobject.message.ImMessageDO; | |
| 10 | -import cn.iocoder.yudao.module.im.dal.mysql.message.ImMessageMapper; | |
| 11 | -import cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum; | |
| 12 | -import cn.iocoder.yudao.module.im.enums.message.ImMessageSourceEnum; | |
| 13 | -import cn.iocoder.yudao.module.im.enums.message.ImMessageStatusEnum; | |
| 14 | -import cn.iocoder.yudao.module.im.service.groupmember.ImGroupMemberService; | |
| 15 | -import cn.iocoder.yudao.module.im.service.inbox.ImInboxService; | |
| 16 | -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 17 | -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 18 | -import jakarta.annotation.Resource; | |
| 19 | -import lombok.extern.slf4j.Slf4j; | |
| 20 | -import org.springframework.stereotype.Service; | |
| 21 | -import org.springframework.validation.annotation.Validated; | |
| 22 | - | |
| 23 | -import java.time.LocalDateTime; | |
| 24 | -import java.util.Collections; | |
| 25 | -import java.util.List; | |
| 26 | - | |
| 27 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 28 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 29 | -import static cn.iocoder.yudao.module.im.enums.ErrorCodeConstants.MESSAGE_RECEIVER_NOT_EXISTS; | |
| 30 | -import static cn.iocoder.yudao.module.im.enums.conversation.ImConversationTypeEnum.generateConversationNo; | |
| 31 | - | |
| 32 | -/** | |
| 33 | - * 消息 Service 实现类 | |
| 34 | - * | |
| 35 | - * @author 芋道源码 | |
| 36 | - */ | |
| 37 | -@Service | |
| 38 | -@Validated | |
| 39 | -@Slf4j | |
| 40 | -public class ImMessageServiceImpl implements ImMessageService { | |
| 41 | - | |
| 42 | - @Resource | |
| 43 | - private ImMessageMapper imMessageMapper; | |
| 44 | - @Resource | |
| 45 | - private AdminUserApi adminUserApi; | |
| 46 | - @Resource | |
| 47 | - private ImInboxService imInboxService; | |
| 48 | - @Resource | |
| 49 | - private ImGroupMemberService imGroupMemberService; | |
| 50 | - | |
| 51 | - @Override | |
| 52 | - public List<ImMessageDO> getMessageList(ImMessageListReqVO listReqVO, Long loginUserId) { | |
| 53 | - | |
| 54 | - String no = generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); | |
| 55 | - | |
| 56 | - ImMessageDO message = new ImMessageDO() | |
| 57 | - .setSendTime(listReqVO.getSendTime()) | |
| 58 | - .setConversationNo(no); | |
| 59 | - | |
| 60 | - return imMessageMapper.selectMessageList(message); | |
| 61 | - } | |
| 62 | - | |
| 63 | - @Override | |
| 64 | - public List<ImMessageDO> getMessageListByConversationNo(ImMessageListByNoReqVO listReqVO) { | |
| 65 | - | |
| 66 | - // 1. 查询历史消息 | |
| 67 | - ImMessageDO message = new ImMessageDO() | |
| 68 | - .setSendTime(listReqVO.getSendTime()) | |
| 69 | - .setConversationNo(listReqVO.getConversationNo()); | |
| 70 | - return imMessageMapper.selectMessageList(message); | |
| 71 | - } | |
| 72 | - | |
| 73 | - | |
| 74 | - @Override | |
| 75 | - public List<ImMessageDO> pullMessageList(Long userId, Long sequence, Integer size) { | |
| 76 | - List<Long> messageIds = imInboxService.selectMessageIdsByUserIdAndSequence(userId, sequence, size); | |
| 77 | - if (CollUtil.isEmpty(messageIds)) { | |
| 78 | - return Collections.emptyList(); | |
| 79 | - } | |
| 80 | - return imMessageMapper.selectBatchIds(messageIds); | |
| 81 | - } | |
| 82 | - | |
| 83 | - @Override | |
| 84 | - public ImMessageDO sendMessage(Long fromUserId, ImMessageSendReqVO imMessageSendReqVO) { | |
| 85 | - // 1. 保存消息 | |
| 86 | - ImMessageDO message = saveMessage(fromUserId, imMessageSendReqVO); | |
| 87 | - // 2. 保存到收件箱,并发送消息 | |
| 88 | - imInboxService.saveInboxAndSendMessage(message); | |
| 89 | - return message; | |
| 90 | - } | |
| 91 | - | |
| 92 | - private ImMessageDO saveMessage(Long fromUserId, ImMessageSendReqVO message) { | |
| 93 | - // TODO 芋艿:消息格式的校验 | |
| 94 | - // 1. 校验接收人是否存在 | |
| 95 | - validateReceiverIdExists(message); | |
| 96 | - // 2. 查询发送人信息 | |
| 97 | - AdminUserRespDTO fromUser = adminUserApi.getUser(fromUserId); | |
| 98 | - | |
| 99 | - // 3. 生成conversationNo | |
| 100 | - String conversationNo = generateConversationNo(fromUserId, message.getReceiverId(), message.getConversationType()); | |
| 101 | - | |
| 102 | - // 4. 保存消息 | |
| 103 | - ImMessageDO imMessageDO = BeanUtil.copyProperties(message, ImMessageDO.class) | |
| 104 | - .setSenderNickname(fromUser.getNickname()).setSenderAvatar(fromUser.getAvatar()) | |
| 105 | - .setSenderId(fromUserId) | |
| 106 | - .setConversationNo(conversationNo) | |
| 107 | - .setSendFrom(ImMessageSourceEnum.USER_SEND.getSource()) | |
| 108 | - .setMessageStatus(ImMessageStatusEnum.SENDING.getStatus()) | |
| 109 | - .setSendTime(LocalDateTime.now()); | |
| 110 | - imMessageMapper.insert(imMessageDO); | |
| 111 | - return imMessageDO; | |
| 112 | - } | |
| 113 | - | |
| 114 | - private void validateReceiverIdExists(ImMessageSendReqVO message) { | |
| 115 | - if (message.getConversationType().equals(ImConversationTypeEnum.SINGLE.getType())) { | |
| 116 | - // 校验用户是否存在 | |
| 117 | - AdminUserRespDTO receiverUser = adminUserApi.getUser(message.getReceiverId()); | |
| 118 | - if (receiverUser == null) { | |
| 119 | - throw exception(MESSAGE_RECEIVER_NOT_EXISTS); | |
| 120 | - } | |
| 121 | - } else if (message.getConversationType().equals(ImConversationTypeEnum.GROUP.getType())) { | |
| 122 | - // 校验群聊是否存在 | |
| 123 | - List<ImGroupMemberDO> imGroupMemberDOS = imGroupMemberService.selectByGroupId(message.getReceiverId()); | |
| 124 | - if (imGroupMemberDOS.isEmpty()) { | |
| 125 | - throw exception(MESSAGE_RECEIVER_NOT_EXISTS); | |
| 126 | - } | |
| 127 | - } | |
| 128 | - } | |
| 129 | - | |
| 130 | -} | |
| 131 | 0 | \ No newline at end of file |