From 0d7cb763ff135b289c58f7193254695c234afc4c Mon Sep 17 00:00:00 2001 From: YunaiV Date: Tue, 5 May 2026 19:36:30 +0800 Subject: [PATCH] feat(im): 增加好友申请的管理界面 --- yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/ImFriendRequestManagerController.java | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java | 9 +++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerPageReqVO.java | 34 ++++++++++++++++++++++++++++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerRespVO.java | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java | 12 ++++++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java | 9 +++++++++ yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java | 7 +++++++ 7 files changed, 185 insertions(+), 0 deletions(-) create mode 100644 yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/ImFriendRequestManagerController.java create mode 100644 yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerPageReqVO.java create mode 100644 yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerRespVO.java diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/ImFriendRequestManagerController.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/ImFriendRequestManagerController.java new file mode 100644 index 0000000..eac0c9a --- /dev/null +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/ImFriendRequestManagerController.java @@ -0,0 +1,66 @@ +package cn.iocoder.yudao.module.im.controller.admin.manager.friend; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.pojo.CommonResult; +import cn.iocoder.yudao.framework.common.pojo.PageResult; +import cn.iocoder.yudao.framework.common.util.collection.MapUtils; +import cn.iocoder.yudao.framework.common.util.object.BeanUtils; +import cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo.ImFriendRequestManagerPageReqVO; +import cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo.ImFriendRequestManagerRespVO; +import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; +import cn.iocoder.yudao.module.im.service.friend.ImFriendRequestService; +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Stream; + +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap; + +@Tag(name = "管理后台 - IM 好友申请管理") +@RestController +@RequestMapping("/im/manager/friend-request") +@Validated +public class ImFriendRequestManagerController { + + @Resource + private ImFriendRequestService friendRequestService; + @Resource + private AdminUserApi adminUserApi; + + @GetMapping("/page") + @Operation(summary = "获得好友申请分页") + @PreAuthorize("@ss.hasPermission('im:manager:friend-request:query')") + public CommonResult> getFriendRequestPage( + @Valid ImFriendRequestManagerPageReqVO pageReqVO) { + // 1. 分页查询 + PageResult pageResult = friendRequestService.getFriendRequestPage(pageReqVO); + if (CollUtil.isEmpty(pageResult.getList())) { + return success(PageResult.empty(pageResult.getTotal())); + } + + // 2.1 一次性批量查询发起方 + 接收方的昵称 + Set userIds = convertSetByFlatMap(pageResult.getList(), + request -> Stream.of(request.getFromUserId(), request.getToUserId())); + Map userMap = adminUserApi.getUserMap(userIds); + // 2.2 转换为 VO,填充昵称 + return success(BeanUtils.toBean(pageResult, ImFriendRequestManagerRespVO.class, vo -> { + MapUtils.findAndThen(userMap, vo.getFromUserId(), + user -> vo.setFromNickname(user.getNickname())); + MapUtils.findAndThen(userMap, vo.getToUserId(), + user -> vo.setToNickname(user.getNickname())); + })); + } + +} diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java index 1b21920..6664f24 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendManagerRespVO.java @@ -27,9 +27,18 @@ public class ImFriendManagerRespVO { @Schema(description = "好友展示备注") private String displayName; + @Schema(description = "添加来源", example = "1") + private Integer addSource; // 参见 ImFriendAddSourceEnum 枚举类 + @Schema(description = "是否免打扰", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") private Boolean silent; + @Schema(description = "是否置顶联系人", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") + private Boolean pinned; + + @Schema(description = "是否拉黑", requiredMode = Schema.RequiredMode.REQUIRED, example = "false") + private Boolean blocked; + @Schema(description = "好友状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") private Integer status; // 参见 CommonStatusEnum 枚举类 diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerPageReqVO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerPageReqVO.java new file mode 100644 index 0000000..a078909 --- /dev/null +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerPageReqVO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo; + +import cn.iocoder.yudao.framework.common.pojo.PageParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +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; + +@Schema(description = "管理后台 - IM 好友申请分页 Request VO") +@Data +@EqualsAndHashCode(callSuper = true) +public class ImFriendRequestManagerPageReqVO extends PageParam { + + @Schema(description = "发起方用户编号", example = "1024") + private Long fromUserId; + + @Schema(description = "接收方用户编号", example = "2048") + private Long toUserId; + + @Schema(description = "处理结果", example = "0") + private Integer handleResult; // 参见 ImFriendRequestHandleResultEnum 枚举类 + + @Schema(description = "添加来源", example = "1") + private Integer addSource; // 参见 ImFriendAddSourceEnum 枚举类 + + @Schema(description = "创建时间", example = "[2026-04-01 00:00:00, 2026-04-30 23:59:59]") + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) + private LocalDateTime[] createTime; + +} diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerRespVO.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerRespVO.java new file mode 100644 index 0000000..9fa9d4d --- /dev/null +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/controller/admin/manager/friend/vo/ImFriendRequestManagerRespVO.java @@ -0,0 +1,48 @@ +package cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +@Schema(description = "管理后台 - IM 好友申请 Response VO") +@Data +public class ImFriendRequestManagerRespVO { + + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long id; + + @Schema(description = "发起方用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long fromUserId; + + @Schema(description = "发起方昵称", example = "张三") + private String fromNickname; + + @Schema(description = "接收方用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "2048") + private Long toUserId; + + @Schema(description = "接收方昵称", example = "李四") + private String toNickname; + + @Schema(description = "申请理由", example = "我是芋艿") + private String applyContent; + + @Schema(description = "发起方对接收方的备注") + private String displayName; + + @Schema(description = "添加来源", example = "1") + private Integer addSource; // 参见 ImFriendAddSourceEnum 枚举类 + + @Schema(description = "处理结果", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") + private Integer handleResult; // 参见 ImFriendRequestHandleResultEnum 枚举类 + + @Schema(description = "处理理由", example = "暂不通过") + private String handleContent; + + @Schema(description = "处理时间") + private LocalDateTime handleTime; + + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) + private LocalDateTime createTime; + +} diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java index 7fddddb..bdf61aa 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/dal/mysql/friend/ImFriendRequestMapper.java @@ -1,7 +1,9 @@ package cn.iocoder.yudao.module.im.dal.mysql.friend; +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.manager.friend.vo.ImFriendRequestManagerPageReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import org.apache.ibatis.annotations.Mapper; @@ -43,4 +45,14 @@ public interface ImFriendRequestMapper extends BaseMapperX { .eq(ImFriendRequestDO::getId, id).eq(ImFriendRequestDO::getHandleResult, handleResult)); } + default PageResult selectPage(ImFriendRequestManagerPageReqVO reqVO) { + return selectPage(reqVO, new LambdaQueryWrapperX() + .eqIfPresent(ImFriendRequestDO::getFromUserId, reqVO.getFromUserId()) + .eqIfPresent(ImFriendRequestDO::getToUserId, reqVO.getToUserId()) + .eqIfPresent(ImFriendRequestDO::getHandleResult, reqVO.getHandleResult()) + .eqIfPresent(ImFriendRequestDO::getAddSource, reqVO.getAddSource()) + .betweenIfPresent(ImFriendRequestDO::getCreateTime, reqVO.getCreateTime()) + .orderByDesc(ImFriendRequestDO::getId)); + } + } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java index 82f053a..e914f3b 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestService.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.im.service.friend; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.im.controller.admin.friend.vo.request.ImFriendRequestApplyReqVO; +import cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo.ImFriendRequestManagerPageReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; import java.util.List; @@ -53,4 +55,11 @@ public interface ImFriendRequestService { */ ImFriendRequestDO getFriendRequest(Long id); + // ==================== 管理后台 ==================== + + /** + * 【管理后台】分页查询好友申请记录 + */ + PageResult getFriendRequestPage(ImFriendRequestManagerPageReqVO reqVO); + } diff --git a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java index 7d4e741..838333f 100644 --- a/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java +++ b/yudao-module-im/src/main/java/cn/iocoder/yudao/module/im/service/friend/ImFriendRequestServiceImpl.java @@ -5,8 +5,10 @@ import cn.hutool.core.bean.copier.CopyOptions; import cn.hutool.core.util.ObjUtil; import cn.hutool.extra.spring.SpringUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.im.controller.admin.friend.vo.request.ImFriendRequestApplyReqVO; +import cn.iocoder.yudao.module.im.controller.admin.manager.friend.vo.ImFriendRequestManagerPageReqVO; import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendDO; import cn.iocoder.yudao.module.im.dal.dataobject.friend.ImFriendRequestDO; import cn.iocoder.yudao.module.im.dal.mysql.friend.ImFriendRequestMapper; @@ -200,6 +202,11 @@ public class ImFriendRequestServiceImpl implements ImFriendRequestService { return friendRequestMapper.selectById(id); } + @Override + public PageResult getFriendRequestPage(ImFriendRequestManagerPageReqVO reqVO) { + return friendRequestMapper.selectPage(reqVO); + } + /** * 校验申请可被「当前用户」处理:申请存在 + 未处理 + 操作人 = 接收方 */ -- libgit2 0.21.4