学习天机02

1.注入bean的写法

构造函数的注入

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**。这个字段用于建立回答和评论之间的层级关系,让系统知道每个回答或评论是针对哪个问题或上一级回答/评论的。

新增页面原型:

业务流程:

前端传参

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

@RestController
@RequestMapping("/replies")
@RequiredArgsConstructor
@Api(tags = "互动问答相关接口 ")
public class InteractionReplyController {private final IInteractionReplyService replyService;@ApiOperation("新增回答或评论")@PostMappingpublic void saveReply(@RequestBody ReplyDTO replyDTO) {replyService.saveReply(replyDTO);}@ApiOperation("分页查询回答或评论")@GetMapping("page")public PageDTO<ReplyVO> queryReplyPage(ReplyPageQuery pageQuery){return replyService.queryReplyPage(pageQuery, false);}
}
 @Override@Transactionalpublic 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);}}@Overridepublic PageDTO<ReplyVO> 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.分页查询replyPage<InteractionReply> 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<InteractionReply> records = page.getRecords();if (CollUtils.isEmpty(records)) {return PageDTO.empty(page);}// 3.数据处理,需要查询:提问者信息、回复目标信息、当前用户是否点赞Set<Long> userIds = new HashSet<>();Set<Long> answerIds = new HashSet<>();Set<Long> 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<InteractionReply> targetReplies = listByIds(targetReplyIds);Set<Long> targetUserIds = targetReplies.stream().filter(Predicate.not(InteractionReply::getAnonymity).or(r -> forAdmin)).map(InteractionReply::getUserId).collect(Collectors.toSet());userIds.addAll(targetUserIds);}// 3.3.查询用户Map<Long, UserDTO> userMap = new HashMap<>(userIds.size());if(userIds.size() > 0) {List<UserDTO> users = userClient.queryUserByIds(userIds);userMap = users.stream().collect(Collectors.toMap(UserDTO::getId, u -> u));}// 3.4.查询用户点赞状态Set<Long> bizLiked = remarkClient.isBizLiked(answerIds);// 4.处理VOList<ReplyVO> 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);}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/467411.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通俗易懂搞定forEach和map的区别和使用

前言 在前端开发的时候&#xff0c;我们有时候需要对后端传过来的数组的进行相应的遍历处理&#xff0c;但是很多小伙伴对map和forEach两个方法的界限还是有模糊&#xff0c;本文从具体的示例来弄清楚两者的相同点和不同点 相同点 1.都是用于遍历数组的方法&#xff0c;可以…

《Linux 简易速速上手小册》第1章: Linux 系统基础(2024 最新版)

文章目录 1.1 Linux 操作系统概述1.1.1 重点基础知识1.1.2 重点案例&#xff1a;配置 Apache Web 服务器1.1.3 拓展案例 1&#xff1a;配置 SSH 服务以进行远程管理1.1.4 拓展案例 2&#xff1a;使用 Cron 定时任务 1.2 选择合适的 Linux 发行版1.2.1 重点基础知识1.2.2 重点案…

腾讯云幻兽帕鲁服务器配置怎么选择合适?

腾讯云幻兽帕鲁服务器配置怎么选&#xff1f;根据玩家数量选择CPU内存配置&#xff0c;4到8人选择4核16G、10到20人玩家选择8核32G、2到4人选择4核8G、32人选择16核64G配置&#xff0c;腾讯云百科txybk.com来详细说下腾讯云幻兽帕鲁专用服务器CPU内存带宽配置选择方法&#xff…

理解JAVA命名和目录接口(JNDI)

理解JAVA命名和目录接口(JNDI) 考虑访问网站的场景,Web用户要求记住四字节的IP地址而不是有意义的名称。例如,假设Web用户用123.23.3.123而不是hotmail.com访问hotmail网站。在这种情形下,Web用户难以记住不同的IP地址来访问不同的网站。因此,要使其变得对Web用户简单方…

Vue3高频知识点和写法

一 Vue插件 二 vue3项目创建 创建完成后npm install npm run dev 三 setup 一 响应式数据 setup函数是用来代替data和methods的写法的&#xff0c;在setup函数中声明的数据和函数&#xff0c;导出后可以在页面中使用。 但是暂时不是响应式数据&#xff0c;如果要响应式数据的…

单片机学习笔记---AT24C02数据存储

目录 AT24C02数据存储 准备工作 代码讲解 I2C.c 模拟起始位置的时序 模拟发送一个字节的时序 模拟接收应答的时序 模拟接收一个字节的时序 模拟发送应答的时序 模拟结束位置的时序 I2C.h AT24C02.c 字节写&#xff1a;在WORD ADDRESS&#xff08;字地址&#xff…

Verilog刷题笔记29

题目&#xff1a; Create a 100-bit binary ripple-carry adder by instantiating 100 full adders. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out. To encourage you to actually instantiate full adders, also output the ca…

【教3妹学编程-算法题】输入单词需要的最少按键次数 I

3妹&#xff1a;2哥&#xff0c;新年好鸭~ 2哥 : 新年好&#xff0c;3妹这么早啊 3妹&#xff1a;是啊&#xff0c;新年第一天要起早&#xff0c;这样就可以起早一整年 2哥 :得&#xff0c;我还不了解你&#xff0c;每天晒到日上三竿 3妹&#xff1a;嘿嘿嘿嘿&#xff0c;一年是…

【数据结构】链表OJ面试题4《返回链表入环的第一个结点》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 给定一个链表&#xff0c;判断链表中是否有环。http://t.csdnimg.cn/Rcdyc 记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 10. 给定一个链表&#xff0c;返回链表开始…

TCP和UDP相关问题(重点)——8.TCP的拥塞控制怎么实现的?

在某段时间内&#xff0c;若对网络中某一资源的需求超过了该资源所能提供的可用部分&#xff0c;网络性能就会变坏&#xff0c;比如在高速公路上行驶的车辆&#xff0c;如果一时期内涌入了太多的车辆&#xff0c;道路将变得拥堵&#xff0c;交通状况变差。网络中也是一样&#…

CTFshow web(php命令执行 68-71)

web68 还是那句话&#xff0c;没看到flag在哪&#xff0c;那就优先找到flag位置 这里cvar_dump(scandir("/")); 直接输出根目录的位置&#xff0c;然后查看源代码&#xff0c;发现flag位置为flag.txt 知道flag在根目录下面的flag.txt直接访问就好了 cinclude(/flag…

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection

【北邮鲁鹏老师计算机视觉课程笔记】07 Local feature-Blob detection 1 实现尺度不变性 不管多近多远&#xff0c;多大多小都能检测出来 找到一个函数&#xff0c;实现尺度的选择特性 2 高斯偏导模版求边缘 做卷积 3 高斯二阶导拉普拉斯 看哪个信号能产生最大响应 高斯…