Commit d67362043e94f428ecc6f8b6d2f0929f97315bec
1 parent
29a3ad42
创建会话
Showing
8 changed files
with
145 additions
and
14 deletions
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java
| 1 | 1 | package cn.iocoder.yudao.module.im.controller.admin.conversation; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 3 | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | 5 | import cn.iocoder.yudao.framework.common.util.object.BeanUtils; |
| 6 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; | |
| 7 | +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; | |
| 5 | 8 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; |
| 6 | 9 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationRespVO; |
| 7 | 10 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; |
| ... | ... | @@ -75,4 +78,11 @@ public class ImConversationController { |
| 75 | 78 | return success(true); |
| 76 | 79 | } |
| 77 | 80 | |
| 81 | + @PostMapping("/create") | |
| 82 | + @Operation(summary = "创建会话") | |
| 83 | + public CommonResult<ImConversationDO> createConversation(@Valid @RequestBody ImConversationCreateReqVO createReqVO) { | |
| 84 | + ImConversationDO conversation = imConversationService.createConversation(getLoginUserId(), createReqVO); | |
| 85 | + return success(conversation); | |
| 86 | + } | |
| 87 | + | |
| 78 | 88 | } |
| 79 | 89 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationCreateReqVO.java
0 → 100755
| 1 | +package cn.iocoder.yudao.module.im.controller.admin.conversation.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 | + | |
| 9 | +import java.time.LocalDateTime; | |
| 10 | + | |
| 11 | +@Schema(description = "管理后台 - 会话最后已读时间 Request VO") | |
| 12 | +@Data | |
| 13 | +public class ImConversationCreateReqVO { | |
| 14 | + | |
| 15 | + @Schema(description = "聊天对象编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") | |
| 16 | + private Long targetId; | |
| 17 | + | |
| 18 | + @Schema(description = "会话类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | |
| 19 | + @InEnum(value = ImConversationTypeEnum.class, message = "会话类型必须是 {value}") | |
| 20 | + private Integer type; | |
| 21 | + | |
| 22 | +} | |
| 0 | 23 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java
| 1 | 1 | package cn.iocoder.yudao.module.im.service.conversation; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; | |
| 3 | 4 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; |
| 4 | 5 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; |
| 5 | 6 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| ... | ... | @@ -36,4 +37,6 @@ public interface ImConversationService { |
| 36 | 37 | */ |
| 37 | 38 | void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO); |
| 38 | 39 | |
| 40 | + ImConversationDO createConversation(Long loginUserId, ImConversationCreateReqVO createReqVO); | |
| 41 | + | |
| 39 | 42 | } |
| 40 | 43 | \ No newline at end of file | ... | ... |
yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java
| 1 | 1 | package cn.iocoder.yudao.module.im.service.conversation; |
| 2 | 2 | |
| 3 | +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | |
| 4 | +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; | |
| 5 | +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; | |
| 3 | 6 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdateLastReadTimeReqVO; |
| 4 | 7 | import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationUpdatePinnedReqVO; |
| 5 | 8 | import cn.iocoder.yudao.module.im.dal.dataobject.conversation.ImConversationDO; |
| ... | ... | @@ -13,6 +16,8 @@ import org.springframework.validation.annotation.Validated; |
| 13 | 16 | |
| 14 | 17 | import java.util.List; |
| 15 | 18 | |
| 19 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | |
| 20 | + | |
| 16 | 21 | /** |
| 17 | 22 | * IM 会话 Service 实现类 |
| 18 | 23 | * |
| ... | ... | @@ -21,17 +26,24 @@ import java.util.List; |
| 21 | 26 | @Service |
| 22 | 27 | @Validated |
| 23 | 28 | public class ImConversationServiceImpl implements ImConversationService { |
| 29 | + private final String IM_CONVERSATION_ADD = "im-conversation-add"; | |
| 24 | 30 | |
| 25 | 31 | @Resource |
| 26 | 32 | private ImConversationMapper imConversationMapper; |
| 27 | 33 | |
| 34 | + @Resource | |
| 35 | + WebSocketMessageSender webSocketMessageSender; | |
| 36 | + | |
| 28 | 37 | @Override |
| 29 | 38 | public List<ImConversationDO> getConversationList(Long loginUserId) { |
| 30 | 39 | // 根据loginUserId判断targetId, 自己不能做targetId |
| 31 | - // 如何loginUserId和targetId相同,则需要调换userId和targetId | |
| 40 | + // 如果loginUserId和targetId相同,则需要调换userId和targetId | |
| 32 | 41 | List<ImConversationDO> conversationList = imConversationMapper.selectList(); |
| 42 | + | |
| 43 | + // 过滤和自己无关的会话 | |
| 44 | + List<ImConversationDO> conversationFilteredList = conversationList.stream().filter(item -> loginUserId.equals(item.getUserId()) || loginUserId.equals(item.getTargetId())).toList(); | |
| 33 | 45 | // 遍历判断loginUserId和targetId相同,相同则将userId设置为targetId, targetId设置为userId |
| 34 | - conversationList.forEach(item -> { | |
| 46 | + conversationFilteredList.forEach(item -> { | |
| 35 | 47 | if (item.getTargetId().equals(loginUserId)) { |
| 36 | 48 | Long targetId = item.getTargetId(); |
| 37 | 49 | Long userId = item.getUserId(); |
| ... | ... | @@ -39,7 +51,7 @@ public class ImConversationServiceImpl implements ImConversationService { |
| 39 | 51 | item.setUserId(targetId); |
| 40 | 52 | } |
| 41 | 53 | }); |
| 42 | - return conversationList; | |
| 54 | + return conversationFilteredList; | |
| 43 | 55 | } |
| 44 | 56 | |
| 45 | 57 | @Override |
| ... | ... | @@ -84,4 +96,29 @@ public class ImConversationServiceImpl implements ImConversationService { |
| 84 | 96 | // 4. 做对应更新的 notify 推送 |
| 85 | 97 | } |
| 86 | 98 | |
| 99 | + @Override | |
| 100 | + public ImConversationDO createConversation(Long loginUserId, ImConversationCreateReqVO createReqVO) { | |
| 101 | + // 1. 获得会话编号 | |
| 102 | + String no = ImConversationTypeEnum.generateConversationNo(loginUserId, createReqVO.getTargetId(), createReqVO.getType()); | |
| 103 | + // 2. 查询会话 | |
| 104 | + ImConversationDO conversation = imConversationMapper.selectByNo(no); | |
| 105 | + | |
| 106 | + if (conversation == null) { | |
| 107 | + // 2.1. 不存在,则插入 | |
| 108 | + conversation = insertConversation(no, loginUserId, createReqVO.getTargetId(), createReqVO.getType()); | |
| 109 | + } | |
| 110 | + | |
| 111 | + // 发送打开会话的通知,并推送会话实体 | |
| 112 | + // 给自己发送创建会话成功的通知 | |
| 113 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), getLoginUserId(), | |
| 114 | + IM_CONVERSATION_ADD, conversation); | |
| 115 | + | |
| 116 | + // 给接受者发送创建会话的通知 | |
| 117 | + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), createReqVO.getTargetId(), | |
| 118 | + IM_CONVERSATION_ADD, conversation); | |
| 119 | + | |
| 120 | + return conversation; | |
| 121 | + } | |
| 122 | + | |
| 123 | + | |
| 87 | 124 | } |
| 88 | 125 | \ 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
| ... | ... | @@ -53,19 +53,24 @@ public class ImMessageServiceImpl implements ImMessageService { |
| 53 | 53 | public List<ImMessageDO> getMessageList(ImMessageListReqVO listReqVO) { |
| 54 | 54 | |
| 55 | 55 | // 1. 获得会话编号 |
| 56 | - String no = ""; | |
| 57 | 56 | Long loginUserId = getLoginUserId(); |
| 58 | - if (Objects.equals(loginUserId, listReqVO.getUserId())) { | |
| 59 | - no = generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); | |
| 60 | - } else { | |
| 61 | - no = generateConversationNo(listReqVO.getReceiverId(),loginUserId , listReqVO.getConversationType()); | |
| 62 | - } | |
| 57 | + String no1 = generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); | |
| 58 | + String no2 = generateConversationNo(listReqVO.getReceiverId(),loginUserId, listReqVO.getConversationType()); | |
| 63 | 59 | |
| 64 | 60 | // 2. 查询历史消息 |
| 65 | 61 | ImMessageDO message = new ImMessageDO() |
| 66 | 62 | .setSendTime(listReqVO.getSendTime()) |
| 67 | - .setConversationNo(no); | |
| 68 | - return imMessageMapper.selectMessageList(message); | |
| 63 | + .setConversationNo(no1); | |
| 64 | + List<ImMessageDO> list = imMessageMapper.selectMessageList(message); | |
| 65 | + | |
| 66 | + if (!list.isEmpty()) { | |
| 67 | + return list; | |
| 68 | + } | |
| 69 | + | |
| 70 | + message.setConversationNo(no2); | |
| 71 | + list = imMessageMapper.selectMessageList(message); | |
| 72 | + | |
| 73 | + return list; | |
| 69 | 74 | } |
| 70 | 75 | |
| 71 | 76 | @Override | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java
| ... | ... | @@ -27,9 +27,7 @@ import org.springframework.web.bind.annotation.*; |
| 27 | 27 | import org.springframework.web.multipart.MultipartFile; |
| 28 | 28 | |
| 29 | 29 | import java.io.IOException; |
| 30 | -import java.util.Arrays; | |
| 31 | -import java.util.List; | |
| 32 | -import java.util.Map; | |
| 30 | +import java.util.*; | |
| 33 | 31 | |
| 34 | 32 | import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; |
| 35 | 33 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| ... | ... | @@ -103,6 +101,37 @@ public class UserController { |
| 103 | 101 | pageResult.getTotal())); |
| 104 | 102 | } |
| 105 | 103 | |
| 104 | + @GetMapping("/all") | |
| 105 | + @Operation(summary = "获得所有用户列表") | |
| 106 | + @PreAuthorize("@ss.hasPermission('system:user:list')") | |
| 107 | + public CommonResult<List<UserRespVO>> getUserAll() { | |
| 108 | + List<AdminUserDO> result = userService.getUserListAll(); | |
| 109 | + if (CollUtil.isEmpty(result)) { | |
| 110 | + return success(null); | |
| 111 | + } | |
| 112 | + // 拼接数据 | |
| 113 | + Map<Long, DeptDO> deptMap = deptService.getDeptMap( | |
| 114 | + convertList(result, AdminUserDO::getDeptId)); | |
| 115 | + return success(UserConvert.INSTANCE.convertList(result, deptMap)); | |
| 116 | + } | |
| 117 | + | |
| 118 | + @GetMapping("/listByDept") | |
| 119 | + @Operation(summary = "获得部门用户列表") | |
| 120 | + @PreAuthorize("@ss.hasPermission('system:user:list')") | |
| 121 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | |
| 122 | + public CommonResult<List<UserRespVO>> getDeptUsers(@RequestParam("id") Long id) { | |
| 123 | + List<Long> ids = new ArrayList<>(); | |
| 124 | + ids.add(id); | |
| 125 | + List<AdminUserDO> result = userService.getDeptUsers(ids); | |
| 126 | + if (CollUtil.isEmpty(result)) { | |
| 127 | + return success(null); | |
| 128 | + } | |
| 129 | + // 拼接数据 | |
| 130 | + Map<Long, DeptDO> deptMap = deptService.getDeptMap( | |
| 131 | + convertList(result, AdminUserDO::getDeptId)); | |
| 132 | + return success(UserConvert.INSTANCE.convertList(result, deptMap)); | |
| 133 | + } | |
| 134 | + | |
| 106 | 135 | @GetMapping({"/list-all-simple", "/simple-list"}) |
| 107 | 136 | @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") |
| 108 | 137 | public CommonResult<List<UserSimpleRespVO>> getSimpleUserList() { | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java
| ... | ... | @@ -160,6 +160,14 @@ public interface AdminUserService { |
| 160 | 160 | */ |
| 161 | 161 | List<AdminUserDO> getUserList(Collection<Long> ids); |
| 162 | 162 | |
| 163 | + | |
| 164 | + /** | |
| 165 | + * 获得全部用户列表 | |
| 166 | + * | |
| 167 | + * @return 用户列表 | |
| 168 | + */ | |
| 169 | + List<AdminUserDO> getUserListAll(); | |
| 170 | + | |
| 163 | 171 | /** |
| 164 | 172 | * 校验用户们是否有效。如下情况,视为无效: |
| 165 | 173 | * 1. 用户编号不存在 |
| ... | ... | @@ -208,6 +216,13 @@ public interface AdminUserService { |
| 208 | 216 | List<AdminUserDO> getUserListByStatus(Integer status); |
| 209 | 217 | |
| 210 | 218 | /** |
| 219 | + * 获得指定部门的用户 | |
| 220 | + * @param deptIds | |
| 221 | + * @return | |
| 222 | + */ | |
| 223 | + List<AdminUserDO> getDeptUsers(Collection<Long> deptIds); | |
| 224 | + | |
| 225 | + /** | |
| 211 | 226 | * 判断密码是否匹配 |
| 212 | 227 | * |
| 213 | 228 | * @param rawPassword 未加密的密码 | ... | ... |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java
| ... | ... | @@ -308,6 +308,11 @@ public class AdminUserServiceImpl implements AdminUserService { |
| 308 | 308 | return userMapper.selectBatchIds(ids); |
| 309 | 309 | } |
| 310 | 310 | |
| 311 | + public List<AdminUserDO> getUserListAll() { | |
| 312 | + return userMapper.selectList(); | |
| 313 | + } | |
| 314 | + | |
| 315 | + | |
| 311 | 316 | @Override |
| 312 | 317 | public void validateUserList(Collection<Long> ids) { |
| 313 | 318 | if (CollUtil.isEmpty(ids)) { |
| ... | ... | @@ -510,6 +515,11 @@ public class AdminUserServiceImpl implements AdminUserService { |
| 510 | 515 | } |
| 511 | 516 | |
| 512 | 517 | @Override |
| 518 | + public List<AdminUserDO> getDeptUsers(Collection<Long> deptIds) { | |
| 519 | + return userMapper.selectListByDeptIds(deptIds); | |
| 520 | + } | |
| 521 | + | |
| 522 | + @Override | |
| 513 | 523 | public boolean isPasswordMatch(String rawPassword, String encodedPassword) { |
| 514 | 524 | return passwordEncoder.matches(rawPassword, encodedPassword); |
| 515 | 525 | } | ... | ... |