wrapper = new LambdaQueryWrapper<>();
initWrapper.accept(wrapper);
if (StrUtil.isNotBlank(request.getCursor())) {
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserApplyDao.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserApplyDao.java
index 0beacd6..187cea4 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserApplyDao.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserApplyDao.java
@@ -1,11 +1,20 @@
package com.abin.mallchat.common.user.dao;
import com.abin.mallchat.common.user.domain.entity.UserApply;
+import com.abin.mallchat.common.user.domain.enums.ApplyStatusEnum;
+import com.abin.mallchat.common.user.domain.enums.ApplyTypeEnum;
import com.abin.mallchat.common.user.mapper.UserApplyMapper;
-import com.abin.mallchat.common.user.service.IUserApplyService;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
+import java.util.List;
+
+import static com.abin.mallchat.common.user.domain.enums.ApplyReadStatusEnum.READ;
+import static com.abin.mallchat.common.user.domain.enums.ApplyReadStatusEnum.UNREAD;
+import static com.abin.mallchat.common.user.domain.enums.ApplyStatusEnum.AGREE;
+
/**
*
* 用户申请表 服务实现类
@@ -15,6 +24,42 @@ import org.springframework.stereotype.Service;
* @since 2023-07-16
*/
@Service
-public class UserApplyDao extends ServiceImpl implements IUserApplyService {
+public class UserApplyDao extends ServiceImpl {
+ public UserApply getFriendApproving(Long uid, Long targetUid) {
+ return lambdaQuery().eq(UserApply::getUid, uid)
+ .eq(UserApply::getTargetId, targetUid)
+ .eq(UserApply::getStatus, ApplyStatusEnum.WAIT_APPROVAL)
+ .eq(UserApply::getType, ApplyTypeEnum.ADD_FRIEND.getCode())
+ .one();
+ }
+
+ public Integer getUnReadCount(Long targetId) {
+ return lambdaQuery().eq(UserApply::getTargetId, targetId)
+ .eq(UserApply::getReadStatus, UNREAD.getCode())
+ .count();
+ }
+
+ public IPage FriendApplyPage(Long uid, Page page) {
+ return lambdaQuery()
+ .eq(UserApply::getTargetId, uid)
+ .eq(UserApply::getType, ApplyTypeEnum.ADD_FRIEND.getCode())
+ .orderByAsc(UserApply::getCreateTime)
+ .page(page);
+ }
+
+ public void readApples(Long uid, List applyIds) {
+ lambdaUpdate()
+ .set(UserApply::getReadStatus, READ.getCode())
+ .eq(UserApply::getReadStatus, UNREAD.getCode())
+ .in(UserApply::getId, applyIds)
+ .eq(UserApply::getTargetId, uid)
+ .update();
+ }
+
+ public void agree(Long applyId) {
+ lambdaUpdate().set(UserApply::getStatus, AGREE.getCode())
+ .eq(UserApply::getId, applyId)
+ .update();
+ }
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserFriendDao.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserFriendDao.java
index 5921882..8dcc587 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserFriendDao.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/dao/UserFriendDao.java
@@ -2,10 +2,11 @@ package com.abin.mallchat.common.user.dao;
import com.abin.mallchat.common.user.domain.entity.UserFriend;
import com.abin.mallchat.common.user.mapper.UserFriendMapper;
-import com.abin.mallchat.common.user.service.IUserFriendService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
+import java.util.List;
+
/**
*
* 用户联系人表 服务实现类
@@ -15,6 +16,17 @@ import org.springframework.stereotype.Service;
* @since 2023-07-16
*/
@Service
-public class UserFriendDao extends ServiceImpl implements IUserFriendService {
+public class UserFriendDao extends ServiceImpl {
+ public List getByFriends(Long uid, List uidList) {
+ return lambdaQuery().eq(UserFriend::getUid, uid)
+ .in(UserFriend::getFriendUid, uidList)
+ .list();
+ }
+
+ public UserFriend getByFriend(Long uid, Long targetUid) {
+ return lambdaQuery().eq(UserFriend::getUid, uid)
+ .eq(UserFriend::getFriendUid, targetUid)
+ .one();
+ }
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserRole.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserRole.java
index 9d8340a..075ffc9 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserRole.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/domain/entity/UserRole.java
@@ -54,6 +54,4 @@ public class UserRole implements Serializable {
*/
@TableField("update_time")
private LocalDateTime updateTime;
-
-
}
diff --git a/mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserCache.java b/mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserCache.java
index 44b7321..c5cc861 100644
--- a/mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserCache.java
+++ b/mallchat-common/src/main/java/com/abin/mallchat/common/user/service/cache/UserCache.java
@@ -31,8 +31,6 @@ import java.util.stream.Collectors;
@Component
public class UserCache {
- @Autowired
- private CursorUtils cursorUtils;
@Autowired
private UserDao userDao;
@Autowired
@@ -88,11 +86,11 @@ public class UserCache {
}
public CursorPageBaseResp> getOnlineCursorPage(CursorPageBaseReq pageBaseReq) {
- return cursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.ONLINE_UID_ZET), Long::parseLong);
+ return CursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.ONLINE_UID_ZET), Long::parseLong);
}
public CursorPageBaseResp> getOfflineCursorPage(CursorPageBaseReq pageBaseReq) {
- return cursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.OFFLINE_UID_ZET), Long::parseLong);
+ return CursorUtils.getCursorPageByRedis(pageBaseReq, RedisKey.getKey(RedisKey.OFFLINE_UID_ZET), Long::parseLong);
}
public List getUserModifyTime(List uidList) {
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java
index 10bbbd6..1cf8b36 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ChatController.java
@@ -1,6 +1,7 @@
package com.abin.mallchat.custom.chat.controller;
+import com.abin.mallchat.common.chat.domain.dto.MsgReadInfoDTO;
import com.abin.mallchat.common.common.annotation.FrequencyControl;
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.ApiResult;
@@ -19,6 +20,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
+import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -51,7 +53,6 @@ public class ChatController {
@ApiOperation("群成员列表")
@FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
public ApiResult> getMemberPage(@Valid CursorPageBaseReq request) {
-// black(request);
CursorPageBaseResp memberPage = chatService.getMemberPage(request);
filterBlackMember(memberPage);
return ApiResult.success(memberPage);
@@ -59,6 +60,7 @@ public class ChatController {
@GetMapping("/member/list")
@ApiOperation("房间内的所有群成员列表-@专用")
+ @Deprecated
public ApiResult> getMemberList(@Valid ChatMessageMemberReq chatMessageMemberReq) {
return ApiResult.success(chatService.getMemberList(chatMessageMemberReq));
}
@@ -74,6 +76,7 @@ public class ChatController {
@GetMapping("public/member/statistic")
@ApiOperation("群成员人数统计")
+ @Deprecated
public ApiResult getMemberStatistic() {
return ApiResult.success(chatService.getMemberStatistic());
}
@@ -85,7 +88,6 @@ public class ChatController {
@ApiOperation("消息列表")
@FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
public ApiResult> getMsgPage(@Valid ChatMessagePageReq request) {
-// black(request);
CursorPageBaseResp msgPage = chatService.getMsgPage(request, RequestHolder.get().getUid());
filterBlackMsg(msgPage);
return ApiResult.success(msgPage);
@@ -101,7 +103,7 @@ public class ChatController {
@FrequencyControl(time = 5, count = 3, target = FrequencyControl.Target.UID)
@FrequencyControl(time = 30, count = 5, target = FrequencyControl.Target.UID)
@FrequencyControl(time = 60, count = 10, target = FrequencyControl.Target.UID)
- public ApiResult sendMsg(@Valid @RequestBody ChatMessageReq request) {
+ public ApiResult sendMsg(@Valid @RequestBody ChatMessageReq request) {//todo 发送给单聊
Long msgId = chatService.sendMsg(request, RequestHolder.get().getUid());
//返回完整消息格式,方便前端展示
return ApiResult.success(chatService.getMsgResp(msgId, RequestHolder.get().getUid()));
@@ -122,5 +124,19 @@ public class ChatController {
chatService.recallMsg(RequestHolder.get().getUid(), request);
return ApiResult.success();
}
+
+ @GetMapping("/msg/read/page")
+ @ApiOperation("消息的已读未读列表")
+ public ApiResult> getReadPage(@Valid ChatMessageReadReq request) {
+ Long uid = RequestHolder.get().getUid();
+ return ApiResult.success(chatService.getReadPage(uid, request));
+ }
+
+ @GetMapping("/msg/read")
+ @ApiOperation("获取消息的已读未读总数")
+ public ApiResult> getReadInfo(@Valid ChatMessageReadInfoReq request) {
+ Long uid = RequestHolder.get().getUid();
+ return ApiResult.success(chatService.getMsgReadInfo(uid, request));
+ }
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ContactController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ContactController.java
new file mode 100644
index 0000000..cbb5ee5
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/ContactController.java
@@ -0,0 +1,48 @@
+package com.abin.mallchat.custom.chat.controller;
+
+
+import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
+import com.abin.mallchat.common.common.domain.vo.response.ApiResult;
+import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
+import com.abin.mallchat.common.common.utils.RequestHolder;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp;
+import com.abin.mallchat.custom.chat.service.ChatService;
+import com.abin.mallchat.custom.chat.service.RoomService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.validation.Valid;
+
+/**
+ *
+ * 会话相关接口
+ *
+ *
+ * @author abin
+ * @since 2023-03-19
+ */
+@RestController
+@RequestMapping("/capi/chat")
+@Api(tags = "聊天室相关接口")
+@Slf4j
+public class ContactController {
+ @Autowired
+ private ChatService chatService;
+ @Autowired
+ private RoomService roomService;
+
+ @GetMapping("/public/contact/page")
+ @ApiOperation("会话列表")
+ public ApiResult> getRoomPage(@Valid CursorPageBaseReq request) {
+ Long uid = RequestHolder.get().getUid();
+ return ApiResult.success(roomService.getContactPage(request, uid));
+ }
+
+
+}
+
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/RoomController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/RoomController.java
new file mode 100644
index 0000000..fb71cbf
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/controller/RoomController.java
@@ -0,0 +1,79 @@
+package com.abin.mallchat.custom.chat.controller;
+
+
+import com.abin.mallchat.common.common.annotation.FrequencyControl;
+import com.abin.mallchat.common.common.domain.vo.request.IdReqVO;
+import com.abin.mallchat.common.common.domain.vo.response.ApiResult;
+import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
+import com.abin.mallchat.common.common.utils.RequestHolder;
+import com.abin.mallchat.common.user.service.cache.UserCache;
+import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageMemberReq;
+import com.abin.mallchat.custom.chat.domain.vo.request.MemberAddReq;
+import com.abin.mallchat.custom.chat.domain.vo.request.MemberDelReq;
+import com.abin.mallchat.custom.chat.domain.vo.request.MemberReq;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberListResp;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatMemberResp;
+import com.abin.mallchat.custom.chat.domain.vo.response.MemberResp;
+import com.abin.mallchat.custom.chat.service.ChatService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ *
+ * 房间相关接口
+ *
+ *
+ * @author abin
+ * @since 2023-03-19
+ */
+@RestController
+@RequestMapping("/capi/room")
+@Api(tags = "聊天室相关接口")
+@Slf4j
+public class RoomController {
+ @Autowired
+ private ChatService chatService;
+ @Autowired
+ private UserCache userCache;
+
+ @GetMapping("/public/group")
+ @ApiOperation("群组详情")
+ public ApiResult groupDetail(@Valid IdReqVO request) {
+ return ApiResult.success();
+ }
+
+ @GetMapping("/public/group/member/page")
+ @ApiOperation("群成员列表")
+ @FrequencyControl(time = 120, count = 20, target = FrequencyControl.Target.IP)
+ public ApiResult> getMemberPage(@Valid MemberReq request) {
+ CursorPageBaseResp memberPage = chatService.getMemberPage(request);
+ return ApiResult.success(memberPage);
+ }
+
+ @GetMapping("/group/member/list")
+ @ApiOperation("房间内的所有群成员列表-@专用")
+ public ApiResult> getMemberList(@Valid ChatMessageMemberReq request) {
+ return ApiResult.success(chatService.getMemberList(request));
+ }
+
+ @DeleteMapping("/group/member")
+ @ApiOperation("移除成员")
+ public ApiResult delMember(@Valid @RequestBody MemberDelReq request) {
+ Long uid = RequestHolder.get().getUid();
+ return ApiResult.success();
+ }
+
+ @PostMapping("/group/member")
+ @ApiOperation("邀请好友")
+ public ApiResult> addMember(@Valid @RequestBody MemberAddReq request) {
+ Long uid = RequestHolder.get().getUid();
+ return ApiResult.success();
+ }
+}
+
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadInfoReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadInfoReq.java
new file mode 100644
index 0000000..2b1c585
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadInfoReq.java
@@ -0,0 +1,25 @@
+package com.abin.mallchat.custom.chat.domain.vo.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-17
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ChatMessageReadInfoReq {
+ @ApiModelProperty("消息id集合(只查本人)")
+ @Size(max = 20)
+ private List msgIds;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadReq.java
new file mode 100644
index 0000000..686318a
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReadReq.java
@@ -0,0 +1,29 @@
+package com.abin.mallchat.custom.chat.domain.vo.request;
+
+import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-17
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ChatMessageReadReq extends CursorPageBaseReq {
+ @ApiModelProperty("消息id")
+ @NotNull
+ private Long msgId;
+
+ @ApiModelProperty("查询类型 1已读 2未读")
+ @NotNull
+ private Long searchType;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java
index b255a34..4300f94 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/ChatMessageReq.java
@@ -24,7 +24,7 @@ import javax.validation.constraints.NotNull;
@NoArgsConstructor
public class ChatMessageReq {
@NotNull
- @ApiModelProperty("会话id")
+ @ApiModelProperty("房间id")
private Long roomId;
@ApiModelProperty("消息类型")
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberAddReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberAddReq.java
new file mode 100644
index 0000000..661148a
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberAddReq.java
@@ -0,0 +1,31 @@
+package com.abin.mallchat.custom.chat.domain.vo.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * Description: 移除群成员
+ * Author: abin
+ * Date: 2023-03-29
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberAddReq {
+ @NotNull
+ @ApiModelProperty("会话id")
+ private Long roomId;
+
+ @NotNull
+ @Size(min = 1, max = 50)
+ @ApiModelProperty("邀请的uid")
+ private List uidList;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberDelReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberDelReq.java
new file mode 100644
index 0000000..7951023
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberDelReq.java
@@ -0,0 +1,28 @@
+package com.abin.mallchat.custom.chat.domain.vo.request;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * Description: 移除群成员
+ * Author: abin
+ * Date: 2023-03-29
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberDelReq {
+ @NotNull
+ @ApiModelProperty("会话id")
+ private Long roomId;
+
+ @NotNull
+ @ApiModelProperty("被移除的uid(主动退群填自己)")
+ private Long uid;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberReq.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberReq.java
new file mode 100644
index 0000000..ce41b7c
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/request/MemberReq.java
@@ -0,0 +1,25 @@
+package com.abin.mallchat.custom.chat.domain.vo.request;
+
+import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-17
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberReq extends CursorPageBaseReq {
+ @ApiModelProperty("房间号")
+ @NotNull
+ private Long roomId;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadInfoResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadInfoResp.java
new file mode 100644
index 0000000..dd6cb71
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadInfoResp.java
@@ -0,0 +1,28 @@
+package com.abin.mallchat.custom.chat.domain.vo.response;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-17
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ChatMessageReadInfoResp {
+ @ApiModelProperty("消息id")
+ private Long msgId;
+
+ @ApiModelProperty("已读数")
+ private Integer readCount;
+
+ @ApiModelProperty("未读数")
+ private Integer unReadCount;
+
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadResp.java
new file mode 100644
index 0000000..4b187c8
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatMessageReadResp.java
@@ -0,0 +1,21 @@
+package com.abin.mallchat.custom.chat.domain.vo.response;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-03-23
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class ChatMessageReadResp {
+ @ApiModelProperty("已读或者未读的用户uid")
+ private Long uid;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatRoomResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatRoomResp.java
index b7f22b7..9913bf8 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatRoomResp.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/ChatRoomResp.java
@@ -18,12 +18,20 @@ import java.util.Date;
@AllArgsConstructor
@NoArgsConstructor
public class ChatRoomResp {
- @ApiModelProperty("会话id")
- private Long id;
+ @ApiModelProperty("房间id")
+ private Long roomId;
+ @ApiModelProperty("房间类型 1群聊 2单聊")
+ private Integer type;
+ @ApiModelProperty("是否全员展示的会话 0否 1是")
+ private Integer hot_Flag;
+ @ApiModelProperty("最新消息")
+ private String text;
@ApiModelProperty("会话名称")
private String name;
- @ApiModelProperty("会话类型 1大群聊 2沸点")
- private Integer type;
- @ApiModelProperty("房间最后活跃时间")
+ @ApiModelProperty("会话头像")
+ private String avatar;
+ @ApiModelProperty("房间最后活跃时间(用来排序)")
private Date lastActiveTime;
+ @ApiModelProperty("未读数")
+ private Integer unreadCount;
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/MemberResp.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/MemberResp.java
new file mode 100644
index 0000000..0bc8c79
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/domain/vo/response/MemberResp.java
@@ -0,0 +1,29 @@
+package com.abin.mallchat.custom.chat.domain.vo.response;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-17
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class MemberResp {
+ @ApiModelProperty("群id")
+ private Long id;
+ @ApiModelProperty("群名称")
+ private Long groupName;
+ @ApiModelProperty("在线人数")
+ private Long onlineNum;//在线人数
+ @ApiModelProperty("群聊描述")
+ private String desc;//在线人数
+ @ApiModelProperty("成员角色 1群主 2管理员 3普通成员 4踢出群聊")
+ private Integer role;//在线人数
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/ChatService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/ChatService.java
index 43e00cc..48c083f 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/ChatService.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/ChatService.java
@@ -1,5 +1,6 @@
package com.abin.mallchat.custom.chat.service;
+import com.abin.mallchat.common.chat.domain.dto.MsgReadInfoDTO;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
@@ -7,6 +8,7 @@ import com.abin.mallchat.custom.chat.domain.vo.request.*;
import com.abin.mallchat.custom.chat.domain.vo.response.*;
import javax.annotation.Nullable;
+import java.util.Collection;
import java.util.List;
/**
@@ -73,4 +75,8 @@ public interface ChatService {
void recallMsg(Long uid, ChatMessageBaseReq request);
List getMemberList(ChatMessageMemberReq chatMessageMemberReq);
+
+ Collection getMsgReadInfo(Long uid, ChatMessageReadInfoReq request);
+
+ CursorPageBaseResp getReadPage(Long uid, ChatMessageReadReq request);
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/RoomService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/RoomService.java
new file mode 100644
index 0000000..0266882
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/RoomService.java
@@ -0,0 +1,17 @@
+package com.abin.mallchat.custom.chat.service;
+
+import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
+import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-22
+ */
+public interface RoomService {
+ /**
+ * 获取会话列表--支持未登录态
+ */
+ CursorPageBaseResp getContactPage(CursorPageBaseReq request, Long uid);
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java
index b1bdf8d..5fa2a71 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/MessageAdapter.java
@@ -5,20 +5,16 @@ import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
import com.abin.mallchat.common.chat.domain.enums.MessageMarkTypeEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageStatusEnum;
+import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
import com.abin.mallchat.common.common.domain.enums.YesOrNoEnum;
import com.abin.mallchat.common.user.domain.entity.UserApply;
import com.abin.mallchat.custom.chat.domain.vo.request.ChatMessageReq;
+import com.abin.mallchat.custom.chat.domain.vo.request.msg.TextMsgReq;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
import com.abin.mallchat.custom.chat.service.strategy.msg.AbstractMsgHandler;
import com.abin.mallchat.custom.chat.service.strategy.msg.MsgHandlerFactory;
-import com.abin.mallchat.custom.user.domain.vo.response.ws.WSApplyMessage;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
import java.util.stream.Collectors;
/**
@@ -99,4 +95,13 @@ public class MessageAdapter {
}
+ public static ChatMessageReq buildAgreeMsg(Long roomId) {
+ ChatMessageReq chatMessageReq = new ChatMessageReq();
+ chatMessageReq.setRoomId(roomId);
+ chatMessageReq.setMsgType(MessageTypeEnum.TEXT.getType());
+ TextMsgReq textMsgReq = new TextMsgReq();
+ textMsgReq.setContent("我们已经成为好友了,开始聊天吧");
+ chatMessageReq.setBody(textMsgReq);
+ return chatMessageReq;
+ }
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/RoomAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/RoomAdapter.java
index 58a69c4..360883d 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/RoomAdapter.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/adapter/RoomAdapter.java
@@ -1,7 +1,9 @@
package com.abin.mallchat.custom.chat.service.adapter;
import cn.hutool.core.bean.BeanUtil;
+import com.abin.mallchat.common.chat.domain.entity.Contact;
import com.abin.mallchat.common.chat.domain.entity.Room;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageReadResp;
import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp;
import java.util.List;
@@ -24,4 +26,12 @@ public class RoomAdapter {
return resp;
}).collect(Collectors.toList());
}
+
+ public static List buildReadResp(List list) {
+ return list.stream().map(contact -> {
+ ChatMessageReadResp resp = new ChatMessageReadResp();
+ resp.setUid(contact.getUid());
+ return resp;
+ }).collect(Collectors.toList());
+ }
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java
index 03ab62f..cb9539b 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/ChatServiceImpl.java
@@ -5,14 +5,18 @@ import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Pair;
+import com.abin.mallchat.common.chat.dao.ContactDao;
import com.abin.mallchat.common.chat.dao.MessageDao;
import com.abin.mallchat.common.chat.dao.MessageMarkDao;
import com.abin.mallchat.common.chat.dao.RoomDao;
+import com.abin.mallchat.common.chat.domain.dto.MsgReadInfoDTO;
+import com.abin.mallchat.common.chat.domain.entity.Contact;
import com.abin.mallchat.common.chat.domain.entity.Message;
import com.abin.mallchat.common.chat.domain.entity.MessageMark;
import com.abin.mallchat.common.chat.domain.entity.Room;
import com.abin.mallchat.common.chat.domain.enums.MessageMarkActTypeEnum;
import com.abin.mallchat.common.chat.domain.enums.MessageTypeEnum;
+import com.abin.mallchat.common.chat.service.ContactService;
import com.abin.mallchat.common.common.annotation.RedissonLock;
import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
@@ -44,6 +48,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import javax.annotation.Nullable;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -77,6 +82,10 @@ public class ChatServiceImpl implements ChatService {
private IRoleService iRoleService;
@Autowired
private RecallMsgHandler recallMsgHandler;
+ @Autowired
+ private ContactService contactService;
+ @Autowired
+ private ContactDao contactDao;
/**
* 发送消息
@@ -205,6 +214,32 @@ public class ChatServiceImpl implements ChatService {
return null;
}
+ @Override
+ public Collection getMsgReadInfo(Long uid, ChatMessageReadInfoReq request) {
+ List messages = messageDao.listByIds(request.getMsgIds());
+ messages.forEach(message -> {
+ AssertUtil.equal(uid, message.getFromUid(), "只能查询自己发送的消息");
+ });
+ return contactService.getMsgReadInfo(messages).values();
+ }
+
+ @Override
+ public CursorPageBaseResp getReadPage(@Nullable Long uid, ChatMessageReadReq request) {
+ Message message = messageDao.getById(request.getMsgId());
+ AssertUtil.isNotEmpty(message, "消息id有误");
+ AssertUtil.equal(uid, message.getFromUid(), "只能查看自己的消息");
+ CursorPageBaseResp page;
+ if (request.getSearchType() == 1) {//已读
+ page = contactDao.getReadPage(message, request);
+ } else {
+ page = contactDao.getUnReadPage(message, request);
+ }
+ if (CollectionUtil.isEmpty(page.getList())) {
+ return CursorPageBaseResp.empty();
+ }
+ return CursorPageBaseResp.init(page, RoomAdapter.buildReadResp(page.getList()));
+ }
+
private void checkRecall(Long uid, Message message) {
AssertUtil.isNotEmpty(message, "消息有误");
AssertUtil.notEqual(message.getType(), MessageTypeEnum.RECALL, "消息无法撤回");
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/RoomServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/RoomServiceImpl.java
new file mode 100644
index 0000000..001ef38
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/impl/RoomServiceImpl.java
@@ -0,0 +1,114 @@
+package com.abin.mallchat.custom.chat.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import com.abin.mallchat.common.chat.dao.ContactDao;
+import com.abin.mallchat.common.chat.dao.MessageDao;
+import com.abin.mallchat.common.chat.domain.dto.RoomBaseInfo;
+import com.abin.mallchat.common.chat.domain.entity.*;
+import com.abin.mallchat.common.chat.domain.enums.RoomTypeEnum;
+import com.abin.mallchat.common.chat.service.adapter.ChatAdapter;
+import com.abin.mallchat.common.chat.service.cache.RoomCache;
+import com.abin.mallchat.common.chat.service.cache.RoomFriendCache;
+import com.abin.mallchat.common.chat.service.cache.RoomGroupCache;
+import com.abin.mallchat.common.common.domain.vo.request.CursorPageBaseReq;
+import com.abin.mallchat.common.common.domain.vo.response.CursorPageBaseResp;
+import com.abin.mallchat.common.user.domain.entity.User;
+import com.abin.mallchat.common.user.service.cache.UserInfoCache;
+import com.abin.mallchat.custom.chat.domain.vo.response.ChatRoomResp;
+import com.abin.mallchat.custom.chat.service.RoomService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-22
+ */
+@Service
+public class RoomServiceImpl implements RoomService {
+
+ @Autowired
+ private ContactDao contactDao;
+ @Autowired
+ private RoomCache roomCache;
+ @Autowired
+ private RoomGroupCache roomGroupCache;
+ @Autowired
+ private RoomFriendCache roomFriendCache;
+ @Autowired
+ private UserInfoCache userInfoCache;
+ @Autowired
+ private MessageDao messageDao;
+
+ @Override
+ public CursorPageBaseResp getContactPage(CursorPageBaseReq request, Long uid) {
+
+ if (Objects.nonNull(uid)) {
+ CursorPageBaseResp contactPage = contactDao.getContactPage(uid, request);
+ List roomIds = contactPage.getList().stream().map(Contact::getRoomId).collect(Collectors.toList());
+ //表情和头像
+ Map roomBaseInfoMap = getRoomBaseInfoMap(roomIds, uid);
+ //最后一条消息
+ List msgIds = contactPage.getList().stream().map(Contact::getLastMsgId).collect(Collectors.toList());
+ List messages = messageDao.listByIds(msgIds);
+ Map msgMap = messages.stream().collect(Collectors.toMap(Message::getId, Function.identity()));
+ List collect = contactPage.getList().stream().map(contact -> {
+ ChatRoomResp resp = new ChatRoomResp();
+ BeanUtil.copyProperties(contact, resp);
+ RoomBaseInfo roomBaseInfo = roomBaseInfoMap.get(contact.getRoomId());
+ resp.setAvatar(roomBaseInfo.getAvatar());
+ resp.setName(roomBaseInfo.getName());
+ Message message = msgMap.get(contact.getLastMsgId());
+ if (Objects.nonNull(message)) {
+ resp.setText();
+ }
+ return resp;
+ }).collect(Collectors.toList());
+ CursorPageBaseResp.init(contactPage, collect);
+ }
+ return null;
+ }
+
+ private Map getFriendRoomMap(List roomIds, Long uid) {
+ Map roomFriendMap = roomFriendCache.getBatch(roomIds);
+ Set friendUidSet = ChatAdapter.getFriendUidSet(roomFriendMap.values(), uid);
+ Map userBatch = userInfoCache.getBatch(new ArrayList<>(friendUidSet));
+ return roomFriendMap.values()
+ .stream()
+ .collect(Collectors.toMap(RoomFriend::getRoomId, roomFriend -> {
+ Long friendUid = ChatAdapter.getFriendUid(roomFriend, uid);
+ return userBatch.get(friendUid);
+ }));
+ }
+
+ private Map getRoomBaseInfoMap(List roomIds, Long uid) {
+ Map roomMap = roomCache.getBatch(roomIds);
+ Map> groupRoomIdMap = roomMap.values().stream().collect(Collectors.groupingBy(Room::getType,
+ Collectors.mapping(Room::getId, Collectors.toList())));
+ //获取群组信息
+ List groupRoomId = groupRoomIdMap.get(RoomTypeEnum.GROUP.getType());
+ Map roomInfoBatch = roomGroupCache.getBatch(groupRoomId);
+ //获取好友信息
+ List friendRoomId = groupRoomIdMap.get(RoomTypeEnum.FRIEND.getType());
+ Map friendRoomMap = getFriendRoomMap(friendRoomId, uid);
+ return roomMap.values().stream().map(room -> {
+ RoomBaseInfo roomBaseInfo = new RoomBaseInfo();
+ roomBaseInfo.setRoomId(room.getId());
+ if (RoomTypeEnum.of(room.getType()) == RoomTypeEnum.GROUP) {
+ RoomGroup roomGroup = roomInfoBatch.get(room.getId());
+ roomBaseInfo.setName(roomGroup.getName());
+ roomBaseInfo.setAvatar(roomGroup.getAvatar());
+ } else if (RoomTypeEnum.of(room.getType()) == RoomTypeEnum.FRIEND) {
+ User user = friendRoomMap.get(room.getId());
+ roomBaseInfo.setName(user.getName());
+ roomBaseInfo.setAvatar(user.getAvatar());
+ }
+ return roomBaseInfo;
+ }).collect(Collectors.toMap(RoomBaseInfo::getRoomId, Function.identity()));
+ }
+
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/AbstractMsgHandler.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/AbstractMsgHandler.java
index 1715937..6ea052b 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/AbstractMsgHandler.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/chat/service/strategy/msg/AbstractMsgHandler.java
@@ -18,14 +18,29 @@ public abstract class AbstractMsgHandler {
MsgHandlerFactory.register(getMsgTypeEnum().getType(), this);
}
+ /**
+ * 消息类型
+ */
abstract MessageTypeEnum getMsgTypeEnum();
+ /**
+ * 校验消息——保存前校验
+ */
public abstract void checkMsg(ChatMessageReq req, Long uid);
+ /**
+ * 保存消息
+ */
public abstract void saveMsg(Message msg, ChatMessageReq req);
+ /**
+ * 展示消息
+ */
public abstract Object showMsg(Message msg);
+ /**
+ * 被回复时——展示的消息
+ */
public abstract Object showReplyMsg(Message msg);
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/UserApplyListener.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/UserApplyListener.java
new file mode 100644
index 0000000..a95cd23
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/common/event/listener/UserApplyListener.java
@@ -0,0 +1,36 @@
+package com.abin.mallchat.custom.common.event.listener;
+
+import com.abin.mallchat.common.common.event.UserApplyEvent;
+import com.abin.mallchat.common.user.dao.UserApplyDao;
+import com.abin.mallchat.common.user.domain.entity.UserApply;
+import com.abin.mallchat.custom.user.domain.vo.response.ws.WSFriendApply;
+import com.abin.mallchat.custom.user.service.WebSocketService;
+import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.event.TransactionalEventListener;
+
+/**
+ * 好友申请监听器
+ *
+ * @author zhongzb create on 2022/08/26
+ */
+@Slf4j
+@Component
+public class UserApplyListener {
+ @Autowired
+ private UserApplyDao userApplyDao;
+ @Autowired
+ private WebSocketService webSocketService;
+
+ @Async
+ @TransactionalEventListener(classes = UserApplyEvent.class, fallbackExecution = true)
+ public void notifyFriend(UserApplyEvent event) {
+ UserApply userApply = event.getUserApply();
+ Integer unReadCount = userApplyDao.getUnReadCount(userApply.getTargetId());
+ webSocketService.sendToFriend(WSAdapter.buildApplySend(new WSFriendApply(userApply.getUid(), unReadCount)), userApply.getTargetId());
+ }
+
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/FriendController.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/FriendController.java
index f3ae8fe..e94288d 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/FriendController.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/controller/FriendController.java
@@ -88,7 +88,7 @@ public class FriendController {
@PutMapping("/apply")
@ApiOperation("申请审批")
public ApiResult applyApprove(@Valid @RequestBody FriendApproveReq request) {
- friendService.applyApprove(request);
+ friendService.applyApprove(RequestHolder.get().getUid(), request);
return ApiResult.success();
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/WSRespTypeEnum.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/WSRespTypeEnum.java
index e8ab2fe..a201691 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/WSRespTypeEnum.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/enums/WSRespTypeEnum.java
@@ -26,7 +26,9 @@ public enum WSRespTypeEnum {
BLACK(7, "拉黑用户", WSBlack.class),
MARK(8, "消息标记", WSMsgMark.class),
RECALL(9, "消息撤回", WSMsgRecall.class),
- APPLY(10,"好友申请", WSApplyMessage.class),
+ APPLY(10, "好友申请", WSFriendApply.class),
+ MEMBER_CHANGE(11, "成员变动", WSMemberChange.class),
+ MESSAGE_READ(12, "消息已读数", WSMessageRead.class),
;
private final Integer type;
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSApplyMessage.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSApplyMessage.java
deleted file mode 100644
index 192d33f..0000000
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSApplyMessage.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.abin.mallchat.custom.user.domain.vo.response.ws;
-
-import com.abin.mallchat.custom.chat.domain.vo.response.ChatMessageResp;
-import lombok.AllArgsConstructor;
-
-/**
- * @author : limeng
- * @description : 好友申请消息推送
- * @date : 2023/07/21
- */
-@AllArgsConstructor
-public class WSApplyMessage extends ChatMessageResp {
-
-}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSFriendApply.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSFriendApply.java
new file mode 100644
index 0000000..07cb8b4
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSFriendApply.java
@@ -0,0 +1,23 @@
+package com.abin.mallchat.custom.user.domain.vo.response.ws;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-03-19
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class WSFriendApply {
+ @ApiModelProperty("申请人")
+ private Long uid;
+ @ApiModelProperty("申请未读数")
+ private Integer unreadCount;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMemberChange.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMemberChange.java
new file mode 100644
index 0000000..d6f291c
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMemberChange.java
@@ -0,0 +1,34 @@
+package com.abin.mallchat.custom.user.domain.vo.response.ws;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-03-19
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class WSMemberChange {
+ @ApiModelProperty("群组id")
+ private Long roomId;
+ @ApiModelProperty("变动人")
+ private Long uid;
+ @ApiModelProperty("变动类型 1加入群组 2移除群组")
+ private Integer changeType;
+ /**
+ * @see com.abin.mallchat.common.user.domain.enums.ChatActiveStatusEnum
+ */
+ @ApiModelProperty("在线状态 1在线 2离线")
+ private Integer activeStatus;
+ @ApiModelProperty("最后一次上下线时间")
+ private Date lastOptTime;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMessageRead.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMessageRead.java
new file mode 100644
index 0000000..37e56d7
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSMessageRead.java
@@ -0,0 +1,23 @@
+package com.abin.mallchat.custom.user.domain.vo.response.ws;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-03-19
+ */
+@Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
+public class WSMessageRead {
+ @ApiModelProperty("消息")
+ private Long msgId;
+ @ApiModelProperty("阅读人数(可能为0)")
+ private Integer readCount;
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSOnlineOfflineNotify.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSOnlineOfflineNotify.java
index 9d9c82f..f0f077e 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSOnlineOfflineNotify.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/domain/vo/response/ws/WSOnlineOfflineNotify.java
@@ -21,7 +21,4 @@ import java.util.List;
public class WSOnlineOfflineNotify {
private List changeList = new ArrayList<>();//新的上下线用户
private Long onlineNum;//在线人数
- @Deprecated
- private Long totalNum;//总人数
-
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/FriendService.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/FriendService.java
index dc8b0b5..7502827 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/FriendService.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/FriendService.java
@@ -56,5 +56,5 @@ public interface FriendService {
* @param uid uid
* @param request 请求
*/
- void applyApprove(FriendApproveReq request);
+ void applyApprove(Long uid, FriendApproveReq request);
}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/FriendAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/FriendAdapter.java
new file mode 100644
index 0000000..6525007
--- /dev/null
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/FriendAdapter.java
@@ -0,0 +1,43 @@
+package com.abin.mallchat.custom.user.service.adapter;
+
+import com.abin.mallchat.common.user.domain.entity.UserApply;
+import com.abin.mallchat.custom.user.domain.vo.request.friend.FriendApplyReq;
+import com.abin.mallchat.custom.user.domain.vo.response.friend.FriendApplyResp;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static com.abin.mallchat.common.user.domain.enums.ApplyReadStatusEnum.UNREAD;
+import static com.abin.mallchat.common.user.domain.enums.ApplyStatusEnum.WAIT_APPROVAL;
+import static com.abin.mallchat.common.user.domain.enums.ApplyTypeEnum.ADD_FRIEND;
+
+/**
+ * Description: 好友适配器
+ * Author: abin
+ * Date: 2023-07-22
+ */
+public class FriendAdapter {
+
+
+ public static UserApply buildFriendApply(Long uid, FriendApplyReq request) {
+ UserApply userApplyNew = new UserApply();
+ userApplyNew.setUid(uid);
+ userApplyNew.setMsg(request.getMsg());
+ userApplyNew.setType(ADD_FRIEND.getCode());
+ userApplyNew.setTargetId(request.getTargetUid());
+ userApplyNew.setStatus(WAIT_APPROVAL.getCode());
+ userApplyNew.setReadStatus(UNREAD.getCode());
+ return userApplyNew;
+ }
+
+ public static List buildFriendApplyList(List records) {
+ return records.stream().map(userApply -> {
+ FriendApplyResp friendApplyResp = new FriendApplyResp();
+ friendApplyResp.setUid(userApply.getUid());
+ friendApplyResp.setType(userApply.getType());
+ friendApplyResp.setMsg(userApply.getMsg());
+ friendApplyResp.setStatus(userApply.getStatus());
+ return friendApplyResp;
+ }).collect(Collectors.toList());
+ }
+}
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/WSAdapter.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/WSAdapter.java
index 7739026..4956491 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/WSAdapter.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/adapter/WSAdapter.java
@@ -133,8 +133,8 @@ public class WSAdapter {
return wsBaseResp;
}
- public static WSBaseResp buildApplySend(WSApplyMessage resp) {
- WSBaseResp wsBaseResp = new WSBaseResp<>();
+ public static WSBaseResp buildApplySend(WSFriendApply resp) {
+ WSBaseResp wsBaseResp = new WSBaseResp<>();
wsBaseResp.setType(WSRespTypeEnum.APPLY.getType());
wsBaseResp.setData(resp);
return wsBaseResp;
diff --git a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/FriendServiceImpl.java b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/FriendServiceImpl.java
index 5c5343b..bc16a2e 100644
--- a/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/FriendServiceImpl.java
+++ b/mallchat-custom-server/src/main/java/com/abin/mallchat/custom/user/service/impl/FriendServiceImpl.java
@@ -1,11 +1,20 @@
package com.abin.mallchat.custom.user.service.impl;
+import cn.hutool.core.collection.CollectionUtil;
+import com.abin.mallchat.common.chat.dao.RoomFriendDao;
+import com.abin.mallchat.common.chat.domain.entity.RoomFriend;
+import com.abin.mallchat.common.chat.service.ContactService;
+import com.abin.mallchat.common.chat.service.RoomService;
+import com.abin.mallchat.common.common.annotation.RedissonLock;
import com.abin.mallchat.common.common.domain.vo.request.PageBaseReq;
import com.abin.mallchat.common.common.domain.vo.response.PageBaseResp;
+import com.abin.mallchat.common.common.event.UserApplyEvent;
+import com.abin.mallchat.common.common.utils.AssertUtil;
+import com.abin.mallchat.common.user.dao.UserApplyDao;
+import com.abin.mallchat.common.user.dao.UserFriendDao;
import com.abin.mallchat.common.user.domain.entity.UserApply;
import com.abin.mallchat.common.user.domain.entity.UserFriend;
-import com.abin.mallchat.common.user.service.IUserApplyService;
-import com.abin.mallchat.common.user.service.IUserFriendService;
+import com.abin.mallchat.custom.chat.service.ChatService;
import com.abin.mallchat.custom.chat.service.adapter.MessageAdapter;
import com.abin.mallchat.custom.user.domain.vo.request.friend.FriendApplyReq;
import com.abin.mallchat.custom.user.domain.vo.request.friend.FriendApproveReq;
@@ -13,27 +22,24 @@ import com.abin.mallchat.custom.user.domain.vo.request.friend.FriendCheckReq;
import com.abin.mallchat.custom.user.domain.vo.response.friend.FriendApplyResp;
import com.abin.mallchat.custom.user.domain.vo.response.friend.FriendCheckResp;
import com.abin.mallchat.custom.user.domain.vo.response.friend.FriendUnreadResp;
-import com.abin.mallchat.custom.user.domain.vo.response.ws.WSApplyMessage;
import com.abin.mallchat.custom.user.service.FriendService;
import com.abin.mallchat.custom.user.service.WebSocketService;
-import com.abin.mallchat.custom.user.service.adapter.WSAdapter;
-import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
-import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
+import com.abin.mallchat.custom.user.service.adapter.FriendAdapter;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
-import javax.annotation.Resource;
+import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.stream.Collectors;
-import static com.abin.mallchat.common.user.domain.enums.ApplyReadStatusEnum.UNREAD;
import static com.abin.mallchat.common.user.domain.enums.ApplyStatusEnum.AGREE;
-import static com.abin.mallchat.common.user.domain.enums.ApplyStatusEnum.WAIT_APPROVAL;
-import static com.abin.mallchat.common.user.domain.enums.ApplyTypeEnum.ADD_FRIEND;
/**
* @author : limeng
@@ -44,15 +50,24 @@ import static com.abin.mallchat.common.user.domain.enums.ApplyTypeEnum.ADD_FRIEN
@Service
public class FriendServiceImpl implements FriendService {
- @Resource
- private IUserFriendService friendService;
-
- @Resource
- private IUserApplyService applyService;
-
- @Resource
+ @Autowired
private WebSocketService webSocketService;
+ @Autowired
+ private UserFriendDao userFriendDao;
+ @Autowired
+ private UserApplyDao userApplyDao;
+ @Autowired
+ private ApplicationEventPublisher applicationEventPublisher;
+ @Autowired
+ private RoomFriendDao roomFriendDao;
+ @Autowired
+ private RoomService roomService;
+ @Autowired
+ private ContactService contactService;
+ @Autowired
+ private ChatService chatService;
+
/**
* 检查
* 检查是否是自己好友
@@ -63,15 +78,13 @@ public class FriendServiceImpl implements FriendService {
*/
@Override
public FriendCheckResp check(Long uid, FriendCheckReq request) {
- LambdaQueryChainWrapper wrapper = friendService.lambdaQuery();
- wrapper.eq(UserFriend::getUid, uid)
- .in(UserFriend::getFriendUid, request.getUidList());
- List friendList = friendService.list(wrapper);
- Map friendMap = friendList.stream().collect(Collectors.toMap(UserFriend::getFriendUid, friend -> friend));
+ List friendList = userFriendDao.getByFriends(uid, request.getUidList());
+
+ Set friendUidSet = friendList.stream().map(UserFriend::getFriendUid).collect(Collectors.toSet());
List friendCheckList = request.getUidList().stream().map(friendUid -> {
FriendCheckResp.FriendCheck friendCheck = new FriendCheckResp.FriendCheck();
friendCheck.setUid(friendUid);
- friendCheck.setIsFriend(friendMap.containsKey(friendUid));
+ friendCheck.setIsFriend(friendUidSet.contains(friendUid));
return friendCheck;
}).collect(Collectors.toList());
return new FriendCheckResp(friendCheckList);
@@ -84,25 +97,20 @@ public class FriendServiceImpl implements FriendService {
*/
@Override
public void apply(Long uid, FriendApplyReq request) {
- LambdaQueryChainWrapper wrapper = applyService.lambdaQuery();
- wrapper.eq(UserApply::getUid, uid)
- .eq(UserApply::getTargetId, request.getTargetUid());
- UserApply userApply = applyService.getOne(wrapper);
- if (Objects.nonNull(userApply)) {
+ //是否有好友关系
+ UserFriend friend = userFriendDao.getByFriend(uid, request.getTargetUid());
+ AssertUtil.isEmpty(friend, "你们已经是好友了");
+ //是否有待审批的申请记录
+ UserApply friendApproving = userApplyDao.getFriendApproving(uid, request.getTargetUid());
+ if (Objects.nonNull(friendApproving)) {
log.info("已有好友申请记录,uid:{}, targetId:{}", uid, request.getTargetUid());
return;
}
- UserApply userApplyNew = new UserApply();
- userApplyNew.setUid(uid);
- userApplyNew.setMsg(request.getMsg());
- userApplyNew.setType(ADD_FRIEND.getCode());
- userApplyNew.setTargetId(request.getTargetUid());
- userApplyNew.setStatus(WAIT_APPROVAL.getCode());
- userApplyNew.setReadStatus(UNREAD.getCode());
- applyService.save(userApplyNew);
-
- WSApplyMessage applyMessage = MessageAdapter.buildApplyResp(userApplyNew);
- webSocketService.sendToFriend(WSAdapter.buildApplySend(applyMessage), request.getTargetUid());
+ //申请入库
+ UserApply insert = FriendAdapter.buildFriendApply(uid, request);
+ userApplyDao.save(insert);
+ //申请事件
+ applicationEventPublisher.publishEvent(new UserApplyEvent(this, insert));
}
/**
@@ -113,23 +121,15 @@ public class FriendServiceImpl implements FriendService {
*/
@Override
public PageBaseResp pageApplyFriend(Long uid, PageBaseReq request) {
- // todo 分页
- LambdaQueryChainWrapper wrapper = applyService.lambdaQuery();
- wrapper.eq(UserApply::getUid, uid)
- .or()
- .eq(UserApply::getTargetId, uid);
- List userApplyList = applyService.list(wrapper);
- List friendApplyResps = userApplyList.stream().map(userApply -> {
- FriendApplyResp friendApplyResp = new FriendApplyResp();
- friendApplyResp.setUid(userApply.getUid());
- friendApplyResp.setType(userApply.getType());
- friendApplyResp.setMsg(userApply.getMsg());
- friendApplyResp.setStatus(userApply.getStatus());
- return friendApplyResp;
- }).collect(Collectors.toList());
- PageBaseResp pageBaseResp = new PageBaseResp<>();
- pageBaseResp.setList(friendApplyResps);
- return pageBaseResp;
+ IPage userApplyIPage = userApplyDao.FriendApplyPage(uid, request.plusPage());
+ if (CollectionUtil.isEmpty(userApplyIPage.getRecords())) {
+ return PageBaseResp.empty();
+ }
+ //将这些申请列表设为已读
+ List applyIds = userApplyIPage.getRecords().stream().map(UserApply::getId).collect(Collectors.toList());
+ userApplyDao.readApples(uid, applyIds);
+ //返回消息
+ return PageBaseResp.init(userApplyIPage, FriendAdapter.buildFriendApplyList(userApplyIPage.getRecords()));
}
/**
@@ -139,34 +139,38 @@ public class FriendServiceImpl implements FriendService {
*/
@Override
public FriendUnreadResp unread(Long uid) {
- LambdaQueryChainWrapper wrapper = applyService.lambdaQuery();
- wrapper.eq(UserApply::getTargetId, uid)
- .eq(UserApply::getReadStatus, UNREAD.getCode());
- return new FriendUnreadResp(applyService.count(wrapper));
+ Integer unReadCount = userApplyDao.getUnReadCount(uid);
+ return new FriendUnreadResp(unReadCount);
}
@Override
@Transactional
- public void applyApprove(FriendApproveReq request) {
- UserApply userApply = applyService.getById(request.getApplyId());
- if (Objects.isNull(userApply)) {
- log.error("不存在申请记录:{}", request.getApplyId());
- return;
- }
- if (Objects.equals(userApply.getStatus(), AGREE.getCode())) {
- log.error("已同意好友申请:{}", request.getApplyId());
- return;
- }
- LambdaUpdateChainWrapper updateWrapper = applyService.lambdaUpdate();
- updateWrapper.set(UserApply::getStatus, AGREE.getCode())
- .eq(UserApply::getId, request.getApplyId());
- applyService.update(updateWrapper);
+ @RedissonLock(key = "#uid")
+ public void applyApprove(Long uid, FriendApproveReq request) {
+ UserApply userApply = userApplyDao.getById(request.getApplyId());
+ AssertUtil.isNotEmpty(userApply, "不存在申请记录");
+ AssertUtil.equal(userApply.getTargetId(), uid, "不存在申请记录");
+ AssertUtil.equal(userApply.getStatus(), AGREE.getCode(), "已同意好友申请");
+ //同意申请
+ userApplyDao.agree(request.getApplyId());
+ //创建双方好友关系
+ createFriend(uid, userApply.getUid());
+ //创建一个聊天房间
+ RoomFriend roomFriend = roomService.createFriendRoom(Arrays.asList(uid, userApply.getUid()));
+ //创建双方的会话
+ contactService.createContact(uid, roomFriend.getRoomId());
+ contactService.createContact(userApply.getUid(), roomFriend.getRoomId());
+ //发送一条同意消息。。我们已经是好友了,开始聊天吧
+ chatService.sendMsg(MessageAdapter.buildAgreeMsg(roomFriend.getRoomId()), uid);
+ }
+
+ private void createFriend(Long uid, Long targetUid) {
UserFriend userFriend1 = new UserFriend();
- userFriend1.setUid(userApply.getUid());
- userFriend1.setFriendUid(userApply.getTargetId());
+ userFriend1.setUid(uid);
+ userFriend1.setFriendUid(targetUid);
UserFriend userFriend2 = new UserFriend();
- userFriend2.setUid(userApply.getTargetId());
- userFriend2.setFriendUid(userApply.getUid());
- friendService.saveBatch(Lists.newArrayList(userFriend1, userFriend2));
+ userFriend2.setUid(targetUid);
+ userFriend2.setFriendUid(uid);
+ userFriendDao.saveBatch(Lists.newArrayList(userFriend1, userFriend2))
}
}
diff --git a/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/common/CommonTest.java b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/common/CommonTest.java
new file mode 100644
index 0000000..96fb649
--- /dev/null
+++ b/mallchat-custom-server/src/test/java/com/abin/mallchat/custom/common/CommonTest.java
@@ -0,0 +1,18 @@
+package com.abin.mallchat.custom.common;
+
+import org.junit.Test;
+
+import static com.abin.mallchat.custom.user.service.adapter.FriendAdapter.buildFriendRoomKey;
+
+/**
+ * Description:
+ * Author: abin
+ * Date: 2023-07-22
+ */
+public class CommonTest {
+ @Test
+ public void test() {
+ System.out.println(buildFriendRoomKey(100L, 102L));
+ }
+
+}