学习天机02

1.注入bean的写法

学习天机02_第1张图片

学习天机02_第2张图片

构造函数的注入

学习天机02_第3张图片

2.回答和评论

在做这个功能的时候需要理解一些概念,张三提出问题就是提问者,李四去回答张三的问题,李四就是回答者,王五去回答李四的评论,王五就是评论者。

在提供的`InteractionReply`类中:

- `questionId`: 互动问题问题id,指的是原始问题的ID,比如张三提出的问题的ID。
- `answerId`: 回复的上级回答id,这个字段用来指向直接上一级的回答或评论的ID。在你给的场景中,如果王五是在评论李四的回答,那么`answerId`将会是李四回答的ID。
- `userId`: 回答者id,指的是进行回答或评论操作的用户的ID。在你的例子中,如果李四是回答问题的人,那么在李四的回答记录中,`userId`就是李四的ID;如果王五是在对李四的回答进行评论,那么在王五的评论记录中,`userId`就是王五的ID。
- `targetUserId`: 回复的目标用户id,这个字段可能用来指示这个回答或评论是针对哪个用户的。例如,如果王五是在回复李四的回答,那么`targetUserId`可能就是李四的用户ID。
- `targetReplyId`: 回复的目标回复id,这个字段可以用来指示这个回答或评论是直接针对哪个回答或评论的。在你的场景中,如果王五是在评论李四的回答,`targetReplyId`可能就是李四回答的`id`。

因此,根据你的场景,**上一级的回答者id** (`answerId`) **是指李四的回答的ID**。这个字段用于建立回答和评论之间的层级关系,让系统知道每个回答或评论是针对哪个问题或上一级回答/评论的。

新增页面原型:

学习天机02_第4张图片

业务流程:

学习天机02_第5张图片

前端传参

学习天机02_第6张图片

新增和分页查询的接口代码

@RestController
@RequestMapping("/replies")
@RequiredArgsConstructor
@Api(tags = "互动问答相关接口 ")
public class InteractionReplyController {

    private final IInteractionReplyService replyService;

    @ApiOperation("新增回答或评论")
    @PostMapping
    public void saveReply(@RequestBody ReplyDTO replyDTO) {
        replyService.saveReply(replyDTO);
    }

    @ApiOperation("分页查询回答或评论")
    @GetMapping("page")
    public PageDTO queryReplyPage(ReplyPageQuery pageQuery){
        return replyService.queryReplyPage(pageQuery, false);
    }
}
 @Override
    @Transactional
    public void saveReply(ReplyDTO replyDTO) {
        // 1.获取登录用户
        Long userId = UserContext.getUser();
        // 2.新增回答
        InteractionReply reply = BeanUtils.toBean(replyDTO, InteractionReply.class);
        reply.setUserId(userId);
        save(reply);
        // 3.累加评论数或者累加回答数
        // 3.1.判断当前回复的类型是否是回答
        boolean isAnswer = replyDTO.getAnswerId() == null;
        if (!isAnswer) {
            // 3.2.是评论,则需要更新上级回答的评论数量
            lambdaUpdate()
                    .setSql("reply_times = reply_times + 1")
                    .eq(InteractionReply::getId, replyDTO.getAnswerId())
                    .update();
        }
        // 3.3.尝试更新问题表中的状态、 最近一次回答、回答数量
        questionService.lambdaUpdate()
                .set(isAnswer, InteractionQuestion::getLatestAnswerId, reply.getAnswerId())
                .setSql(isAnswer, "answer_times = answer_times + 1")
                .set(replyDTO.getIsStudent(), InteractionQuestion::getStatus, QuestionStatus.UN_CHECK.getValue())
                .eq(InteractionQuestion::getId, replyDTO.getQuestionId())
                .update();

        // 4.尝试累加积分
        if(replyDTO.getIsStudent()) {
            // 学生才需要累加积分
            mqHelper.send(
                    MqConstants.Exchange.LEARNING_EXCHANGE,
                    MqConstants.Key.WRITE_REPLY,
                    5);
        }
    }

    @Override
    public PageDTO queryReplyPage(ReplyPageQuery query, boolean forAdmin) {
        // 1.问题id和回答id至少要有一个,先做参数判断
        Long questionId = query.getQuestionId();
        Long answerId = query.getAnswerId();
        if (questionId == null && answerId == null) {
            throw new BadRequestException("问题或回答id不能都为空");
        }
        // 标记当前是查询问题下的回答
        boolean isQueryAnswer = questionId != null;
        // 2.分页查询reply
        Page page = lambdaQuery()
                .eq(isQueryAnswer, InteractionReply::getQuestionId, questionId)
                .eq(InteractionReply::getAnswerId, isQueryAnswer ? 0L : answerId)
                .eq(!forAdmin, InteractionReply::getHidden, false)
                .page(query.toMpPage( // 先根据点赞数排序,点赞数相同,再按照创建时间排序
                        new OrderItem(DATA_FIELD_NAME_LIKED_TIME, false),
                        new OrderItem(DATA_FIELD_NAME_CREATE_TIME, true))
                );
        List records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 3.数据处理,需要查询:提问者信息、回复目标信息、当前用户是否点赞
        Set userIds = new HashSet<>();
        Set answerIds = new HashSet<>();
        Set targetReplyIds = new HashSet<>();
        // 3.1.获取提问者id 、回复的目标id、当前回答或评论id(统计点赞信息)
        for (InteractionReply r : records) {
            if(!r.getAnonymity() || forAdmin) {
                // 非匿名
                userIds.add(r.getUserId());
            }
            targetReplyIds.add(r.getTargetReplyId());
            answerIds.add(r.getId());
        }
        // 3.2.查询目标回复,如果目标回复不是匿名,则需要查询出目标回复的用户信息
        targetReplyIds.remove(0L);
        targetReplyIds.remove(null);
        if(targetReplyIds.size() > 0) {
            List targetReplies = listByIds(targetReplyIds);
            Set targetUserIds = targetReplies.stream()
                    .filter(Predicate.not(InteractionReply::getAnonymity).or(r -> forAdmin))
                    .map(InteractionReply::getUserId)
                    .collect(Collectors.toSet());
            userIds.addAll(targetUserIds);
        }
        // 3.3.查询用户
        Map userMap = new HashMap<>(userIds.size());
        if(userIds.size() > 0) {
            List users = userClient.queryUserByIds(userIds);
            userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));
        }
        // 3.4.查询用户点赞状态
        Set bizLiked = remarkClient.isBizLiked(answerIds);
        // 4.处理VO
        List list = new ArrayList<>(records.size());
        for (InteractionReply r : records) {
            // 4.1.拷贝基础属性
            ReplyVO v = BeanUtils.toBean(r, ReplyVO.class);
            list.add(v);
            // 4.2.回复人信息
            if(!r.getAnonymity() || forAdmin){
                UserDTO userDTO = userMap.get(r.getUserId());
                if (userDTO != null) {
                    v.setUserIcon(userDTO.getIcon());
                    v.setUserName(userDTO.getName());
                    v.setUserType(userDTO.getType());
                }
            }
            // 4.3.如果存在评论的目标,则需要设置目标用户信息
            if(r.getTargetReplyId() != null){
                UserDTO targetUser = userMap.get(r.getTargetUserId());
                if (targetUser != null) {
                    v.setTargetUserName(targetUser.getName());
                }
            }
            // 4.4.点赞状态
            v.setLiked(bizLiked.contains(r.getId()));
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), list);
    }

你可能感兴趣的:(学习)