微博的回复逻辑(自己理解)

首先dao层有dao的实体类,service有它自己的实体类,所以service在调用dao层时有一个补全实体类的逻辑,首先回复可以回复评论,回复也可以回复回复,设计表时需要一个回复人的id和一个被回复人的id,当从数据库中查到数据时返回到service时,先把回复人的id和被回复人的id分别当成两个map中的key存进去,然后在根据各自的id调用用户接口去查询该id下对应的用户昵称,之后把这个昵称分别存到map中,在补全service里面的实体类返回给前台,一共有两个方法 查询和修改,前台展示评论的时候 各自的评论下面只展示两条回复数据,后面会有三个点,当用户点击这三个点的时候,会把该评论下的回复都展示出来,所以前台需要调用后台的回复的查询方法两次,一次是之查找前两条的数据,另一次时所有的全部查询出来,后台只写一个方法就可以加上分页的条件 前台传输数据的时候把分页的字段传给后台,后台去查就可以,添加的时候注意一点 前台传输的时一个dto对象,需要把这个转化成dao层的对象,然后添加就行了

controller层

/**
     * 微博回复的查询方法
     *
     * @param commentsId 评论的id
     * @param offset     第几页
     * @param size       每一页的条数
     * @return Response
     */
    @RequestMapping(value = "/getReply", method = RequestMethod.POST)
    public Response selectReplyByCommentsId(Long commentsId, Integer offset, Integer size) {
        if (null != commentsId && null != offset && null != size) {
            try {
                PageInfo pageInfo = replyService.selectReplyDto(commentsId, offset, size);
                log.info("=查询成功:{}", pageInfo);
                return new ObjectResponse(0, "查询成功", pageInfo);
            } catch (Exception e) {
                log.error("=查询失败:{}", e);
                return new Response(2000, "查询失败");
            }
        } else {
            log.info("==查询的参数不能为空:{}:{}:{}", commentsId, offset, size);
            return new Response(2000, "查询参数不能为空!");
        }
    }

    /**
     * 微博回复的添加方法
     *
     * @param replyDto 回复的传输层实体类
     * @return Response
     */
    @RequestMapping(value = "/insertReply", method = RequestMethod.POST)
    public Response insetReply(ReplyDto replyDto) {
        if (null == userHolder.getCache()) {
            return new Response(2018, "用户未登录");
        }
        //使用后台获取的登录者id覆盖前端传输的id.
        replyDto.setCustomerId(userHolder.getCache().getUid());

        if (!Strings.isBlank(replyDto.getContentText())) {
            if (null != replyDto.getContentText()) {
                try {
                    ReplyDto replyDto1 = replyService.isnsertReplyDto(replyDto);
                    log.error("添加回复结果为:{}",replyDto1);
                    if (null != replyDto1) {
                        return new ObjectResponse(0, "添加成功", replyDto1);
                    }
                    return new Response(2000, "添加失败,返回结果为空");
                } catch (Exception e) {
                    log.error("==评论内容不能为空:{}", e);
                    return new Response(3000, "添加失败");
                }
            } else {
                log.info("==回复内容不能为空:{}", replyDto);
                return new Response(3001, "回复内容不能为空");
            }


        } else {
            log.info("==回复内容不能为空:{}", replyDto);
            return new Response(3002, "回复内容不能为空");
        }
    }

service层

package net.nxb.seer.app.services.impl;

import net.nxb.seer.app.services.ReplyService;
import net.nxb.seer.common.customer.domain.Customer;
import net.nxb.seer.common.dao.CustormerDao;
import net.nxb.seer.common.dao.ReplyMapper;
import net.nxb.seer.common.entity.ReplyDo;
import net.nxb.seer.common.page.PageInfo;
import net.nxb.seer.second.dto.ReplyDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Auther: wuyongfei
 * @Description: 微博回复的业务实现类
 * @Date: 2018/8/21 13:43
 */
@Service
public class ReplyServiceImpl implements ReplyService{

    @Autowired
    private ReplyMapper replyMapper;//回复的dao层对象

    @Autowired
    private CustormerDao custormerDao; //用户的dao层对象

    /**
     * 查询回复业务层
     * @param commentsId 评论id
     * @param offset 第几条数据
     * @param size 每页展示页数
     * @return 自定义对象 PageInfo
     */
    @Override
    public PageInfo selectReplyDto(Long commentsId, Integer offset, Integer size) {
        //创建返回值对象集合
        List<ReplyDto> resultList = new ArrayList<ReplyDto>();
        //调用回复dao层查询回复数据
        if(null !=commentsId && null != offset && null != size) {
            List<ReplyDo> replyDos = replyMapper.selectByCommentsId(commentsId, offset, size + 1);
            //创建回复人id集合
            List<Long> ids = new ArrayList<>();
            //创建被回复人id集合
            List<Long> ids1 = new ArrayList<>();
            if (null != replyDos && replyDos.size() != 0) {
                //遍历对象集合,取出id,放入id集合中
                for (ReplyDo replyDo : replyDos) {  //将对象中的用户id取出来放入id集合中
                    ids.add(replyDo.getCustomerId());
                    ids1.add(replyDo.getReplyTo());
                }
                if (null != ids && ids.size() != 0 && null != ids1 && ids1.size() != 0){

                    //调用用户持久层方法,根据id集合查询用户昵称,返回list对象集合
                    List<Customer> customers = custormerDao.findNameById(ids);
                    List<Customer> replyTOs = custormerDao.findNameById(ids1);

                    //根据id集合去查询昵称
                    Map<Long, String> Names = new HashMap<Long, String>();
                    Map<Long, String> replyNames = new HashMap<Long, String>();

                    if (null != customers && customers.size() !=0 ){
                        //遍历集合,取出对象,
                        for (Customer customer : customers) {
                            Names.put(customer.getId(), customer.getNickName());  //将对象id和名称添加到map集合中
                        }
                        //遍历被回复人集合,取出对象
                        for (Customer customer : replyTOs) {
                            replyNames.put(customer.getId(), customer.getNickName());  //将被回复人对象id和名称添加到map集合中
                        }

                        //遍历集合 完善返回对象集合
                        for (ReplyDo replyDo : replyDos) {
                            //创建servie传输对象
                            ReplyDto replyDto = new ReplyDto();
                            //将dao实体类对象数据copy到传输对象中
                            BeanUtils.copyProperties(replyDo, replyDto);
                            //取出用户id,根据用户id在map中查找用户昵称
                            String name = Names.get(replyDto.getCustomerId());
                            String name1=replyNames.get(replyDto.getReplyTo());
                            //将用户name设置到用户传输对象中
                            replyDto.setCommentsName(name);
                            replyDto.setReplyToName(name1);
                            resultList.add(replyDto);
                        }
                    }
                }
            }
        }
        //判断返回对象集合条数逻辑
        if (null ==resultList && resultList.size()==0){
            return new PageInfo(false,null);
        }
        if(resultList.size() <= size){    //如果小于或等于size,表示没有下一页
            //创建并返回结果集
            return  new PageInfo(false,resultList);
        }
        if (resultList.size() == size+1) {    //如果结果集大小等于参数大小+1,代表有下一页
            //将集合最后一个删除
            resultList.remove(size.intValue());
            //创建并返回结果集
            return  new PageInfo(true,resultList);
        }
        return  new PageInfo(false,null);
    }
     /**
     * 微博添加回复业务层
     * @param replyDto 添加对象
     */
    @Override
    public ReplyDto isnsertReplyDto(ReplyDto replyDto) {

        //把值给dao层对象
        ReplyDo replyDo=new ReplyDo();

        replyDo.setCreateTime(new Date());
        BeanUtils.copyProperties(replyDto,replyDo);
        //实现添加逻辑
        replyMapper.insertReply(replyDo);

        Customer customerById = custormerDao.findCustomerById(replyDo.getCustomerId());
        Customer customerById1 = custormerDao.findCustomerById(replyDo.getReplyTo());
        if (null !=customerById && null !=customerById1){
            replyDto.setReplyToName(customerById1.getNickName());
            replyDto.setCommentsName(customerById.getNickName());
            BeanUtils.copyProperties(replyDo,replyDto);
            return replyDto;
        }
        BeanUtils.copyProperties(replyDo,replyDto);
        return  replyDto;

    }
}

测试出现的Bug1:添加的时候,因为回复既可以回复评论,也可以回复回复,所以当回复评论的时候,此时的被回复的id是空的,这个时候在service中补全的时候一定查不到对应的昵称,而我写的代码中的controller在对前台传入值进行非空判断时是写上的这个被回复人id的这个字段的,所以导致回复回复没问题,但是回复评论的时候始终拦截,因为被回复人的ids始终为空,我第一次改是把它和评论id用|| 然后和其他的字段用&&的,但是后来一想不对劲,因为评论id是必须有的,而被回复人的id是可有可无的 有的话就是回复回复的,没有的话就是回复评论的,这两者没有什么关系。

Bug2:添加的时候,需要再service用的实体类中加入两个字段,一个是回复人的昵称,因为前台展示的效果是这样的注意看,所以添加的时候需要返回一个service对象,然后前端拿到这两个用户的昵称,才能展示给前台,需要改的就是,把返回类型的void改成service对象,然后在service层添加成功后,直接根据service的回复人id和被回复人id调用用户接口查询其用户对象,然后再根据这个对象分别取出这两个对象的名字赋值给service的对象实体类中,然后返回前端(注意:当时改完就直接测试 发现会报个空指针的错误,因为当时我根据用户id调用用户接口查询用户对象时没有这个用户,所以这个查询出来的用户对象是空的,然后调用给用户对象的get方法取用户昵称时肯定会报错,需要加一个非空判断,如果查询的用户为空就不执行赋值过程了,直接把没有用户呢称的service对象返回前台 并提示一个错误 没有该用户即可!)代码如下:回复人的昵称

微博的回复逻辑(自己理解)

微博的回复逻辑(自己理解)

Bug3:首先就是显示的昵称问题,改了之后始终显示错误,这是因为被回复人可以说空,而回复人不能为空,如果被回复人是空,说明回复的是帖子,如果不为空,说明回复的是回复人,而我当时直接来个非空判断,所以回复人的时候可以 回复帖子的时候就不行了,因为直接拦截了 去掉了非空判断就ok了;