天机学堂day05

day05

1 新增互动问题

接口说明 在课程详情页,或者用户学习视频页面,都可以对当前课程提出疑问:用户可以选择公开提问或匿名提问。用户提问可以上传图片
请求方式 POST
请求路径 /questions
请求参数格式 { "courseId": "1578558664933920770", "chapterId": "1578558664933920770", "sectionId": "1578558664933920356", "title": "JDK哪里下载", "description": "找不到网站啊老师", "anonymity": false }
返回值格式 --
InteractionQuestionController.java
java 复制代码
/**
 * 新增互动问题接口
 *
 * @param question
 */
@ApiOperation("新增互动问题接口")
@PostMapping
public void saveQuestion(QuestionFormDTO question) {
    interactionQuestionService.saveQuestion(question);
}
IInteractionQuestionService.java
java 复制代码
void saveQuestion(QuestionFormDTO question);
InteractionQuestionServiceImpl.java
java 复制代码
@Override
public void saveQuestion(QuestionFormDTO question) {
    // 1.将传递的信息进行映射填充
    InteractionQuestion interactionQuestion = BeanUtils.copyBean(question, InteractionQuestion.class);
    // 2.用户id
    interactionQuestion.setUserId(UserContext.getUser());
    // 3.对数据进行保存,一些参数都有默认值
    this.save(interactionQuestion);
}

2 删除互动问题

接口说明 互动消息的删除操作,前端传递对于的消息id后端进行校验判断从而判断
请求方式 DELETE
请求路径 /questions/{id}
请求参数格式 互动问题 id
返回值格式 --
InteractionQuestionController.java
java 复制代码
    /**
     * 删除指定id的互动问题接口
     *
     * @param id
     */

    @ApiOperation("根据id删除当前用户问题")
    @DeleteMapping("/{id}")
    public void deleteQuestion(@PathVariable("id") Long id) {
        interactionQuestionService.deleteById(id);
    }
IInteractionQuestionService.java
java 复制代码
    void deleteById(Long id);
InteractionQuestionServiceImpl.java
java 复制代码
    @Override
    public void deleteById(Long id) {
        InteractionQuestion byId = getById(id);
        if (byId == null) {
            throw new IllegalArgumentException("数据不存在");
        }
        if (!UserContext.getUser().equals(byId.getUserId())) {
            throw new IllegalArgumentException("无删除权限");
        }
        removeById(id);
    }

3 修改互动问题

接口说明 在课程详情页,或者用户学习视频页面,都可以点击自己提出的问题,修改问题标题、描述信息、是否匿名
请求方式 PUT
请求路径 /questions/{id}
请求参数格式 { "title": "JDK哪里下载", // 问题标题 "description": "找不到网站啊老师", // 问题描述 "anonymity": false, // 是否匿名 }
返回值格式 --
InteractionQuestionController.java
java 复制代码
/**
 * 修改指定id的互动问题接口
 *
 * @param id
 */
@ApiOperation("修改指定id的互动问题接口")
@PutMapping("{id}")
public void updateQuestion(@PathVariable Long id, @RequestBody QuestionFormDTO question) {
    interactionQuestionService.updateQuestion(id, question);
}
IInteractionQuestionService.java
java 复制代码
    void updateQuestion(Long id, QuestionFormDTO question);
InteractionQuestionServiceImpl.java
java 复制代码
    @Override
    public void updateQuestion(Long id, QuestionFormDTO question) {
        // 1.校验参数
        if (id == null) {
            throw new IllegalArgumentException("ID不能为空");
        }
        // 2.查询原始数据
        InteractionQuestion old = this.getById(id);
        if (old == null) {
            throw new IllegalArgumentException("数据不存在");
        }
        // 3.将原始数据进行更新
        // 3.1权限校验
        Long userId = UserContext.getUser();
        if (!userId.equals(old.getUserId())) {
            throw new IllegalArgumentException("无权限修改");
        }
        // 2. 只更新传入的非空字段
        if (question.getChapterId() != null) {
            old.setChapterId(question.getChapterId());
        }
        if (question.getSectionId() != null) {
            old.setSectionId(question.getSectionId());
        }
        if (StringUtils.isNotBlank(question.getTitle())) {
            old.setTitle(question.getTitle());
        }
        if (question.getDescription() != null) {
            old.setDescription(question.getDescription());
        }
        if (question.getAnonymity() != null) {
            old.setAnonymity(question.getAnonymity());
        }

        // 3. 更新修改时间
        old.setUpdateTime(LocalDateTime.now());

        // 4. 保存更新
        this.updateById(old);

    }

4 用户端分页查询问题

参数 说明
请求方式 GET
请求路径 /questions/page
请求参数 { "pageNo": 1, // 页码 "pageSize": 5, // 每页大小 "onlyMine": false, // 是否只查看我自己的问题 "courseId": "123", // 课程id,课程与小节至少指定一个 "sectionId": "123", // 小节id,课程与小节至少指定一个 }
返回值 { "total": 18, // 总数量 "totalPage": 4, // 页数 "list": [ { "id": "123", // 问题id "title": "JDK去哪里下载", // 问题的标题 "answerTimes": 10, // 回答数量,0表示没有回答 "createTime": "2023-01-12 12:30:20", // 问题提问时间 "anonymity": false, // 是否匿名 "userId": "123", // 提问者id "userName": "Jack", // 提问者昵称 "userIcon": "1.jpg", // 提问者头像 "latestReplyContent": "去Oracle官网", // 最近一次回答内容 "latestReplyUser": "Rose", // 最近一次回答的用户昵称 } ], }
描述 如果用户是匿名提问,则不应返回提问者信息如果是被管理端隐藏的问题,不应返回
InteractionQuestionController.java
java 复制代码
   @ApiOperation("分页查询课程问题-用户端")
    @GetMapping("page")
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        return questionService.queryQuestionPage(query);
    }
IInteractionQuestionService.java
java 复制代码
    PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query);
InteractionQuestionServiceImpl.java
java 复制代码
    @Override
    public PageDTO<QuestionVO> queryQuestionPage(QuestionPageQuery query) {
        // 1.查询问题的基本信息(传参:课程,小节,是否只查当前用户的boolean)
        if (query.getCourseId() == null || query.getSectionId() == null) {
            throw new BadRequestException("课程id和小节id不能为空");
        }
        LambdaQueryChainWrapper<InteractionQuestion> queryWrapper = lambdaQuery()
                .eq(InteractionQuestion::getCourseId, query.getCourseId())
                .eq(InteractionQuestion::getSectionId, query.getSectionId())
                .eq(InteractionQuestion::getHidden, false);
        if (query.getOnlyMine()) {
            queryWrapper.eq(InteractionQuestion::getUserId, UserContext.getUser());
        }
        Page<InteractionQuestion> page = queryWrapper.page(query.toMpPageDefaultSortByCreateTimeDesc());
        if (page.getTotal() == 0) {
            return PageDTO.empty(page);
        }
        List<InteractionQuestion> records = page.getRecords();
        // 2.查询回答对应的完整信息
        List<InteractionReply> reply = replyService.lambdaQuery().in(InteractionReply::getId, records.stream()
                .map(InteractionQuestion::getLatestAnswerId).filter(Objects::nonNull).collect(Collectors.toSet())).list();
        Map<Long, InteractionReply> replyMap = reply.stream().collect(Collectors
                .toMap(InteractionReply::getId, info -> info));
        // 3.查询回答问题的用户信息
        List<UserDTO> userDTOS = userClient.queryUserByIds(reply.stream()
                .map(InteractionReply::getUserId).collect(Collectors.toSet()));
        Map<Long, UserDTO> userMap01 = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, info -> info));
        // 4.查询提出问题的用户信息
        List<UserDTO> userDTOS1 = userClient.queryUserByIds(records.stream()
                .map(InteractionQuestion::getUserId).collect(Collectors.toSet()));
        Map<Long, UserDTO> userMap02 = userDTOS1.stream().collect(Collectors.toMap(UserDTO::getId, info -> info));
        ArrayList<QuestionVO> vo = new ArrayList<>(records.size());
        //首先先去查询出对应的问题的基本信息
        // (每个信息还需要关联出(1,提问者昵称 2. 提问者头像 3. 问题下的最新回答内容 4. 用户下最新回答用户昵称 5.提问者是否匿名))
        for (InteractionQuestion question : records) {
            // 1.将原始数据进行映射填充
            QuestionVO questionVO = BeanUtils.copyProperties(question, QuestionVO.class);
            // 2.获取回答者信息
            if (question.getLatestAnswerId() != null) {
                InteractionReply interactionReply = replyMap.get(question.getLatestAnswerId());
                UserDTO userDTO = userMap01.get(interactionReply.getUserId());
                questionVO.setLatestReplyUser(userDTO.getName());
                questionVO.setLatestReplyContent(interactionReply.getContent());
            }
            // 3.获取提问者信息
            UserDTO questionUser = userMap02.get(question.getUserId());
            if (questionUser != null) {
                questionVO.setUserName(questionUser.getName());
                questionVO.setUserIcon(questionUser.getIcon());
            } else {
                questionVO.setUserName("");
                questionVO.setUserIcon("");
            }
            //4.是否匿名
            questionVO.setAnonymity(question.getAnonymity());
            vo.add(questionVO);
        }

        return new PageDTO<>(page.getTotal(), page.getPages(), vo);
    }

5 用户端根据id查询问题详情

参数 说明
请求方式 GET
请求路径 /questions/{id}
请求参数 路径占位符,问题id
返回值 { "id": "123", // 问题id "title": "JDK去哪里下载", // 问题的标题 "description": "JDK去哪里下载", // 问题的描述 "answerTimes": 10, // 回答数量,0表示没有回答 "createTime": "2023-01-12 12:30:20", // 问题提问时间 "anonymity": false, // 是否匿名 "userId": "123", // 提问者id "userName": "Jack", // 提问者昵称 "userIcon": "1.jpg", // 提问者头像 }
InteractionQuestionController.java
java 复制代码
    @ApiOperation("根据id查询问题详情-用户端")
    @GetMapping("{id}")
    public QuestionVO queryQuestionById(@PathVariable Long id) {
        return questionService.queryQuestionById(id);
    }
IInteractionQuestionService.java
java 复制代码
    QuestionVO queryQuestionById(Long id);
InteractionQuestionServiceImpl.java
java 复制代码
    @Override
    public QuestionVO getQuestionById(Long id) {
        // 1.非空校验
        if (id == null) {
            throw new BadRequestException("参数id不能为空");
        }
        // 2.查询问题数据
        InteractionQuestion question = getById(id);
        if (question == null) {
            throw new BadRequestException("数据不存在");
        }
        // 3.属性映射
        QuestionVO questionVO = BeanUtils.copyProperties(question, QuestionVO.class);
        // 4.判断是否需要匿名
        if (!question.getAnonymity()) {
            //调用用户服务
            UserDTO userDTO = userClient.queryUserById(question.getUserId());
            if (userDTO != null) {
                questionVO.setUserName(userDTO.getName());
                questionVO.setUserIcon(userDTO.getIcon());
            }
        }
        // 5.返回
        return questionVO;
    }

6 管理端分页查询问题

InteractionQuestionAdminController.java
java 复制代码
    @PostMapping("page")
    @ApiModelProperty("管理端问题分页查询问题")
    public PageDTO<QuestionAdminVO> queryQuestionAdminPage(QuestionAdminPageQuery query) {
        return interactionQuestionService.queryQuestionAdminPage(query);
    }
IInteractionQuestionService.java
java 复制代码
    PageDTO<QuestionAdminVO> queryQuestionAdminPage(QuestionAdminPageQuery query);
InteractionQuestionServiceImpl.java
java 复制代码
 @Override
    public PageDTO<QuestionAdminVO> queryQuestionAdminPage(QuestionAdminPageQuery query) {
        // 1.传递的参数为课程的名称,需要去调用搜索查询课程的id
        String courseName = query.getCourseName();
        List<Long> acids = null;
        if (StringUtils.isNotBlank(courseName)) {
            //远程调用搜索服务 从es中搜索该关键字对应的课程id
            acids = searchClient.queryCoursesIdByName(courseName);
            if (CollUtils.isEmpty(acids)) {
                return PageDTO.empty(0L, 0L);
            }
        }
        // 2.查询互动问题表
        Page<InteractionQuestion> page = this.lambdaQuery()
                .in(CollUtils.isNotEmpty(acids), InteractionQuestion::getCourseId, acids)
                .eq(query.getStatus() != null, InteractionQuestion::getStatus, query.getStatus())
                .between(query.getBeginTime() != null && query.getEndTime() != null,
                        InteractionQuestion::getCreateTime, query.getBeginTime(), query.getEndTime())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());

        List<InteractionQuestion> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(0L, 0L);
        }


        //用户id集合
        Set<Long> aids = new HashSet<>();
        //课程id集合
        Set<Long> courseIds = new HashSet<>();
        //章节id集合
        Set<Long> chapterAndSectionIDs = new HashSet<>();

        for (InteractionQuestion record : records) {
            aids.add(record.getUserId());
            courseIds.add(record.getCourseId());
            chapterAndSectionIDs.add(record.getChapterId());
            chapterAndSectionIDs.add(record.getSectionId());
        }

        // 远程调用用户服务 获取用户信息
        List<UserDTO> userDTOS = userClient.queryUserByIds(aids);
        if (CollUtils.isEmpty(userDTOS)) {
            throw new BizIllegalException("用户不存在");
        }

        Map<Long, UserDTO> userDTOMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, c -> c));

        // 远程调用课程服务 获取课程信息
        List<CourseSimpleInfoDTO> infos = courseClient.getSimpleInfoList(courseIds);
        if (CollUtils.isEmpty(infos)) {
            throw new BizIllegalException("课程不存在");
        }

        Map<Long, CourseSimpleInfoDTO> cinfoMap = infos.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));

        // 远程调用课程服务 获取章节信息
        List<CataSimpleInfoDTO> SimpleCartInfoDOS = catalogueClient.batchQueryCatalogue(chapterAndSectionIDs);
        if (CollUtils.isEmpty(SimpleCartInfoDOS)) {
            throw new BizIllegalException("章节不存在");
        }
        Map<Long, String> catInfoDTO = SimpleCartInfoDOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, CataSimpleInfoDTO::getName));

        // 封装vo返回
        List<QuestionAdminVO> voList = new ArrayList<>();
        for (InteractionQuestion record : records) {
            // 属性拷贝
            QuestionAdminVO adminVO = BeanUtils.copyBean(record, QuestionAdminVO.class);
            // 用户Id拿用户信息
            UserDTO userDTO = userDTOMap.get(record.getUserId());
            if (userDTO != null) {
                adminVO.setUserName(userDTO.getName());
            }
            //课程id拿课程信息
            CourseSimpleInfoDTO infoDTO = cinfoMap.get(record.getCourseId());
            if (infoDTO != null) {
                adminVO.setCourseName(infoDTO.getName());
                //一 二 三级分类id集合
                List<Long> categoryIds = infoDTO.getCategoryIds();
                // 根据id集合获取课程一 二 三级分类名称,同时进行拼接
                String categoryNames = categoryCache.getCategoryNames(categoryIds);
                //三级分类名称
                adminVO.setCategoryName(categoryNames);
            }
            adminVO.setChapterName(catInfoDTO.get(record.getChapterId()));
            adminVO.setSectionName(catInfoDTO.get(record.getSectionId()));
            voList.add(adminVO);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), voList);
    }

7 管理端隐藏或显示问题

  • 接口地址 :/admin/questions/{id}/hidden/{hidden}

  • 请求方式 :PUT

  • 请求参数: 路径占位符参数

  • id:问题id

  • hidden:是否隐藏

InteractionQuestionAdminController.java
java 复制代码
@ApiOperation("隐藏显示问题-管理端")
@PutMapping("{id}/hidden/{hidden}")
public void hiddenQuestionAdmin(@PathVariable("id") Long id, @PathVariable("hidden") Boolean hidden){
    questionService.hiddenQuestionAdmin(id, hidden);
}
IInteractionQuestionService.java
java 复制代码
void hiddenQuestionAdmin(Long id, Boolean hidden);
InteractionQuestionServiceImpl.java
java 复制代码
@Override
public void hiddenQuestionAdmin(Long id, Boolean hidden) {
    InteractionQuestion question = this.getById(id);
    if (question == null) {
        throw new BadRequestException("该问题不存在");
    }
    question.setHidden(hidden);
    this.updateById(question);
}

8 管理端根据id查询问题详情

接口信息如下:
  • 接口地址 : /admin/questions/{id}
  • 请求方式 : GET
  • 请求参数: 路径占位符格式
  • 返回值:与分页查询共享VO,这里不再赘述
InteractionQuestionAdminController.java
java 复制代码
    @ApiOperation("查询问题详情-管理端")
    @GetMapping("{id}")
    public QuestionAdminVO queryQuestionAdminById(@PathVariable("id") Long id){
        return questionService.queryQuestionAdminById(id);
    }
IInteractionQuestionService.java
java 复制代码
    QuestionAdminVO queryQuestionAdminById(Long id);
InteractionQuestionServiceImpl.java
java 复制代码
    @Override
    public QuestionAdminVO queryQuestionAdminById(Long id) {
        //1、校验
        if (id == null) {
            throw new BadRequestException("非法参数!");
        }

        //2、查询互动问题表,按主键查询
        InteractionQuestion question = this.getById(id);
        if (question == null) {
            throw new BadRequestException("该问题不存在!");
        }

        //3、封装vo
        QuestionAdminVO vo = BeanUtils.copyBean(question, QuestionAdminVO.class);

        //4、远程调用用户服务,获取用户信息
        UserDTO userDTO = userClient.queryUserById(question.getUserId());
        if (userDTO != null) {
            vo.setUserName(userDTO.getName()); //用户名称
            vo.setUserIcon(userDTO.getIcon()); //用户头像
        }

        //5、远程调用课程服务,获取课程信息
        CourseFullInfoDTO courseDto = courseClient.getCourseInfoById(question.getCourseId(), false, true);
        if (courseDto != null) {
            vo.setCourseName(courseDto.getName()); //课程名称
            //获取教师名称
            List<Long> teacherIds = courseDto.getTeacherIds();
            if (CollUtils.isEmpty(teacherIds)) {
                throw new BizIllegalException("教师不存在!");
            }
            List<UserDTO> teacherDTOs = userClient.queryUserByIds(teacherIds);
            if (CollUtils.isNotEmpty(teacherDTOs)) {
                vo.setTeacherName(teacherDTOs.stream()
                        .map(UserDTO::getName)
                        .collect(Collectors.joining("/")));

            }
            //获取分类名称
            vo.setCategoryName(categoryCache.getCategoryNames(courseDto.getCategoryIds()));
        }

        //6、调用课程服务,获取章和节信息
        Set<Long> chapterAndSectionIds = new HashSet<>(); //章和节id集合
        chapterAndSectionIds.add(question.getChapterId());
        chapterAndSectionIds.add(question.getSectionId());
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient.batchQueryCatalogue(chapterAndSectionIds);
        if (CollUtils.isEmpty(cataSimpleInfoDTOS)) {
            throw new BizIllegalException("章和节不存在!");
        }
        Map<Long, String> cataSimpleInfoDTOMap = cataSimpleInfoDTOS.stream().collect(Collectors.toMap(CataSimpleInfoDTO::getId, c -> c.getName()));
        vo.setChapterName(cataSimpleInfoDTOMap.get(question.getChapterId())); //章名称
        vo.setSectionName(cataSimpleInfoDTOMap.get(question.getSectionId())); //节名称

        //7、查看完成,将问题status标记为已查看
        question.setStatus(QuestionStatus.CHECKED);
        this.updateById(question);

        //5、返回vo
        return vo;
    }

9 新增回答或评论

接口说明 在问答的详情页面,用户可以回答问题。也可以对他人的回答和评论做评论
请求方式 POST
请求路径 /replies
请求参数格式 { "questionId": "123", // 问题id "content": "回答的内容", // 回答的内容 "anonymity": false, // 是否匿名 "answerId": "321", // 上级回答id,没有可不填 "targetReplyId": "321", // 目标回复id,没有可不填 "targetUserId": "321", // 目标用户id,没有可不填 "isStudent": false, // 标记当前回答是否是学生提交的 }
返回值格式
InteractionReplyController.java
java 复制代码
@ApiOperation("新增回答或评论")
@PostMapping
public void saveReply(@Validated @RequestBody ReplyDTO dto) {
    replyService.saveReply(dto);
}
IInteractionReplyService.java
java 复制代码
    void saveReply(ReplyDTO replyDTO);
InteractionReplyServiceImpl.java
java 复制代码
@Override
public void saveReply(ReplyDTO dto) {
// 获取当前登录用户的id
Long userId = UserContext.getUser();

// 保存回答或者评论 interaction_reply
InteractionReply reply = BeanUtils.copyBean(dto, InteractionReply.class);
reply.setUserId(userId);
this.save(reply);


InteractionQuestion question = questionMapper.selectById(reply.getQuestionId());
// 判断是否是回答 dto.answerId 为空就是回答 不为空就是评论
if (dto.getAnswerId() != null) {
    // 是评论 累加回答下的评论次数
    InteractionReply answerInfo = this.getById(dto.getAnswerId());
    answerInfo.setReplyTimes(answerInfo.getReplyTimes() + 1);
    this.updateById(answerInfo);
} else {
    // 是回答 修改问题表最近一次回答id 同时累加问题表回答次数
    question.setLatestAnswerId(reply.getId());
    question.setAnswerTimes(question.getAnswerTimes() + 1);
}
// 判断是否是学生提交
Boolean isStudent = dto.getIsStudent();
if (isStudent) {
    // dto.isStudent为true 则代表学生提交 如果是则将问题表中该问题的status字段改为未查看
    question.setStatus(QuestionStatus.UN_CHECK);
}
questionMapper.updateById(question);
}

10 客户端分页查询回答或评论列表

InteractionReplyController.java
java 复制代码
@ApiOperation("客户端分页查询回答或评论列表")
@GetMapping("page")
public PageDTO<ReplyVO> queryReplyVoPage(ReplyPageQuery query) {
return replyService.queryReplyVoPage(query);
}
IInteractionReplyService.java
java 复制代码
PageDTO<ReplyVO> queryReplyVoPage(ReplyPageQuery query);
InteractionReplyServiceImpl.java
java 复制代码
@Override
public PageDTO<ReplyVO> queryReplyVoPage(ReplyPageQuery query) {
// 1.校验questionId和answerId是否都为空
if (query.getQuestionId() == null && query.getAnswerId() == null) {
    throw new BadRequestException("问题id和回答id不能都为空");
}
// 2.分页查询interaction_reply表
Page<InteractionReply> page = this.lambdaQuery()
// 如果传问题id则拼接问题id条件
.eq(query.getQuestionId() != null, InteractionReply::getQuestionId, query.getQuestionId())
//.eq(query.getAnswerId() != null, InteractionReply::getAnswerId, query.getAnswerId())
// 如果回答id没传,则查询answer_id为o的数据,也就是回答
.eq(InteractionReply::getAnswerId, query.getAnswerId() == null ? 0L : query.getAnswerId())
.eq(InteractionReply::getHidden, false)
.page(query.toMpPage(// 先根据点赞数排序,点赞数相同,再按照创建时间排序
    new OrderItem(DATA_FIELD_NAME_LIKED_TIME, false),
    new OrderItem(DATA_FIELD_NAME_CREATE_TIME, true)));

List<InteractionReply> records = page.getRecords();
if (CollUtils.isEmpty(records)) {
    return PageDTO.empty(0L, 0L);
}
// 3.补全其他数据
Set<Long> uids = new HashSet<>();
Set<Long> targetReplyIds = new HashSet<>();
for (InteractionReply record : records) {
    if (!record.getAnonymity()) {
        uids.add(record.getUserId());
        uids.add(record.getTargetUserId());
    }
    if (record.getTargetReplyId() != null && record.getTargetReplyId() > 0) {
        targetReplyIds.add(record.getTargetReplyId());
    }
}


// 查询目标回复,如果目标回复不是匿名
if (targetReplyIds.size() > 0) {
    List<InteractionReply> targetReplies = listByIds(targetReplyIds);
    Set<Long> targetUserIds = targetReplies.stream()
    .filter(Predicate.not(InteractionReply::getAnonymity))
    .map(InteractionReply::getUserId)
    .collect(Collectors.toSet());
    uids.addAll(targetUserIds);
}

List<UserDTO> userDTOList = userClient.queryUserByIds(uids);
Map<Long, UserDTO> userDTOMap = new HashMap<>();
if (userDTOList != null) {
    userDTOMap = userDTOList.stream().collect(Collectors.toMap(UserDTO::getId, c -> c));
}
// 4.封装vo返回
List<ReplyVO> voList = new ArrayList<>();
for (InteractionReply record : records) {
    ReplyVO vo = BeanUtils.copyBean(record, ReplyVO.class);
    if (!record.getAnonymity()) {
        UserDTO userDTO = userDTOMap.get(record.getUserId());
        if (userDTO != null) {
            vo.setUserName(userDTO.getName());
            vo.setUserIcon(userDTO.getIcon());
            vo.setUserType(userDTO.getType());
        }
    }
    UserDTO targetUserDTO = userDTOMap.get(record.getTargetReplyId());
    if (targetUserDTO != null) {
        vo.setTargetUserName(targetUserDTO.getName());
    }
    voList.add(vo);
}
return PageDTO.of(page, voList);
}

11 管理端分页查询回答或评论列表

接口说明 在管理端的问答的详情页面,需要分页查询问题下的回答列表。
请求方式 GET
请求路径 /admin/replies/page
请求参数格式 { "pageNo": 1, // 页码 "pageSize": 5, // 每页大小 "questionId": "123", // 问题id,问题与回答至少指定一个 "answerId": "123", // 回答id,问题与回答至少指定一个 }
返回值格式 { "total": 21, "totalPage": 5, "list": [ { "id": "123", // 问题id "content": "回答的内容", // 回答的内容 "hidden": false, // 是否被隐藏 "userId": "123", // 回答者id "userName": "Jack", // 回答者昵称 "userIcon": "1.jpg", // 回答者头像 "createTime": "2023-01-01 12:23:32", // 回答时间 "targetUserName": "Rose", // 被评论的用户昵称 "replyTimes": 5, // 回答下的评论数量 "likedTimes": 2, // 回答下的点赞数量 } ] }
InteractionReplyAdminController.java
java 复制代码
@ApiOperation("分页查询回答或评论-管理端")
@GetMapping("page")
public PageDTO<ReplyVO> queryReplyVOPageAdmin(ReplyPageQuery query){
    return replyService.queryReplyVOPageAdmin(query);
}
IInteractionReplyService.java
java 复制代码
PageDTO<ReplyVO> queryReplyVOPageAdmin(ReplyPageQuery query);
InteractionReplyServiceImpl.java
java 复制代码
@Override
public PageDTO<ReplyVO> queryReplyVOPageAdmin(ReplyPageQuery query) {
    return queryReplyVoPage(query);
}

12 管理端显示或隐藏评论

  • 接口地址: /admin/replies/{id}/hidden/{hidden}

  • 请求方式: PUT

  • **请求参数:**路径占位符参数

  • id:回答或评论id

  • hidden:是否被隐藏

InteractionReplyAdminController.java
java 复制代码
@ApiOperation("隐藏显示回答或评论")
@PutMapping("{id}/hidden/{hidden}")
public void hiddenReplyAdmin(@PathVariable("id") Long id, @PathVariable("hidden") Boolean hidden){
    replyService.hiddenReplyAdmin(id, hidden);
}
IInteractionReplyService.java
java 复制代码
void hiddenReplyAdmin(Long id, Boolean hidden);
InteractionReplyServiceImpl.java
java 复制代码
@Override
public void hiddenReplyAdmin(Long id, Boolean hidden) {
    //根据查询回答或评论
    InteractionReply reply = this.lambdaQuery()
    .eq(InteractionReply::getId, id).one();
    if (reply == null || hidden == null) {
        throw new BadRequestException("该回答或评论不存在");
    }
    //显示或隐藏
    reply.setHidden(hidden);
    this.updateById(reply);

    int num = hidden ? -1 : 1;
    //设置该评论上级的数量变化
    if (reply.getAnswerId() == 0) {
        //说明上级是评论
        InteractionReply answer = this.lambdaQuery().eq(InteractionReply::getAnswerId, id).one();
        answer.setReplyTimes(answer.getReplyTimes() + num);
        return;
    }
    //说明上级是回答
    InteractionQuestion question = questionMapper.selectById(reply.getQuestionId());
    question.setAnswerTimes(question.getAnswerTimes() + num);
    questionMapper.updateById(question);
}

13 管理端根据id查询回答或评论详情

  • 接口地址: /admin/replies/{id}

  • 请求方式: GET

  • **请求参数:**路径占位符参数

  • id:回答或评论id

InteractionReplyAdminController.java
java 复制代码
@ApiOperation("查询回答或评论详情-管理端")
@GetMapping("{id}")
public ReplyVO queryReplyVO(@PathVariable("id") Long id){
    return replyService.queryAdminReplyById(id);
}
IInteractionReplyService.java
java 复制代码
ReplyVO queryAdminReplyById(Long id);
InteractionReplyServiceImpl.java
java 复制代码
@Override
public ReplyVO queryAdminReplyById(Long id) {
    // 校验
    if (id == null) {
        throw new BadRequestException("非法参数!");
    }

    // 查询interaction_reply表,按主键查询
    InteractionReply reply = this.getById(id);
    if (reply == null) {
        throw new BadRequestException("该回答或评论不存在!");
    }

    // 封装vo
    ReplyVO vo = BeanUtils.copyBean(reply, ReplyVO.class);

    // 远程调用用户服务,获取用户信息
    UserDTO userDTO = userClient.queryUserById(reply.getUserId());
    if (userDTO != null) {
        vo.setUserName(userDTO.getName()); // 用户名称
        vo.setUserIcon(userDTO.getIcon()); // 用户头像
    }
    return vo;
}
相关推荐
葫芦和十三7 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp7 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑8 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯8 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
fanly119 小时前
Surging AI Agent 完整产品介绍
微服务·microservice
lizhongxuan11 小时前
多Agent之间的区别
后端
青石路12 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充13 小时前
1.面向对象设计思想
后端
IT_陈寒13 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro14 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端