diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java index 5b1e861587..1b42278dbb 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/ImConversationController.java @@ -1,7 +1,10 @@ package cn.iocoder.yudao.module.im.controller.admin.conversation; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; 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.ImConversationUpdatePinnedReqVO; @@ -75,4 +78,11 @@ public class ImConversationController { return success(true); } + @PostMapping("/create") + @Operation(summary = "创建会话") + public CommonResult createConversation(@Valid @RequestBody ImConversationCreateReqVO createReqVO) { + ImConversationDO conversation = imConversationService.createConversation(getLoginUserId(), createReqVO); + return success(conversation); + } + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationCreateReqVO.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationCreateReqVO.java new file mode 100755 index 0000000000..a86ee56a7d --- /dev/null +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/controller/admin/conversation/vo/ImConversationCreateReqVO.java @@ -0,0 +1,22 @@ +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 ImConversationCreateReqVO { + + @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; + +} \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java index 33e8e447b0..73ac5e5c53 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationService.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.im.service.conversation; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; 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; @@ -36,4 +37,6 @@ public interface ImConversationService { */ void updateLastReadTime(Long loginUserId, ImConversationUpdateLastReadTimeReqVO updateReqVO); + ImConversationDO createConversation(Long loginUserId, ImConversationCreateReqVO createReqVO); + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java index 121797918b..77cdd9b965 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java +++ b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/conversation/ImConversationServiceImpl.java @@ -1,5 +1,8 @@ package cn.iocoder.yudao.module.im.service.conversation; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.websocket.core.sender.WebSocketMessageSender; +import cn.iocoder.yudao.module.im.controller.admin.conversation.vo.ImConversationCreateReqVO; 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; @@ -13,6 +16,8 @@ import org.springframework.validation.annotation.Validated; import java.util.List; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; + /** * IM 会话 Service 实现类 * @@ -21,17 +26,24 @@ import java.util.List; @Service @Validated public class ImConversationServiceImpl implements ImConversationService { + private final String IM_CONVERSATION_ADD = "im-conversation-add"; @Resource private ImConversationMapper imConversationMapper; + @Resource + WebSocketMessageSender webSocketMessageSender; + @Override public List getConversationList(Long loginUserId) { // 根据loginUserId判断targetId, 自己不能做targetId - // 如何loginUserId和targetId相同,则需要调换userId和targetId + // 如果loginUserId和targetId相同,则需要调换userId和targetId List conversationList = imConversationMapper.selectList(); + + // 过滤和自己无关的会话 + List conversationFilteredList = conversationList.stream().filter(item -> loginUserId.equals(item.getUserId()) || loginUserId.equals(item.getTargetId())).toList(); // 遍历判断loginUserId和targetId相同,相同则将userId设置为targetId, targetId设置为userId - conversationList.forEach(item -> { + conversationFilteredList.forEach(item -> { if (item.getTargetId().equals(loginUserId)) { Long targetId = item.getTargetId(); Long userId = item.getUserId(); @@ -39,7 +51,7 @@ public class ImConversationServiceImpl implements ImConversationService { item.setUserId(targetId); } }); - return conversationList; + return conversationFilteredList; } @Override @@ -84,4 +96,29 @@ public class ImConversationServiceImpl implements ImConversationService { // 4. 做对应更新的 notify 推送 } + @Override + public ImConversationDO createConversation(Long loginUserId, ImConversationCreateReqVO createReqVO) { + // 1. 获得会话编号 + String no = ImConversationTypeEnum.generateConversationNo(loginUserId, createReqVO.getTargetId(), createReqVO.getType()); + // 2. 查询会话 + ImConversationDO conversation = imConversationMapper.selectByNo(no); + + if (conversation == null) { + // 2.1. 不存在,则插入 + conversation = insertConversation(no, loginUserId, createReqVO.getTargetId(), createReqVO.getType()); + } + + // 发送打开会话的通知,并推送会话实体 + // 给自己发送创建会话成功的通知 + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), getLoginUserId(), + IM_CONVERSATION_ADD, conversation); + + // 给接受者发送创建会话的通知 + webSocketMessageSender.sendObject(UserTypeEnum.ADMIN.getValue(), createReqVO.getTargetId(), + IM_CONVERSATION_ADD, conversation); + + return conversation; + } + + } \ No newline at end of file diff --git a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java b/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java index 9e95b3efd0..261fc8e501 100755 --- a/yudao-module-im/yudao-module-im-biz/src/main/java/cn/iocoder/yudao/module/im/service/message/ImMessageServiceImpl.java +++ b/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 { public List getMessageList(ImMessageListReqVO listReqVO) { // 1. 获得会话编号 - String no = ""; Long loginUserId = getLoginUserId(); - if (Objects.equals(loginUserId, listReqVO.getUserId())) { - no = generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); - } else { - no = generateConversationNo(listReqVO.getReceiverId(),loginUserId , listReqVO.getConversationType()); - } + String no1 = generateConversationNo(loginUserId, listReqVO.getReceiverId(), listReqVO.getConversationType()); + String no2 = generateConversationNo(listReqVO.getReceiverId(),loginUserId, listReqVO.getConversationType()); // 2. 查询历史消息 ImMessageDO message = new ImMessageDO() .setSendTime(listReqVO.getSendTime()) - .setConversationNo(no); - return imMessageMapper.selectMessageList(message); + .setConversationNo(no1); + List list = imMessageMapper.selectMessageList(message); + + if (!list.isEmpty()) { + return list; + } + + message.setConversationNo(no2); + list = imMessageMapper.selectMessageList(message); + + return list; } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index ab2f4e27d0..e06c40f5c1 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/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.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; +import java.util.*; import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -103,6 +101,37 @@ public class UserController { pageResult.getTotal())); } + @GetMapping("/all") + @Operation(summary = "获得所有用户列表") + @PreAuthorize("@ss.hasPermission('system:user:list')") + public CommonResult> getUserAll() { + List result = userService.getUserListAll(); + if (CollUtil.isEmpty(result)) { + return success(null); + } + // 拼接数据 + Map deptMap = deptService.getDeptMap( + convertList(result, AdminUserDO::getDeptId)); + return success(UserConvert.INSTANCE.convertList(result, deptMap)); + } + + @GetMapping("/listByDept") + @Operation(summary = "获得部门用户列表") + @PreAuthorize("@ss.hasPermission('system:user:list')") + @Parameter(name = "id", description = "编号", required = true, example = "1024") + public CommonResult> getDeptUsers(@RequestParam("id") Long id) { + List ids = new ArrayList<>(); + ids.add(id); + List result = userService.getDeptUsers(ids); + if (CollUtil.isEmpty(result)) { + return success(null); + } + // 拼接数据 + Map deptMap = deptService.getDeptMap( + convertList(result, AdminUserDO::getDeptId)); + return success(UserConvert.INSTANCE.convertList(result, deptMap)); + } + @GetMapping({"/list-all-simple", "/simple-list"}) @Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项") public CommonResult> getSimpleUserList() { diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java index 15564408d7..8c2ae476b3 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserService.java +++ b/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 { */ List getUserList(Collection ids); + + /** + * 获得全部用户列表 + * + * @return 用户列表 + */ + List getUserListAll(); + /** * 校验用户们是否有效。如下情况,视为无效: * 1. 用户编号不存在 @@ -207,6 +215,13 @@ public interface AdminUserService { */ List getUserListByStatus(Integer status); + /** + * 获得指定部门的用户 + * @param deptIds + * @return + */ + List getDeptUsers(Collection deptIds); + /** * 判断密码是否匹配 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java index 1beefc7c1c..66950c4d2c 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/user/AdminUserServiceImpl.java +++ b/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 { return userMapper.selectBatchIds(ids); } + public List getUserListAll() { + return userMapper.selectList(); + } + + @Override public void validateUserList(Collection ids) { if (CollUtil.isEmpty(ids)) { @@ -509,6 +514,11 @@ public class AdminUserServiceImpl implements AdminUserService { return userMapper.selectListByStatus(status); } + @Override + public List getDeptUsers(Collection deptIds) { + return userMapper.selectListByDeptIds(deptIds); + } + @Override public boolean isPasswordMatch(String rawPassword, String encodedPassword) { return passwordEncoder.matches(rawPassword, encodedPassword);