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 c92d743a..9b77ba3e 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 @@ -1,5 +1,6 @@ package org.jeecg.modules.aiol.controller; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; @@ -33,6 +34,7 @@ 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.entity.SysUserRole; import org.jeecg.modules.system.mapper.SysUserMapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -56,149 +58,149 @@ import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import org.jeecg.common.aspect.annotation.AutoLog; import org.apache.shiro.authz.annotation.RequiresPermissions; - /** + +/** * @Description: 会话 * @Author: jeecg-boot - * @Date: 2025-09-11 + * @Date: 2025-09-11 * @Version: V1.0 */ -@Tag(name="会话") +@Tag(name = "会话") @RestController @RequestMapping("/aiol/aiolChat") @Slf4j public class AiolChatController extends JeecgController { - @Autowired - private IAiolChatService aiolChatService; - - @Autowired - private AiolChatMemberMapper aiolChatMemberMapper; - - @Autowired - private ISysBaseAPI sysBaseApi; - - @Autowired - private SysUserMapper sysUserMapper; - - @Autowired - private AiolChatMessageMapper aiolChatMessageMapper; - - @Autowired - private AiolClassMapper aiolClassMapper; - - @Autowired - private AiolClassStudentMapper aiolClassStudentMapper; - - @Autowired - private SysUserRoleMapper sysUserRoleMapper; - - /** - * 分页列表查询 - * - * @param aiolChat - * @param pageNo - * @param pageSize - * @param req - * @return - */ - //@AutoLog(value = "会话-分页列表查询") - @Operation(summary="会话-分页列表查询") - @GetMapping(value = "/list") - public Result> queryPageList(AiolChat aiolChat, - @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, - @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, - HttpServletRequest req) { + @Autowired + private IAiolChatService aiolChatService; + @Autowired + private AiolChatMemberMapper aiolChatMemberMapper; - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(aiolChat, req.getParameterMap()); - Page page = new Page(pageNo, pageSize); - IPage pageList = aiolChatService.page(page, queryWrapper); - return Result.OK(pageList); - } - - /** - * 添加 - * - * @param aiolChat - * @return - */ - @AutoLog(value = "会话-添加") - @Operation(summary="会话-添加") - @RequiresPermissions("aiol:aiol_chat:add") - @PostMapping(value = "/add") - public Result add(@RequestBody AiolChat aiolChat) { - aiolChatService.save(aiolChat); + @Autowired + private ISysBaseAPI sysBaseApi; - return Result.OK("添加成功!"); - } - - /** - * 编辑 - * - * @param aiolChat - * @return - */ - @AutoLog(value = "会话-编辑") - @Operation(summary="会话-编辑") - @RequiresPermissions("aiol:aiol_chat:edit") - @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) - public Result edit(@RequestBody AiolChat aiolChat) { - aiolChatService.updateById(aiolChat); - return Result.OK("编辑成功!"); - } - - /** - * 通过id删除 - * - * @param id - * @return - */ - @AutoLog(value = "会话-通过id删除") - @Operation(summary="会话-通过id删除") - @RequiresPermissions("aiol:aiol_chat:delete") - @DeleteMapping(value = "/delete") - public Result delete(@RequestParam(name="id",required=true) String id) { - aiolChatService.removeById(id); - return Result.OK("删除成功!"); - } - - /** - * 批量删除 - * - * @param ids - * @return - */ - @AutoLog(value = "会话-批量删除") - @Operation(summary="会话-批量删除") - @RequiresPermissions("aiol:aiol_chat:deleteBatch") - @DeleteMapping(value = "/deleteBatch") - public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { - this.aiolChatService.removeByIds(Arrays.asList(ids.split(","))); - return Result.OK("批量删除成功!"); - } - - /** - * 通过id查询 - * - * @param id - * @return - */ - //@AutoLog(value = "会话-通过id查询") - @Operation(summary="会话-通过id查询") - @GetMapping(value = "/queryById") - public Result queryById(@RequestParam(name="id",required=true) String id) { - AiolChat aiolChat = aiolChatService.getById(id); - if(aiolChat==null) { - return Result.error("未找到对应数据"); - } - return Result.OK(aiolChat); - } + @Autowired + private SysUserMapper sysUserMapper; + + @Autowired + private AiolChatMessageMapper aiolChatMessageMapper; + + @Autowired + private AiolClassMapper aiolClassMapper; + + @Autowired + private AiolClassStudentMapper aiolClassStudentMapper; + + @Autowired + private SysUserRoleMapper sysUserRoleMapper; /** - * 导出excel - * - * @param request - * @param aiolChat - */ + * 分页列表查询 + * + * @param aiolChat + * @param pageNo + * @param pageSize + * @param req + * @return + */ + // @AutoLog(value = "会话-分页列表查询") + @Operation(summary = "会话-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(AiolChat aiolChat, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(aiolChat, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = aiolChatService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param aiolChat + * @return + */ + @AutoLog(value = "会话-添加") + @Operation(summary = "会话-添加") + @RequiresPermissions("aiol:aiol_chat:add") + @PostMapping(value = "/add") + public Result add(@RequestBody AiolChat aiolChat) { + aiolChatService.save(aiolChat); + + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param aiolChat + * @return + */ + @AutoLog(value = "会话-编辑") + @Operation(summary = "会话-编辑") + @RequiresPermissions("aiol:aiol_chat:edit") + @RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST }) + public Result edit(@RequestBody AiolChat aiolChat) { + aiolChatService.updateById(aiolChat); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "会话-通过id删除") + @Operation(summary = "会话-通过id删除") + @RequiresPermissions("aiol:aiol_chat:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + aiolChatService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "会话-批量删除") + @Operation(summary = "会话-批量删除") + @RequiresPermissions("aiol:aiol_chat:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + this.aiolChatService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + // @AutoLog(value = "会话-通过id查询") + @Operation(summary = "会话-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + AiolChat aiolChat = aiolChatService.getById(id); + if (aiolChat == null) { + return Result.error("未找到对应数据"); + } + return Result.OK(aiolChat); + } + + /** + * 导出excel + * + * @param request + * @param aiolChat + */ @RequiresPermissions("aiol:aiol_chat:exportXls") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, AiolChat aiolChat) { @@ -206,12 +208,12 @@ public class AiolChatController extends JeecgController importExcel(HttpServletRequest request, HttpServletResponse response) { @@ -233,46 +235,46 @@ public class AiolChatController extends JeecgController memberWrapper = new QueryWrapper<>(); memberWrapper.eq("user_id", sysUser.getId()); List chatMembers = aiolChatMemberMapper.selectList(memberWrapper); - + if (chatMembers.isEmpty()) { return Result.OK(new java.util.ArrayList<>()); } - + // 3. 提取chat_id列表 List chatIds = chatMembers.stream() .map(AiolChatMember::getChatId) .collect(Collectors.toList()); - + // 4. 根据chat_id列表查询会话详情 QueryWrapper chatWrapper = new QueryWrapper<>(); chatWrapper.in("id", chatIds); chatWrapper.orderByDesc("create_time"); - + List chatList = aiolChatService.list(chatWrapper); - + // 5. 转换为包含未读消息数的DTO列表 List resultList = new java.util.ArrayList<>(); - + for (AiolChat chat : chatList) { ChatWithUnreadCountDTO chatDTO = convertToChatWithUnreadCount(chat, chatMembers, sysUser.getId()); resultList.add(chatDTO); } - + log.info("用户 {} 查询到 {} 个会话", username, resultList.size()); return Result.OK(resultList); - + } catch (Exception e) { log.error("查询用户会话列表失败: {}", e.getMessage(), e); return Result.error("查询会话列表失败: " + e.getMessage()); @@ -293,62 +295,75 @@ public class AiolChatController extends JeecgController memberWrapper = new QueryWrapper<>(); memberWrapper.eq("chat_id", chatId); List chatMembers = aiolChatMemberMapper.selectList(memberWrapper); - + if (chatMembers.isEmpty()) { return Result.OK(new java.util.ArrayList<>()); } - + + // 将成员列表按userId建立映射,便于取出member相关字段 + Map userIdToMemberMap = chatMembers.stream() + .collect(Collectors.toMap(AiolChatMember::getUserId, m -> m, (a, b) -> a)); + // 2. 提取用户ID列表 List userIds = chatMembers.stream() .map(AiolChatMember::getUserId) .collect(Collectors.toList()); - + // 3. 查询用户信息 List userList = sysUserMapper.selectByIds(userIds); - + // 4. 查询所有用户的教师角色身份 - Map teacherStatusMap = new java.util.HashMap<>(); + Map teacherStatusMap = new HashMap<>(); if (!userIds.isEmpty()) { try { - QueryWrapper roleWrapper = new QueryWrapper<>(); + QueryWrapper roleWrapper = new QueryWrapper<>(); roleWrapper.eq("role_id", RoleConst.TEACHER_ROLE_ID) - .in("user_id", userIds); - - List teacherRoleList = sysUserRoleMapper.selectList(roleWrapper); - + .in("user_id", userIds); + + List teacherRoleList = sysUserRoleMapper.selectList(roleWrapper); + // 构建教师身份映射 - for (org.jeecg.modules.system.entity.SysUserRole userRole : teacherRoleList) { + for (SysUserRole userRole : teacherRoleList) { teacherStatusMap.put(userRole.getUserId(), true); } } catch (Exception e) { log.warn("查询教师角色身份失败: error={}", e.getMessage()); } } - + // 5. 构建返回结果 - List> result = new java.util.ArrayList<>(); + List> result = new ArrayList<>(); for (SysUser user : userList) { - Map memberInfo = new java.util.HashMap<>(); + Map memberInfo = new HashMap<>(); memberInfo.put("id", user.getId()); memberInfo.put("realname", user.getRealname()); memberInfo.put("avatar", user.getAvatar()); - + // 添加教师身份标记 boolean isTeacher = teacherStatusMap.getOrDefault(user.getId(), false); memberInfo.put("isTeacher", isTeacher); - + // 可选:添加更多用户信息 memberInfo.put("username", user.getUsername()); memberInfo.put("phone", user.getPhone()); memberInfo.put("email", user.getEmail()); memberInfo.put("sex", user.getSex()); - + + // 新增:返回aiol_chat_member表中的角色与设置字段 + AiolChatMember member = userIdToMemberMap.get(user.getId()); + if (member != null) { + memberInfo.put("role", member.getRole()); + memberInfo.put("izMuted", member.getIzMuted()); + memberInfo.put("izNotDisturb", member.getIzNotDisturb()); + memberInfo.put("lastReadMsgId", member.getLastReadMsgId()); + } + result.add(memberInfo); } - + log.info("查询会话 {} 的成员列表,共 {} 个成员", chatId, result.size()); return Result.OK(result); - + } catch (Exception e) { log.error("查询会话成员列表失败: chatId={}, error={}", chatId, e.getMessage(), e); return Result.error("查询会话成员列表失败: " + e.getMessage()); @@ -358,8 +373,8 @@ public class AiolChatController extends JeecgController messageWrapper = new QueryWrapper<>(); messageWrapper.eq("chat_id", chatId); messageWrapper.orderByDesc("create_time"); - + List messageList = aiolChatMessageMapper.selectList(messageWrapper); - + if (messageList.isEmpty()) { return Result.OK(new java.util.ArrayList<>()); } - + // 2. 提取发送者ID列表 List senderIds = messageList.stream() .map(AiolChatMessage::getSenderId) .distinct() .collect(Collectors.toList()); - + // 3. 查询发送者信息 List senderList = sysUserMapper.selectByIds(senderIds); Map senderMap = senderList.stream() .collect(Collectors.toMap(SysUser::getId, user -> user)); - + // 4. 构建返回结果,包含发送者信息 List> result = new java.util.ArrayList<>(); for (AiolChatMessage message : messageList) { Map messageInfo = new java.util.HashMap<>(); - + // 添加消息基本信息 messageInfo.put("id", message.getId()); messageInfo.put("chatId", message.getChatId()); @@ -406,32 +421,36 @@ public class AiolChatController extends JeecgController() {{ - put("id", sender.getId()); - put("realname", sender.getRealname()); - put("avatar", sender.getAvatar()); - put("username", sender.getUsername()); - }}); + messageInfo.put("senderInfo", new java.util.HashMap() { + { + put("id", sender.getId()); + put("realname", sender.getRealname()); + put("avatar", sender.getAvatar()); + put("username", sender.getUsername()); + } + }); } else { // 如果找不到发送者信息,设置默认值 - messageInfo.put("senderInfo", new java.util.HashMap() {{ - put("id", message.getSenderId()); - put("realname", "未知用户"); - put("avatar", ""); - put("username", ""); - }}); + messageInfo.put("senderInfo", new java.util.HashMap() { + { + put("id", message.getSenderId()); + put("realname", "未知用户"); + put("avatar", ""); + put("username", ""); + } + }); } - + result.add(messageInfo); } - + log.info("查询会话 {} 的消息列表,共 {} 条消息", chatId, result.size()); return Result.OK(result); - + } catch (Exception e) { log.error("查询会话消息列表失败: chatId={}, error={}", chatId, e.getMessage(), e); return Result.error("查询会话消息列表失败: " + e.getMessage()); @@ -453,7 +472,7 @@ public class AiolChatController extends JeecgController result = new java.util.HashMap<>(); result.put("id", chat.getId()); @@ -467,7 +486,7 @@ public class AiolChatController extends JeecgController studentWrapper = new QueryWrapper<>(); studentWrapper.eq("class_id", aiolClass.getId()); long studentCount = aiolClassStudentMapper.selectCount(studentWrapper); classInfo.put("studentCount", studentCount); - + result.put("classInfo", classInfo); } else { log.warn("群聊会话 {} 关联的班级 {} 不存在", chatId, chat.getRefId()); result.put("classInfo", null); } } catch (Exception e) { - log.error("查询群聊班级信息失败: chatId={}, refId={}, error={}", + log.error("查询群聊班级信息失败: chatId={}, refId={}, error={}", chatId, chat.getRefId(), e.getMessage(), e); result.put("classInfo", null); } } else { result.put("classInfo", null); } - + log.info("查询会话详情成功: chatId={}, type={}", chatId, chat.getType()); return Result.OK(result); - + } catch (Exception e) { log.error("查询会话详情失败: chatId={}, error={}", chatId, e.getMessage(), e); return Result.error("查询会话详情失败: " + e.getMessage()); @@ -586,9 +605,9 @@ public class AiolChatController extends JeecgController muteMember(@PathVariable(value = "chatId") String chatId, - @PathVariable(value = "userId") String 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) { @@ -648,8 +667,8 @@ public class AiolChatController extends JeecgController unmuteMember(@PathVariable(value = "chatId") String chatId, - @PathVariable(value = "userId") String 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) { @@ -668,8 +687,8 @@ public class AiolChatController extends JeecgController enableNotDisturb(@PathVariable(value = "chatId") String chatId, - @PathVariable(value = "userId") String 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) { @@ -688,8 +707,8 @@ public class AiolChatController extends JeecgController disableNotDisturb(@PathVariable(value = "chatId") String chatId, - @PathVariable(value = "userId") String 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) { @@ -701,19 +720,20 @@ public class AiolChatController extends JeecgController updateMemberSetting(String chatId, String userId, String fieldName, Integer value, String operationName) { + 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("该用户不是群聊成员或会话不存在"); } @@ -739,14 +759,16 @@ public class AiolChatController extends JeecgController chatMembers, String userId) { + private ChatWithUnreadCountDTO convertToChatWithUnreadCount(AiolChat chat, List chatMembers, + String userId) { ChatWithUnreadCountDTO chatDTO = new ChatWithUnreadCountDTO(); - + // 复制基本属性 chatDTO.setId(chat.getId()); chatDTO.setType(chat.getType()); @@ -759,40 +781,40 @@ public class AiolChatController extends JeecgController 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) { // 私聊类型,需要获取对方用户信息 @@ -800,13 +822,13 @@ public class AiolChatController extends JeecgController otherMemberWrapper = new QueryWrapper<>(); otherMemberWrapper.eq("chat_id", chat.getId()) - .ne("user_id", userId); + .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) { @@ -819,70 +841,70 @@ public class AiolChatController extends JeecgController updateLastReadMsgId(@PathVariable(value = "chatId") String chatId, - @PathVariable(value = "messageId") String messageId, - HttpServletRequest request) { + @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()); @@ -892,7 +914,7 @@ public class AiolChatController extends JeecgController exitChat(@PathVariable(value = "chatId") String chatId, - HttpServletRequest request) { + 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())) { // 可选:如果创建者退出,需要转移创建者权限或不允许退出 @@ -937,28 +959,28 @@ public class AiolChatController extends JeecgController 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/controller/AiolChatMemberController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMemberController.java index adfe293f..ab3b29d0 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMemberController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMemberController.java @@ -11,11 +11,16 @@ import java.net.URLDecoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.jeecg.common.api.vo.Result; +import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.system.util.JwtUtil; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.aiol.entity.AiolChatMember; +import org.jeecg.modules.aiol.entity.AiolChatMessage; import org.jeecg.modules.aiol.service.IAiolChatMemberService; +import org.jeecg.modules.aiol.service.IAiolChatMessageService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -27,6 +32,7 @@ import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.base.controller.JeecgController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMessageController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMessageController.java index 7f8988e7..e17aec50 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMessageController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolChatMessageController.java @@ -13,8 +13,12 @@ import javax.servlet.http.HttpServletResponse; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.system.query.QueryRuleEnum; +import org.jeecg.common.system.util.JwtUtil; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.common.util.oConvertUtils; +import org.jeecg.modules.aiol.entity.AiolChatMember; import org.jeecg.modules.aiol.entity.AiolChatMessage; +import org.jeecg.modules.aiol.service.IAiolChatMemberService; import org.jeecg.modules.aiol.service.IAiolChatMessageService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -27,6 +31,7 @@ import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.jeecg.common.system.api.ISysBaseAPI; import org.jeecg.common.system.base.controller.JeecgController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -37,21 +42,28 @@ import com.alibaba.fastjson.JSON; import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.Operation; import org.jeecg.common.aspect.annotation.AutoLog; +import org.jeecg.common.constant.CommonConstant; import org.apache.shiro.authz.annotation.RequiresPermissions; - /** + +/** * @Description: 会话消息 * @Author: jeecg-boot - * @Date: 2025-09-11 + * @Date: 2025-09-11 * @Version: V1.0 */ -@Tag(name="会话消息") +@Tag(name = "会话消息") @RestController @RequestMapping("/aiol/aiolChatMessage") @Slf4j public class AiolChatMessageController extends JeecgController { @Autowired private IAiolChatMessageService aiolChatMessageService; - + + @Autowired + private ISysBaseAPI sysBaseApi; + + @Autowired + private IAiolChatMemberService aiolChatMemberService; /** * 分页列表查询 * @@ -61,122 +73,179 @@ public class AiolChatMessageController extends JeecgController> queryPageList(AiolChatMessage aiolChatMessage, - @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, - @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, - HttpServletRequest req) { + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { - - QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(aiolChatMessage, req.getParameterMap()); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(aiolChatMessage, + req.getParameterMap()); Page page = new Page(pageNo, pageSize); IPage pageList = aiolChatMessageService.page(page, queryWrapper); return Result.OK(pageList); } - + /** - * 添加 + * 添加 * * @param aiolChatMessage * @return */ @AutoLog(value = "会话消息-添加") - @Operation(summary="会话消息-添加") - @RequiresPermissions("aiol:aiol_chat_message:add") + @Operation(summary = "会话消息-添加") @PostMapping(value = "/add") public Result add(@RequestBody AiolChatMessage aiolChatMessage) { aiolChatMessageService.save(aiolChatMessage); - return Result.OK("添加成功!"); + return Result.OK(aiolChatMessage.getId()); } - + /** - * 编辑 + * 编辑 * * @param aiolChatMessage * @return */ @AutoLog(value = "会话消息-编辑") - @Operation(summary="会话消息-编辑") + @Operation(summary = "会话消息-编辑") @RequiresPermissions("aiol:aiol_chat_message:edit") - @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + @RequestMapping(value = "/edit", method = { RequestMethod.PUT, RequestMethod.POST }) public Result edit(@RequestBody AiolChatMessage aiolChatMessage) { aiolChatMessageService.updateById(aiolChatMessage); return Result.OK("编辑成功!"); } - + /** - * 通过id删除 + * 通过id删除 * * @param id * @return */ @AutoLog(value = "会话消息-通过id删除") - @Operation(summary="会话消息-通过id删除") + @Operation(summary = "会话消息-通过id删除") @RequiresPermissions("aiol:aiol_chat_message:delete") @DeleteMapping(value = "/delete") - public Result delete(@RequestParam(name="id",required=true) String id) { + public Result delete(@RequestParam(name = "id", required = true) String id) { aiolChatMessageService.removeById(id); return Result.OK("删除成功!"); } - + /** - * 批量删除 + * 批量删除 * * @param ids * @return */ @AutoLog(value = "会话消息-批量删除") - @Operation(summary="会话消息-批量删除") + @Operation(summary = "会话消息-批量删除") @RequiresPermissions("aiol:aiol_chat_message:deleteBatch") @DeleteMapping(value = "/deleteBatch") - public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { this.aiolChatMessageService.removeByIds(Arrays.asList(ids.split(","))); return Result.OK("批量删除成功!"); } - + /** * 通过id查询 * * @param id * @return */ - //@AutoLog(value = "会话消息-通过id查询") - @Operation(summary="会话消息-通过id查询") + // @AutoLog(value = "会话消息-通过id查询") + @Operation(summary = "会话消息-通过id查询") @GetMapping(value = "/queryById") - public Result queryById(@RequestParam(name="id",required=true) String id) { + public Result queryById(@RequestParam(name = "id", required = true) String id) { AiolChatMessage aiolChatMessage = aiolChatMessageService.getById(id); - if(aiolChatMessage==null) { + if (aiolChatMessage == null) { return Result.error("未找到对应数据"); } return Result.OK(aiolChatMessage); } - /** - * 导出excel - * - * @param request - * @param aiolChatMessage - */ - @RequiresPermissions("aiol:aiol_chat_message:exportXls") - @RequestMapping(value = "/exportXls") - public ModelAndView exportXls(HttpServletRequest request, AiolChatMessage aiolChatMessage) { - return super.exportXls(request, aiolChatMessage, AiolChatMessage.class, "会话消息"); - } + /** + * 导出excel + * + * @param request + * @param aiolChatMessage + */ + @RequiresPermissions("aiol:aiol_chat_message:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, AiolChatMessage aiolChatMessage) { + return super.exportXls(request, aiolChatMessage, AiolChatMessage.class, "会话消息"); + } - /** - * 通过excel导入数据 - * - * @param request - * @param response - * @return - */ - @RequiresPermissions("aiol:aiol_chat_message:importExcel") - @RequestMapping(value = "/importExcel", method = RequestMethod.POST) - public Result importExcel(HttpServletRequest request, HttpServletResponse response) { - return super.importExcel(request, response, AiolChatMessage.class); - } + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("aiol:aiol_chat_message:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, AiolChatMessage.class); + } + /** + * 发送消息 + * 前端传递 chat_id、content、message_type、file_url,sender_id 从token获取 + */ + @AutoLog(value = "会话用户-发送消息") + @Operation(summary = "会话用户-发送消息", description = "发送会话消息,sender_id从token获取") + @PostMapping(value = "/send") + public Result sendMessage(@RequestBody Map body, 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. 解析参数 + String chatId = body.get("chat_id") != null ? String.valueOf(body.get("chat_id")) : null; + String content = body.get("content") != null ? String.valueOf(body.get("content")) : null; + Integer messageType = body.get("message_type") != null + ? Integer.parseInt(String.valueOf(body.get("message_type"))) + : 0; + String fileUrl = body.get("file_url") != null ? String.valueOf(body.get("file_url")) : null; + + if (chatId == null || chatId.trim().isEmpty()) { + return Result.error("chat_id不能为空"); + } + + // 3. 校验用户是否在该会话中 + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.eq("chat_id", chatId).eq("user_id", sysUser.getId()); + AiolChatMember chatMember = aiolChatMemberService.getOne(memberWrapper); + if (chatMember == null) { + return Result.error("您不是该会话的成员"); + } + + // 4. 组装消息并保存 + AiolChatMessage message = new AiolChatMessage(); + message.setChatId(chatId); + message.setSenderId(sysUser.getId()); + message.setContent(content); + message.setMessageType(messageType); + message.setStatus(0); + message.setFileUrl(fileUrl); + + aiolChatMessageService.save(message); + + log.info("用户 {} 在会话 {} 发送消息成功, messageId={}", username, chatId, message.getId()); + return Result.OK(message.getId()); + } catch (Exception e) { + log.error("发送消息失败: error={}", 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/controller/AiolCourseSectionController.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseSectionController.java index b48e1d3a..68c8b576 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseSectionController.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/controller/AiolCourseSectionController.java @@ -105,17 +105,14 @@ public class AiolCourseSectionController extends JeecgController deleteWrapper = new QueryWrapper<>(); @@ -152,7 +168,12 @@ public class AiolCourseSectionController extends JeecgController deleteWrapper = new QueryWrapper<>(); diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSectionDTO.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSectionDTO.java index e717ebd5..51e9d947 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSectionDTO.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/dto/AiolCourseSectionDTO.java @@ -21,10 +21,4 @@ public class AiolCourseSectionDTO extends AiolCourseSection { */ @Schema(description = "资源ID") private String targetId; - - /** - * 资源类型 - */ - @Schema(description = "资源类型") - private String targetType; }