栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

SpringBoot开源项目个人博客——(12)留言/其余页面显示

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot开源项目个人博客——(12)留言/其余页面显示

一、留言页面

留言和评论的实现几乎一模一样,还不需要传blogid,设计思路也一样,这里就直接给出代码。(或者直接参照评论代码,直接复制来改)

1. 持久层接口

在dao包下创建MessageDao接口,添加如下接口:(不需要传博客id)

@Mapper
@Repository
public interface MessageDao {

    //新增一个留言
    int savaMessage(Message message);

    //删除一个留言
    void deleteMessage(Long id);

    

    //查询父级留言 : 它的评论类的父留言的-1
    List findMessageParentIdNull(Long messageParentId);

    //查询一级回复 : 根据父留言id
    List findMessageParentNotNull(Long parentId);

    //查询二级回复 : 根据子回复 id
    List findMessageReplyId(Long childId);

    //单独查询一条回复,查出父评论,用于发送回复邮件
    Message findByParentId(Long id);
}
2.mapper

在mapper目录下创建MessageDao.xml文件,添加如下





    
    
        insert into t_message (nickname, email, content, avatar, create_time, parent_message_id, admin_message)
        values (#{nickname},#{email},#{content},#{avatar},#{createTime},#{parentMessageId},#{adminMessage});
    


    
    
        delete
        from t_message
        where id=#{id};
    

    
    
        select *
        from t_message
        where parent_message_id = #{parentId}
        order by create_time desc;
    

    
    
        select *
        from t_message where  id = #{id};
    


3. 业务层

在service包下创建MessageService接口

public interface MessageService {

    //新增一个留言
    int savaMessage(Message message);

    //删除一个留言 Message message
    void deleteMessage(Long id);

    
    List listMessage();

    Message findByParentId(Long id);//为了发邮件
}

在Impl包下创建接口实现类:MessageServiceImpl接口实现类

@Service
public class MessageServiceImpl implements MessageService {

    @Autowired
    private MessageDao messageDao;

    //存放迭代子评论的集合
    private List tempReplys = new ArrayList<>();

    @Override
    public int savaMessage(Message message) {
        message.setCreateTime(new Date());
        return messageDao.savaMessage(message);
    }

    @Override
    public void deleteMessage(Long id) {
        messageDao.deleteMessage(id);
    }

    @Override
    public List listMessage() {
        //查出父节点, pid =-1
        List messages = messageDao.findMessageParentIdNull((long) -1);

        //为每个父评论 找到 它的子代评论
        for (Message message : messages) {
            Long id = message.getId(); //作为 子代的  pid
            String Nickname = message.getNickname();

            List childMessages = messageDao.findMessageParentNotNull(id);
            //查出这个父评论的  所有子评论
            combineChildren(childMessages, Nickname); //查询完后,所有子代 都添加到 tempReplys中

            message.setReplyMessages(tempReplys);
            //System.out.println(tempReplys);
            tempReplys = new ArrayList<>();//给下一个用,不可以单纯清空内容
        }
        return messages;
    }

    private void combineChildren(List childMessages,String Nickname){

        //判读是否有 一级子评论
        if(childMessages.size() > 0){

            //循环找出 子评论
            for (Message childMessage : childMessages) {
                String parentNickname1 = childMessage.getNickname(); //作为 二级评论 的 父name
                Long childId = childMessage.getId();

                childMessage.setParentNickname(Nickname); //在这里才设置 回复的 parentNickname
                tempReplys.add(childMessage); //存入 子代评论中

                //循环 查出所有子二级评论
                recursively(childId,parentNickname1);
            }
        }

    }

    private void recursively(Long childId,String parentNickname){
        //根据一级评论 id  找到所有二级评论
        List replyMessages = messageDao.findMessageReplyId(childId);

        if(replyMessages.size()>0){
            for (Message replyMessage : replyMessages) {
                String parentNickname2 = replyMessage.getNickname();
                Long replyId = replyMessage.getId();

                replyMessage.setParentNickname(parentNickname);

                tempReplys.add(replyMessage);
                //评论可能还有 子代评论,接着找(直到空为止)
                recursively(replyId,parentNickname2);
            }
        }
    }


    //为了发邮件
    @Override
    public Message findByParentId(Long id) {
        return messageDao.findByParentId(id);
    }
}
4. 控制器

为了实现局部刷新,前端改动:

删除操作也改成局部刷新

回复
删除

...
...
...
回复
删除

JS部分:

// 校验信息
$('#messagepost-btn').click(function () {
    var boo = $('.ui.form').form('validate form');
    if (boo) {
        console.log('校验成功');
        postData();
    } else {
        console.log('校验失败');
    }
});

//发送请求给后端
function postData() {
    $('#message-container').load("/message", {
        "parentMessage.id": $("[name='parentMessage.id']").val(),
        "nickname": $("[name='nickname']").val(),
        "email": $("[name='email']").val(),
        "content": $("[name='content']").val()
    }, function (responseTxt, statusTxt, xhr) {
        clearContent();
    });
}

// 清除表单
function clearContent() {
    $("[name='nickname']").val('');
    $("[name='email']").val('');

    var user =  null;
    
    console.log(user);
    if( user ){
        $("[name='nickname']").val(user.nickname);
        $("[name='email']").val(user.email);
    }

    $("[name='content']").val('');
    $("[name='parentMessage.id']").val(-1);
    $("[name='content']").attr("placeholder", "请输入评论信息...");
}

function reply(obj) {
    //alert("回复");
    var messageId = $(obj).data('messageid');
    var messageNickname = $(obj).data('messagenickname');
    $("[name='content']").attr("placeholder", "@" + messageNickname).focus();
    $("[name='parentMessage.id']").val(messageId);
    $(window).scrollTo($('message-form'), 500);
}


function shanchu(obj){
    var flag =  confirm('确定要删除该评论吗?三思啊! 删了可就没了!');
    if(flag == true){
        var messageId = $(obj).data('messageid');

        $("#message-container").load("/messages/delete",{
            "messageId" : messageId
        });
    }
    $(window).scrollTo($('#message-container'),500);
}

在controller包下创建MessageController类,编写如下代码:(敏感词和邮件发送功能与评论一样,这里不再细说)

@Controller
public class MessageController {
    @Autowired
    private MessageService messageService;
    @Autowired
    private MailUtil mailUtil;
    @Autowired
    private SensitiveFilterUtil sensitiveFilterUtil;
    @Value("${message.avatar}")
    private String avatar;

    private String subject="HXJ的博客留言回复";

    @GetMapping("/message")
    public String message(Model model){
        List messages = messageService.listMessage();
        System.out.println(messages);
        model.addAttribute("messages",messages);
        return "message";
    }

    //新增留言
    @PostMapping("/message")
    public String post(Message message,Model model, HttpSession session){
        User user =(User)session.getAttribute("user");
        if(user!=null){
            message.setAvatar(user.getAvatar());
            message.setAdminMessage(true);
        }else {
            message.setAvatar(avatar);
        }

        message.setContent(sensitiveFilterUtil.filter(message.getContent()));

        //前端传的是 parentMessage.id
        if(message.getParentMessage().getId()!=null){
            //是评论
            message.setParentMessageId(message.getParentMessage().getId());//到impl中 的展示才设置parentNickname

            //是子评论
            if(message.getParentMessageId()!=-1){
                Message parentMessage = messageService.findByParentId(message.getParentMessageId());//获得父评论
                //发邮件给父评论
                String rpl="亲爱的【"+parentMessage.getNickname()+"】,你在【HXJ的博客】的评论:"+parentMessage.getContent()+".收到了来自【"+
                        message.getNickname()+"】的回复! 内容如下:nn";
                mailUtil.sendSimpleMail(parentMessage.getEmail(), subject, rpl+message.getContent());
            }
        }
        messageService.savaMessage(message);
        List messages = messageService.listMessage();
        System.out.println(messages);
        model.addAttribute("messages",messages);
        return "message :: messageList";
    }

    //删除
    @PostMapping("/messages/delete")
    public String delete(Model model, @RequestParam("messageId")Long messageId){
        messageService.deleteMessage(messageId);

        List messages = messageService.listMessage();
        System.out.println(messages);
        model.addAttribute("messages",messages);
        return "message :: messageList";
    }

}

效果示例图如下:


二、归档页(时间轴)

前端直接拿来用,前端所需要的字段较少(但不想再多建一个VO,拿已经有的vo中找一个属性最少的),于是用后台的这个BlogQuery。

这样dao接口Service接口和mapper都用已经存在的getAllBlogQuery接口。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r1VNMra7-1653976189192)(其余页面显示.assets/image-20220531132830021.png)]

  • 只需要编写控制器代码:

在controller包下创建ArchiveShowController类:

@Controller
public class ArchiveShowController {

    @Autowired
    private BlogService blogService;

    @GetMapping("/archives")
    public String archives(Model model){
        List list = blogService.getAllBlogQuery();
        model.addAttribute("blogs",list);
        return "archives";
    }

}
  • 效果示例图如下:

三、友链页

根据前端页面显示,可以直接调用持久层的listFriendLink接口,只需编写控制层代码就可以了。

  • 编写控制器代码:

在controller包下创建FriendsShowController类:

@Controller
public class FriendsShowController {

    @Autowired
    private FriendLinkService friendLinkService;

    @GetMapping("/friends")
    public String friend(Model model){
        List friendLinks = friendLinkService.listFriendLink();
        model.addAttribute("friendlinks",friendLinks);
        return "friends";
    }
}
  • 效果示例图如下:

四、照片墙页面显示

根据前端页面显示,可以直接调用持久层的listPicture接口,只需编写控制层代码就可以了。

照片墙使用了(lightbox插件)jkresponsivegallery.js

官方使用例:

  • 编写控制器代码:

在controller包下创建PictureShowController类:

@Controller
public class PictureShowController {

    @Autowired
    private PictureService pictureService;

    @GetMapping("/picture")
    public String picture(Model model){
        List pictures = pictureService.listPicture();
        model.addAttribute("pictures",pictures);
        return "picture";
    }
}
  • 效果示例图如下:

五、关于我页面显示

关于我页面显示是一个静态页面,直接在控制器中返回页面就可以了

  • 编写控制器代码:

在controller包下创建AboutShowController类:

@Controller
public class AboutShowController {

    @GetMapping("/about")
    public String about(){

        return "about";
    }
}
六、音乐盒

音乐盒显示是一个静态页面,直接在控制器中返回页面就可以了

原本oneStar使用了一个轻量的音乐js插件,结果我发现不如直接拉一个网易云外链方便。

  • 编写控制器代码:

在controller包下创建MusicShowController类:

@Controller
public class MusicShowController {

    //就一个静态页面
    @GetMapping("/music")
    public String music(){
        return "music";
    }
}

小结

至此所有功能开发已经完成。


如果想更换图片资源使用图床,可以看oneStar的Typora+PicGo+七牛云实现图片上传存储(配置不难,但是用PicGo配置的时候要知道自己的存储区域 官方手册有提到 )


线上部署方面,没有买服务器(没精力管),就做了一个穷人体验版。

使用了VMware Workstation 装个centos7,在虚拟机配置好后,本机也可以实现访问(下一篇文章将讲解我的操作。)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/940534.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号