From d925089869bd9c92efb8d317b4ab1868358c4463 Mon Sep 17 00:00:00 2001 From: GoCo Date: Mon, 15 Sep 2025 10:09:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A1=A5=E5=85=85=20&=20question=E8=A1=A8=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E6=96=B0=E5=A2=9Estatus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aiol/controller/AiolChatController.java | 240 ++++++++++++++++++ .../modules/aiol/entity/AiolQuestion.java | 6 +- .../modules/aiol/vue3/AiolQuestion.data.ts | 33 +++ 3 files changed, 278 insertions(+), 1 deletion(-) 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 3707f655..12d1dba4 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 @@ -11,11 +11,22 @@ 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.api.ISysBaseAPI; 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.config.shiro.IgnoreAuth; import org.jeecg.modules.aiol.entity.AiolChat; +import org.jeecg.modules.aiol.entity.AiolChatMember; +import org.jeecg.modules.aiol.entity.AiolChatMessage; +import org.jeecg.modules.aiol.mapper.AiolChatMemberMapper; +import org.jeecg.modules.aiol.mapper.AiolChatMessageMapper; import org.jeecg.modules.aiol.service.IAiolChatService; +import org.jeecg.modules.system.entity.SysUser; +import org.jeecg.modules.system.mapper.SysUserMapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; @@ -52,6 +63,18 @@ public class AiolChatController extends JeecgController> queryMyChatList(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. 根据用户ID查询会话成员表,获取chat_id列表 + QueryWrapper 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. 处理私聊类型的会话,获取对方用户信息 + 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()); + } + } + } + + log.info("用户 {} 查询到 {} 个会话", username, chatList.size()); + return Result.OK(chatList); + + } catch (Exception e) { + log.error("查询用户会话列表失败: {}", e.getMessage(), e); + return Result.error("查询会话列表失败: " + e.getMessage()); + } + } + + /** + * 查询群聊会话成员列表 + * + * @param chatId 会话ID + * @return + */ + @Operation(summary = "查询群聊会话成员列表", description = "根据会话ID查询该会话的所有成员信息,包括用户ID、真实姓名和头像") + @GetMapping(value = "/{chatId}/members") + public Result>> queryChatMembers(@PathVariable(value = "chatId") String chatId) { + try { + // 1. 根据会话ID查询会话成员 + QueryWrapper memberWrapper = new QueryWrapper<>(); + memberWrapper.eq("chat_id", chatId); + List chatMembers = aiolChatMemberMapper.selectList(memberWrapper); + + if (chatMembers.isEmpty()) { + return Result.OK(new java.util.ArrayList<>()); + } + + // 2. 提取用户ID列表 + List userIds = chatMembers.stream() + .map(AiolChatMember::getUserId) + .collect(Collectors.toList()); + + // 3. 查询用户信息 + List userList = sysUserMapper.selectByIds(userIds); + + // 4. 构建返回结果 + List> result = new java.util.ArrayList<>(); + for (SysUser user : userList) { + Map memberInfo = new java.util.HashMap<>(); + memberInfo.put("id", user.getId()); + memberInfo.put("realname", user.getRealname()); + memberInfo.put("avatar", user.getAvatar()); + + // 可选:添加更多用户信息 + memberInfo.put("username", user.getUsername()); + memberInfo.put("phone", user.getPhone()); + memberInfo.put("email", user.getEmail()); + memberInfo.put("sex", user.getSex()); + + 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()); + } + } + + /** + * 查询会话消息列表 + * + * @param chatId 会话ID + * @param pageNo 页码 + * @param pageSize 每页大小 + * @return + */ + @Operation(summary = "查询会话消息列表", description = "根据会话ID查询该会话的消息列表,包含发送者信息") + @GetMapping(value = "/{chatId}/messages") + public Result>> queryChatMessages( + @PathVariable(value = "chatId") String chatId) { + try { + // 1. 构建查询条件 + QueryWrapper 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()); + messageInfo.put("senderId", message.getSenderId()); + messageInfo.put("content", message.getContent()); + messageInfo.put("messageType", message.getMessageType()); + messageInfo.put("status", message.getStatus()); + messageInfo.put("fileUrl", message.getFileUrl()); + messageInfo.put("fileName", message.getFileName()); + messageInfo.put("fileSize", message.getFileSize()); + messageInfo.put("createTime", message.getCreateTime()); + + // 添加发送者信息 + SysUser sender = senderMap.get(message.getSenderId()); + if (sender != null) { + 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", ""); + }}); + } + + 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()); + } + } } diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolQuestion.java b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolQuestion.java index fe264c20..330455fe 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolQuestion.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/entity/AiolQuestion.java @@ -22,7 +22,7 @@ import lombok.experimental.Accessors; /** * @Description: 题目 * @Author: jeecg-boot - * @Date: 2025-09-02 + * @Date: 2025-09-15 * @Version: V1.0 */ @Data @@ -71,6 +71,10 @@ public class AiolQuestion implements Serializable { @Excel(name = "能力", width = 15) @Schema(description = "能力") private java.lang.Integer ability; + /**状态*/ + @Excel(name = "状态", width = 15) + @Schema(description = "状态") + private java.lang.Integer status; /**创建人*/ @Schema(description = "创建人") private java.lang.String createBy; diff --git a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolQuestion.data.ts b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolQuestion.data.ts index 88a27ad2..a5b2322c 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolQuestion.data.ts +++ b/jeecg-boot/jeecg-boot-module/jeecg-module-aiol/src/main/java/org/jeecg/modules/aiol/vue3/AiolQuestion.data.ts @@ -35,6 +35,21 @@ export const columns: BasicColumn[] = [ align:"center", dataIndex: 'score' }, + { + title: '程度', + align:"center", + dataIndex: 'degree' + }, + { + title: '能力', + align:"center", + dataIndex: 'ability' + }, + { + title: '状态', + align:"center", + dataIndex: 'status' + }, ]; //查询数据 export const searchFormSchema: FormSchema[] = [ @@ -76,6 +91,21 @@ export const formSchema: FormSchema[] = [ label: '分值', field: 'score', component: 'InputNumber', + }, + { + label: '程度', + field: 'degree', + component: 'InputNumber', + }, + { + label: '能力', + field: 'ability', + component: 'InputNumber', + }, + { + label: '状态', + field: 'status', + component: 'InputNumber', }, // TODO 主键隐藏字段,目前写死为ID { @@ -94,6 +124,9 @@ export const superQuerySchema = { analysis: {title: '题目解析',order: 3,view: 'umeditor', type: 'string',}, difficulty: {title: '难度',order: 4,view: 'number', type: 'number',dictCode: 'question_difficulty',}, score: {title: '分值',order: 5,view: 'number', type: 'number',}, + degree: {title: '程度',order: 6,view: 'number', type: 'number',}, + ability: {title: '能力',order: 7,view: 'number', type: 'number',}, + status: {title: '状态',order: 8,view: 'number', type: 'number',}, }; /**