From 59cd0049e2c4cdb5cf78fa977d0fc83a7e89b7c3 Mon Sep 17 00:00:00 2001 From: GoCo Date: Mon, 22 Sep 2025 08:44:15 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E5=9C=A8=E7=BA=BF?= =?UTF-8?q?=E4=BA=A4=E6=B5=81=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiol/controller/AiolChatController.java | 528 ++++++++++++++++-- .../aiol/dto/ChatWithUnreadCountDTO.java | 21 + .../modules/aiol/entity/AiolChatMember.java | 2 +- 3 files changed, 517 insertions(+), 34 deletions(-) create mode 100644 jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/ChatWithUnreadCountDTO.java diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatController.java index 4199302f..c92d743a 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatController.java @@ -24,10 +24,13 @@ import org.jeecg.modules.aiol.entity.AiolChatMember; import org.jeecg.modules.aiol.entity.AiolChatMessage; import org.jeecg.modules.aiol.entity.AiolClass; import org.jeecg.modules.aiol.entity.AiolClassStudent; +import org.jeecg.modules.aiol.dto.ChatWithUnreadCountDTO; import org.jeecg.modules.aiol.mapper.AiolChatMemberMapper; import org.jeecg.modules.aiol.mapper.AiolChatMessageMapper; import org.jeecg.modules.aiol.mapper.AiolClassMapper; import org.jeecg.modules.aiol.mapper.AiolClassStudentMapper; +import org.jeecg.modules.system.mapper.SysUserRoleMapper; +import org.jeecg.modules.aiol.constant.RoleConst; import org.jeecg.modules.aiol.service.IAiolChatService; import org.jeecg.modules.system.entity.SysUser; import org.jeecg.modules.system.mapper.SysUserMapper; @@ -85,6 +88,9 @@ public class AiolChatController extends JeecgController> queryMyChatList(HttpServletRequest request) { + public Result> queryMyChatList(HttpServletRequest request) { try { // 1. 从token获取当前用户信息 String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); @@ -235,7 +241,7 @@ public class AiolChatController extends JeecgController memberWrapper = new QueryWrapper<>(); memberWrapper.eq("user_id", sysUser.getId()); List chatMembers = aiolChatMemberMapper.selectList(memberWrapper); @@ -256,37 +262,16 @@ public class AiolChatController extends JeecgController chatList = aiolChatService.list(chatWrapper); - // 5. 处理私聊类型的会话,获取对方用户信息 + // 5. 转换为包含未读消息数的DTO列表 + List resultList = new java.util.ArrayList<>(); + for (AiolChat chat : chatList) { - if (chat.getType() != null && chat.getType() == 0) { - // 私聊类型,需要获取对方用户信息 - try { - // 查询该会话的成员,排除当前用户 - QueryWrapper otherMemberWrapper = new QueryWrapper<>(); - otherMemberWrapper.eq("chat_id", chat.getId()) - .ne("user_id", sysUser.getId()); - List otherMembers = aiolChatMemberMapper.selectList(otherMemberWrapper); - - if (!otherMembers.isEmpty()) { - // 获取对方用户ID - String otherUserId = otherMembers.get(0).getUserId(); - - // 查询对方用户信息 - SysUser otherUser = sysUserMapper.selectById(otherUserId); - if (otherUser != null) { - // 替换会话的name和avatar为对方用户信息 - chat.setName(otherUser.getRealname()); - chat.setAvatar(otherUser.getAvatar()); - } - } - } catch (Exception e) { - log.warn("获取私聊对方用户信息失败: chatId={}, error={}", chat.getId(), e.getMessage()); - } - } + ChatWithUnreadCountDTO chatDTO = convertToChatWithUnreadCount(chat, chatMembers, sysUser.getId()); + resultList.add(chatDTO); } - log.info("用户 {} 查询到 {} 个会话", username, chatList.size()); - return Result.OK(chatList); + log.info("用户 {} 查询到 {} 个会话", username, resultList.size()); + return Result.OK(resultList); } catch (Exception e) { log.error("查询用户会话列表失败: {}", e.getMessage(), e); @@ -300,7 +285,7 @@ public class AiolChatController extends JeecgController>> queryChatMembers(@PathVariable(value = "chatId") String chatId) { try { @@ -321,7 +306,26 @@ public class AiolChatController extends JeecgController userList = sysUserMapper.selectByIds(userIds); - // 4. 构建返回结果 + // 4. 查询所有用户的教师角色身份 + Map teacherStatusMap = new java.util.HashMap<>(); + if (!userIds.isEmpty()) { + try { + QueryWrapper roleWrapper = new QueryWrapper<>(); + roleWrapper.eq("role_id", RoleConst.TEACHER_ROLE_ID) + .in("user_id", userIds); + + List teacherRoleList = sysUserRoleMapper.selectList(roleWrapper); + + // 构建教师身份映射 + for (org.jeecg.modules.system.entity.SysUserRole userRole : teacherRoleList) { + teacherStatusMap.put(userRole.getUserId(), true); + } + } catch (Exception e) { + log.warn("查询教师角色身份失败: error={}", e.getMessage()); + } + } + + // 5. 构建返回结果 List> result = new java.util.ArrayList<>(); for (SysUser user : userList) { Map memberInfo = new java.util.HashMap<>(); @@ -329,6 +333,10 @@ public class AiolChatController extends JeecgController muteAll(@PathVariable(value = "chatId") String chatId) { + try { + return updateChatSetting(chatId, "iz_all_muted", 1, "开启全员禁言"); + } catch (Exception e) { + log.error("开启全员禁言失败: chatId={}, error={}", chatId, e.getMessage(), e); + return Result.error("开启全员禁言失败: " + e.getMessage()); + } + } + + /** + * 关闭全员禁言 + * + * @param chatId 会话ID + * @return + */ + @AutoLog(value = "会话-关闭全员禁言") + @Operation(summary = "关闭全员禁言", description = "关闭群聊的全员禁言功能,设置iz_all_muted字段为0") + @PostMapping(value = "/{chatId}/unmute_all") + public Result unmuteAll(@PathVariable(value = "chatId") String chatId) { + try { + return updateChatSetting(chatId, "iz_all_muted", 0, "关闭全员禁言"); + } catch (Exception e) { + log.error("关闭全员禁言失败: chatId={}, error={}", chatId, e.getMessage(), e); + return Result.error("关闭全员禁言失败: " + e.getMessage()); + } + } + + /** + * 开启显示教师标签 + * + * @param chatId 会话ID + * @return + */ + @AutoLog(value = "会话-开启显示教师标签") + @Operation(summary = "开启显示教师标签", description = "开启群聊中显示教师标签功能,设置show_label字段为1") + @PostMapping(value = "/{chatId}/show_label") + public Result showLabel(@PathVariable(value = "chatId") String chatId) { + try { + return updateChatSetting(chatId, "show_label", 1, "开启显示教师标签"); + } catch (Exception e) { + log.error("开启显示教师标签失败: chatId={}, error={}", chatId, e.getMessage(), e); + return Result.error("开启显示教师标签失败: " + e.getMessage()); + } + } + + /** + * 关闭显示教师标签 + * + * @param chatId 会话ID + * @return + */ + @AutoLog(value = "会话-关闭显示教师标签") + @Operation(summary = "关闭显示教师标签", description = "关闭群聊中显示教师标签功能,设置show_label字段为0") + @PostMapping(value = "/{chatId}/hide_label") + public Result hideLabel(@PathVariable(value = "chatId") String chatId) { + try { + return updateChatSetting(chatId, "show_label", 0, "关闭显示教师标签"); + } catch (Exception e) { + log.error("关闭显示教师标签失败: chatId={}, error={}", chatId, e.getMessage(), e); + return Result.error("关闭显示教师标签失败: " + e.getMessage()); + } + } + + /** + * 通用更新会话设置的方法 + * + * @param chatId 会话ID + * @param fieldName 字段名 + * @param value 字段值 + * @param operationName 操作名称 + * @return + */ + private Result updateChatSetting(String chatId, String fieldName, Integer value, String operationName) { + // 1. 查询会话是否存在 + AiolChat chat = aiolChatService.getById(chatId); + if (chat == null) { + return Result.error("会话不存在"); + } + + // 2. 根据字段名设置相应的值 + if ("iz_all_muted".equals(fieldName)) { + chat.setIzAllMuted(value); + } else if ("show_label".equals(fieldName)) { + chat.setShowLabel(value); + } else { + return Result.error("无效的字段名"); + } + + // 3. 更新数据库 + boolean updated = aiolChatService.updateById(chat); + if (!updated) { + return Result.error(operationName + "失败"); + } + + log.info("{}成功: chatId={}, {}={}", operationName, chatId, fieldName, value); + return Result.OK(operationName + "成功!"); + } + + /** + * 禁言群聊成员 + * + * @param chatId 会话ID + * @param userId 用户ID + * @return + */ + @AutoLog(value = "会话-禁言群聊成员") + @Operation(summary = "禁言群聊成员", description = "禁言指定群聊成员,设置iz_muted字段为1") + @PostMapping(value = "/{chatId}/mute_member/{userId}") + public Result muteMember(@PathVariable(value = "chatId") String chatId, + @PathVariable(value = "userId") String userId) { + try { + return updateMemberSetting(chatId, userId, "iz_muted", 1, "禁言群聊成员"); + } catch (Exception e) { + log.error("禁言群聊成员失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e); + return Result.error("禁言群聊成员失败: " + e.getMessage()); + } + } + + /** + * 解除禁言群聊成员 + * + * @param chatId 会话ID + * @param userId 用户ID + * @return + */ + @AutoLog(value = "会话-解除禁言群聊成员") + @Operation(summary = "解除禁言群聊成员", description = "解除指定群聊成员的禁言状态,设置iz_muted字段为0") + @PostMapping(value = "/{chatId}/unmute_member/{userId}") + public Result unmuteMember(@PathVariable(value = "chatId") String chatId, + @PathVariable(value = "userId") String userId) { + try { + return updateMemberSetting(chatId, userId, "iz_muted", 0, "解除禁言群聊成员"); + } catch (Exception e) { + log.error("解除禁言群聊成员失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e); + return Result.error("解除禁言群聊成员失败: " + e.getMessage()); + } + } + + /** + * 开启免打扰 + * + * @param chatId 会话ID + * @param userId 用户ID + * @return + */ + @AutoLog(value = "会话-开启免打扰") + @Operation(summary = "开启免打扰", description = "为指定用户开启群聊免打扰功能,设置iz_not_disturb字段为1") + @PostMapping(value = "/{chatId}/enable_not_disturb/{userId}") + public Result enableNotDisturb(@PathVariable(value = "chatId") String chatId, + @PathVariable(value = "userId") String userId) { + try { + return updateMemberSetting(chatId, userId, "iz_not_disturb", 1, "开启免打扰"); + } catch (Exception e) { + log.error("开启免打扰失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e); + return Result.error("开启免打扰失败: " + e.getMessage()); + } + } + + /** + * 关闭免打扰 + * + * @param chatId 会话ID + * @param userId 用户ID + * @return + */ + @AutoLog(value = "会话-关闭免打扰") + @Operation(summary = "关闭免打扰", description = "为指定用户关闭群聊免打扰功能,设置iz_not_disturb字段为0") + @PostMapping(value = "/{chatId}/disable_not_disturb/{userId}") + public Result disableNotDisturb(@PathVariable(value = "chatId") String chatId, + @PathVariable(value = "userId") String userId) { + try { + return updateMemberSetting(chatId, userId, "iz_not_disturb", 0, "关闭免打扰"); + } catch (Exception e) { + log.error("关闭免打扰失败: chatId={}, userId={}, error={}", chatId, userId, e.getMessage(), e); + return Result.error("关闭免打扰失败: " + e.getMessage()); + } + } + + /** + * 通用更新群聊成员设置的方法 + * + * @param chatId 会话ID + * @param userId 用户ID + * @param fieldName 字段名 + * @param value 字段值 + * @param operationName 操作名称 + * @return + */ + private Result updateMemberSetting(String chatId, String userId, String fieldName, Integer value, String operationName) { + // 1. 查询群聊成员是否存在 + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.eq("chat_id", chatId).eq("user_id", userId); + AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper); + + if (chatMember == null) { + return Result.error("该用户不是群聊成员或会话不存在"); + } + + // 2. 根据字段名设置相应的值 + if ("iz_muted".equals(fieldName)) { + chatMember.setIzMuted(value); + } else if ("iz_not_disturb".equals(fieldName)) { + chatMember.setIzNotDisturb(value); + } else { + return Result.error("无效的字段名"); + } + + // 3. 更新数据库 + boolean updated = aiolChatMemberMapper.updateById(chatMember) > 0; + if (!updated) { + return Result.error(operationName + "失败"); + } + + log.info("{}成功: chatId={}, userId={}, {}={}", operationName, chatId, userId, fieldName, value); + return Result.OK(operationName + "成功!"); + } + + /** + * 将AiolChat转换为包含未读消息数的DTO + * @param chat 会话实体 + * @param chatMembers 会话成员列表 + * @param userId 当前用户ID + * @return 包含未读消息数的DTO + */ + private ChatWithUnreadCountDTO convertToChatWithUnreadCount(AiolChat chat, List chatMembers, String userId) { + ChatWithUnreadCountDTO chatDTO = new ChatWithUnreadCountDTO(); + + // 复制基本属性 + chatDTO.setId(chat.getId()); + chatDTO.setType(chat.getType()); + chatDTO.setName(chat.getName()); + chatDTO.setAvatar(chat.getAvatar()); + chatDTO.setRefId(chat.getRefId()); + chatDTO.setIzAllMuted(chat.getIzAllMuted()); + chatDTO.setShowLabel(chat.getShowLabel()); + chatDTO.setCreateBy(chat.getCreateBy()); + chatDTO.setCreateTime(chat.getCreateTime()); + chatDTO.setUpdateBy(chat.getUpdateBy()); + chatDTO.setUpdateTime(chat.getUpdateTime()); + + try { + // 1. 计算未读消息数 + AiolChatMember currentUserMember = chatMembers.stream() + .filter(member -> member.getChatId().equals(chat.getId()) && member.getUserId().equals(userId)) + .findFirst() + .orElse(null); + + int unreadCount = 0; + if (currentUserMember != null) { + String lastReadMsgId = currentUserMember.getLastReadMsgId(); + + // 查询该会话中last_read_msg_id之后的消息数量 + QueryWrapper messageWrapper = new QueryWrapper<>(); + messageWrapper.eq("chat_id", chat.getId()); + + if (lastReadMsgId != null && !lastReadMsgId.trim().isEmpty()) { + // 如果有最后读取的消息ID,查询该消息之后的消息 + QueryWrapper lastReadMsgWrapper = new QueryWrapper<>(); + lastReadMsgWrapper.eq("chat_id", chat.getId()).eq("id", lastReadMsgId); + AiolChatMessage lastReadMsg = aiolChatMessageMapper.selectOne(lastReadMsgWrapper); + + if (lastReadMsg != null) { + // 查询创建时间晚于最后读取消息的消息数量 + messageWrapper.gt("create_time", lastReadMsg.getCreateTime()); + } + } + + Long count = aiolChatMessageMapper.selectCount(messageWrapper); + unreadCount = count != null ? count.intValue() : 0; + } + + chatDTO.setUnreadCount(unreadCount); + + // 2. 处理私聊类型的会话,获取对方用户信息 + if (chat.getType() != null && chat.getType() == 0) { + // 私聊类型,需要获取对方用户信息 + try { + // 查询该会话的成员,排除当前用户 + QueryWrapper otherMemberWrapper = new QueryWrapper<>(); + otherMemberWrapper.eq("chat_id", chat.getId()) + .ne("user_id", userId); + List otherMembers = aiolChatMemberMapper.selectList(otherMemberWrapper); + + if (!otherMembers.isEmpty()) { + // 获取对方用户ID + String otherUserId = otherMembers.get(0).getUserId(); + + // 查询对方用户信息 + SysUser otherUser = sysUserMapper.selectById(otherUserId); + if (otherUser != null) { + // 替换会话的name和avatar为对方用户信息 + chatDTO.setName(otherUser.getRealname()); + chatDTO.setAvatar(otherUser.getAvatar()); + } + } + } catch (Exception e) { + log.warn("获取私聊对方用户信息失败: chatId={}, error={}", chat.getId(), e.getMessage()); + } + } + + } catch (Exception e) { + log.error("转换会话信息失败: chatId={}, error={}", chat.getId(), e.getMessage(), e); + // 即使转换失败,也返回基本的会话信息 + chatDTO.setUnreadCount(0); + } + + return chatDTO; + } + + /** + * 更新用户最后读取的消息ID + * + * @param chatId 会话ID + * @param messageId 消息ID + * @param request HTTP请求对象 + * @return + */ + @AutoLog(value = "会话-更新最后读取消息ID") + @Operation(summary = "更新最后读取消息ID", description = "更新当前用户在指定会话中的最后读取消息ID") + @PostMapping(value = "/{chatId}/update_last_read/{messageId}") + public Result updateLastReadMsgId(@PathVariable(value = "chatId") String chatId, + @PathVariable(value = "messageId") String messageId, + HttpServletRequest request) { + try { + // 1. 从token获取当前用户信息 + String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); + if (token == null || token.trim().isEmpty()) { + return Result.error("用户未登录"); + } + + String username = JwtUtil.getUsername(token); + LoginUser sysUser = sysBaseApi.getUserByName(username); + + if (sysUser == null) { + return Result.error("用户信息不存在"); + } + + // 2. 查询群聊成员是否存在 + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId()); + AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper); + + if (chatMember == null) { + return Result.error("该用户不是群聊成员或会话不存在"); + } + + // 3. 验证消息是否存在 + AiolChatMessage message = aiolChatMessageMapper.selectById(messageId); + if (message == null || !message.getChatId().equals(chatId)) { + return Result.error("消息不存在或不属于该会话"); + } + + // 4. 更新最后读取的消息ID + chatMember.setLastReadMsgId(messageId); + boolean updated = aiolChatMemberMapper.updateById(chatMember) > 0; + + if (!updated) { + return Result.error("更新失败"); + } + + log.info("用户 {} 更新会话 {} 的最后读取消息ID为 {}", username, chatId, messageId); + return Result.OK("更新成功!"); + + } catch (Exception e) { + log.error("更新最后读取消息ID失败: chatId={}, messageId={}, error={}", chatId, messageId, e.getMessage(), e); + return Result.error("更新失败: " + e.getMessage()); + } + } + + /** + * 退出群聊 + * + * @param chatId 会话ID + * @param request HTTP请求对象 + * @return + */ + @AutoLog(value = "会话-退出群聊") + @Operation(summary = "退出群聊", description = "当前用户退出指定的群聊会话,从aiol_chat_member表中删除用户记录") + @DeleteMapping(value = "/{chatId}/exit") + public Result exitChat(@PathVariable(value = "chatId") String chatId, + HttpServletRequest request) { + try { + // 1. 从token获取当前用户信息 + String token = request.getHeader(CommonConstant.X_ACCESS_TOKEN); + if (token == null || token.trim().isEmpty()) { + return Result.error("用户未登录"); + } + + String username = JwtUtil.getUsername(token); + LoginUser sysUser = sysBaseApi.getUserByName(username); + + if (sysUser == null) { + return Result.error("用户信息不存在"); + } + + // 2. 验证会话是否存在 + AiolChat chat = aiolChatService.getById(chatId); + if (chat == null) { + return Result.error("会话不存在"); + } + + // 3. 查询用户是否为该会话的成员 + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId()); + AiolChatMember chatMember = aiolChatMemberMapper.selectOne(memberWrapper); + + if (chatMember == null) { + return Result.error("您不是该会话的成员"); + } + + // 4. 检查是否为会话创建者(可选:不允许创建者退出) + if (chat.getCreateBy() != null && chat.getCreateBy().equals(sysUser.getId())) { + // 可选:如果创建者退出,需要转移创建者权限或不允许退出 + log.warn("会话创建者尝试退出群聊: chatId={}, userId={}", chatId, sysUser.getId()); + // 这里可以选择是否允许创建者退出,或者需要先转移权限 + // return Result.error("群聊创建者不能直接退出,请先转移群主权限"); + } + + // 5. 从会话成员表中删除该用户 + boolean deleted = aiolChatMemberMapper.deleteById(chatMember.getId()) > 0; + + if (!deleted) { + return Result.error("退出群聊失败"); + } + + // 6. 检查会话是否还有其他成员,如果没有则删除会话(可选) + QueryWrapper remainingMemberWrapper = new QueryWrapper<>(); + remainingMemberWrapper.eq("chat_id", chatId); + long remainingMemberCount = aiolChatMemberMapper.selectCount(remainingMemberWrapper); + + if (remainingMemberCount == 0) { + // 如果没有其他成员了,删除会话 + aiolChatService.removeById(chatId); + log.info("会话 {} 无成员,已自动删除", chatId); + } + + log.info("用户 {} 成功退出群聊 {}", username, chatId); + return Result.OK("退出群聊成功!"); + + } catch (Exception e) { + log.error("退出群聊失败: chatId={}, error={}", chatId, e.getMessage(), e); + return Result.error("退出群聊失败: " + e.getMessage()); + } + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/ChatWithUnreadCountDTO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/ChatWithUnreadCountDTO.java new file mode 100644 index 00000000..21524d25 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/ChatWithUnreadCountDTO.java @@ -0,0 +1,21 @@ +package org.jeecg.modules.aiol.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.jeecg.modules.aiol.entity.AiolChat; + +/** + * @Description: 会话详情DTO,包含未读消息数 + * @Author: jeecg-boot + * @Date: 2025-01-16 + * @Version: V1.0 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@Schema(description = "会话详情,包含未读消息数") +public class ChatWithUnreadCountDTO extends AiolChat { + + @Schema(description = "未读消息数") + private Integer unreadCount; +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolChatMember.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolChatMember.java index 4e442739..27addb30 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolChatMember.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolChatMember.java @@ -60,7 +60,7 @@ public class AiolChatMember implements Serializable { /**最后已读消息id*/ @Excel(name = "最后已读消息id", width = 15) @Schema(description = "最后已读消息id") - private java.lang.Integer lastReadMsgId; + private java.lang.String lastReadMsgId; /**创建人*/ @Schema(description = "创建人") private java.lang.String createBy;