评论插件

基于jquery 的评论小插件

github项目地址:https://github.com/fancaixia/jquery-comment

001.png
案例思路:

[后台建立两个表]

  • comment_list 评论表 id,userID,userName,articleID,content
  • reply_list 回复表 id,talkID,content,fromID,fromUser,toID,toUser

[查询评论]

  • 后台获取 comment_list 表数据
  • 检索reply_list表中item.talkID == comment_list中 item.id, 并存入comment_list中对应item.child

[发送评论]

  • 前台发送用户id,用户名称, 文章id, 评论内容到后台
  • 后台将评论存储到comment_list中

[删除评论]

  • 前台发送此条评论ID到后台,
  • 后台reply_list判断 talkId == id 进行删除
  • 同时查询comment_list判断 id 相等的数据并进行删除

[回复评论]

  • 前台发送评论id, 内容, fromID, fromUser, toID, toUser 到后台
  • 后台将消息存储到reply_list中

[删除回复]

  • 前台发送此条回复ID到后台,
  • 后台reply_list判断对应 id 进行删除

[前台判断]

  • 根据当前登录用户id判断评论或回复用户是否一致 (不可给自己评论)
  • 划过某条评论时判断是不是当前用户的评论,(只能删除自己的评论)

代码结构

comment_static

config.js            接口文档
common.js        封装 ajax 请求及提示信息
index.html         主文件
index.js              业务逻辑

模拟多个用户可复制index.html,并修改index.js 中currentUserID和currentUserName

comment_mysql_server
app.js        主文件 连接mysql配置
route

activity_talk        后台逻辑处理

项目启动

  1. cd / comment_mysql_server
  2. app.js 更改数据库连接信息
  3. npm / cnpm install
  4. npm run dev

代码片段:

server / route / activity_talk.js

const express = require('express');
const uuid = require('uuid')
const route_talk = express.Router();

route_talk.use((req,res,next)=>{
    
    //解决跨域请求
    res.header("Access-Control-Allow-Origin","*");
    res.header("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept");  
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
    next()

})

// 查询评论数据
route_talk.post('/get',(req,res)=>{
    let articleID = req.body.articleID;
    let talkID = req.body.talkID;
    let replyCount = req.body.replyCount;   //查询评论对应回复的条数  默认3  查询所有时设置为10000
    req.pool.query(`SELECT * FROM comment_list WHERE articleID=${articleID}`,(err,data)=>{
        if(err){
            res.send({code:1,msg:"服务端错误"}).end();
        }else{
            //文章列表查询评论成功后  遍历数组  回复表根根talkID查 回复数据 
            
            function makePromise(item, index) {
                return new Promise((resolve) => {
                    let newitem = JSON.parse(JSON.stringify(item));
                    //如果传入 talkID  那么此评论对应回复查询所有
                    if(talkID && talkID == newitem.id){
                        replyCount = 10000;
                    }else{
                        replyCount = 3;
                    }
                    
                    req.pool.query(`SELECT * FROM reply_list WHERE talkID="${newitem.id}" LIMIT 0,${replyCount}`,(err,replydata)=>{
                        if(err){
                            res.send({code:1,msg:"服务端错误"}).end();
                        }else{
                            //模拟查询用户表数据
                            newitem.img="./images/reply.jpg";
                            newitem.time = "2017-07-06  12:45";
                            newitem.child = JSON.parse(JSON.stringify(replydata));

                            //遍历回复数据  模拟查询用户表  添加用户信息
                            newitem.child.forEach((item,index) => {
                                item.fromImg = './images/reply_01.jpg';   //模拟查询用户表数据
                                item.time = "2017-07-06  12:45";
                            });
                        

                            req.pool.query(`SELECT COUNT(*) AS count FROM reply_list WHERE talkID="${newitem.id}"`,(err,num)=>{
                                if(err){
                                    res.send({code:1,msg:"服务端错误"}).end();
                                }else{
                                    newitem.replytotal = num[0].count;
                                    resolve(newitem)
        
                                }
                            })
                    

                        }
                    })

                });
            }
            
            
            Promise.all(data.map((v, k) => makePromise(v, k))).then(data => {
                res.send({code:0,data,}).end();
            });
            
           
            
        }
    })
})
//添加评论  
route_talk.post('/add',(req,res)=>{

    const uuid_str = uuid.v4().replace(/-/g,'');
    req.pool.query(`insert into comment_list (id,userID,userName,articleID,content) VALUES("${uuid_str}","${req.body.userID}","${req.body.userName}","${req.body.articleID}","${req.body.content}")`,(err,state)=>{
        if(err){
            res.send({code:1,msg:"添加失败"}).end();
        }else{
            //添加成功   返回评论数据
            res.send({code:0,msg:"添加成功"}).end();
        }
    })

})
//删除评论   首先删除评论对应回复  DELETE FROM reply_list WHERE talkID=""
route_talk.post('/remove',(req,res)=>{
    req.pool.query(`delete from reply_list where talkID="${req.body.id}"`,(err,state)=>{
        if(err){
            res.send({code:1,msg:"删除回复失败"}).end();
        }else{
            req.pool.query(`delete from comment_list where id="${req.body.id}"`,(err,data)=>{
                if(err){
                    res.send({code:1,msg:"删除评论失败"}).end();
                }else{
                    res.send({code:0,msg:"ok"}).end();
                }
            })
        }
    })

})
//添加回复
route_talk.post('/addreply',(req,res)=>{

    const uuid_str = uuid.v4().replace(/-/g,'');
    req.pool.query(`insert into reply_list (id,talkID,content,fromID,fromUser,toID,toUser) VALUES("${uuid_str}","${req.body.talkID}","${req.body.content}","${req.body.fromID}","${req.body.fromUser}","${req.body.toID}","${req.body.toUser}")`,(err,state)=>{
        if(err){
            res.send({code:1,msg:"回复失败"}).end();
        }else{
            res.send({code:1,msg:"ok"}).end();

        }
    })

})
//删除回复
route_talk.post('/removereply',(req,res)=>{
    req.pool.query(`delete from reply_list where id="${req.body.id}"`,(err,data)=>{
        if(err){
            res.send({code:1,msg:"删除回复失败"}).end();
        }else{
            res.send({code:1,msg:"删除回复成功"}).end();
        }
    })

})

module.exports = route_talk;

static / index.js

let replySize = 3;  //回复默认显示3条  当点击更多 则为评论相关回复total总数
const replyCount = 3; //回复条数大于3  隐藏
const currentUserID = '1549bd4753424d88a4f0d5839da33f96'; 
let currentUserName = '小财神';
// const currentUserID = '25b92f4e04d54ca5a159b46309255f7e';
// let currentUserName = '小迷糊'; 


let replyUser = '';   //回复人XXX
let replyUserID = '';  //回复人ID
let seeAlltalkID = '';   //点击查看按钮时  储存点击的评论ID  
let articleID = '0'    // 假设此篇文章ID 为 0 (根据文章ID 请求对应评论数据)

$('#current_user').html('当前用户:'+currentUserName)
//初始化渲染评论数据
getTalkData();
//初始化渲染评论数据
function getTalkData(id){
  let talkID = id || '';

  let data = {
    articleID,  
    talkID:talkID,
    replyCount:replyCount
  };
  commonfun.request(serverApi.getTalk,data,renderData,renderFail)
}

//获取数据成功回调
function renderData(data){
      if(data.code != 0){
          tipObj.setErrmsg(data.msg,1);
          return;
      }

      let talkStr = '';  //整个评论信息
      let moreStr = '';

      data.data.forEach((talkitem,index)=>{
        //判断此评论是否有回复
        let replyStr = '';  //回复文本
        if(talkitem.child.length > 0){
          replyStr = '
'; talkitem.child.forEach((item,index)=>{ //渲染评论数据 replyStr += '
'+ '
'+ ''+ ''+item.fromUser+''+ ' 回复: '+ ''+item.toUser+''+ ''+item.time+'
'+ '
'+ ''+item.content+''+ '回复'+ '删除'+ '
' }) moreStr = '
'+ '剩余'+(seeAlltalkID== talkitem.id? talkitem.replytotal-replySize : talkitem.replytotal-replyCount)+'条评论 '+(talkitem.replytotal-replySize == 0?'收起':"点击查看")+'
'; replyStr += moreStr+'
' } talkStr += '
'+ '
'+ '
'+ '
'+ ''+ ''+talkitem.userName+''+ ''+talkitem.time+''+ '回复
'+ '
'+ ''+talkitem.content+''+ '删除'+ '
'+replyStr+'
'; }) $('#talk_content').html(talkStr); } // 渲染数据失败 function renderFail(err){ tipObj.setErrmsg("请求失败,请重试",1); } //对文章评论 ++++++++++++++++++++++ $('#textareaBox').on('focus',function () { $('#cancelbtn').removeClass('none') }) //发布评论 $('#talk_submit').on('click',function(){ //提交请求 let content = $.trim($('#textareaBox').val()) if(content.length > 0){ let data = { userID:currentUserID, userName:currentUserName, articleID, content, }; commonfun.request(serverApi.addTalk,data,addTalkfun,addTalkFail) }else{ //提示层 tipObj.setErrmsg('请输入评论内容',1); } }) //添加评论成功 function addTalkfun(data){ $('#textareaBox').val('') $('#cancelbtn').addClass('none') getTalkData(); } //添加评论失败 function addTalkFail(err){ tipObj.setErrmsg("请求失败,请重试",1); } //发布评论回车事件处理 $('#textareaBox').keypress(function(e){ if(e.ctrlKey && e.which == 13 || e.which == 10 || e.which == 13) { $('#talk_submit').trigger('click') e.preventDefault(); //屏蔽enter对系统作用。按后增加\r\n等换行 } }); //取消评论 $('#cancelbtn').on('click',function(){ $('#textareaBox').val('') $(this).addClass('none') }) //滑过评论控件 显示删除按钮 $('#talk_content').on('mouseover','.comment_people_titleBox ',function(){ if(currentUserID == $(this).parents('.comment').attr('data-userID')){ $(this).find('#talk_remove').removeClass('none') } }); //移出评论控件 隐藏删除按钮 $('#talk_content').on('mouseout','.comment_people_titleBox',function(){ $(this).find('#talk_remove').addClass('none') }) //删除评论 $('#talk_content').on('click','#talk_remove',function(){ let id = $(this).parents('.comment').attr('data-id') let data = { id, } commonfun.request(serverApi.removeTalk,data,removeTalkfun,removeTalkFail) }) //删除评论成功回调 function removeTalkfun(){ //初始化查询评论数据 getTalkData(); } //删除评论失败回调 function removeTalkFail(){ tipObj.setErrmsg("请求失败,请重试",1); } //滑过回复控件 显示删除 $('#talk_content').on('mouseover','.one_reply ',function(){ if(currentUserID == $(this).attr('data-fromid')){ $(this).find('#reply_remove').removeClass('none') } }); //移出回复控件 隐藏删除 $('#talk_content').on('mouseout','.one_reply',function(){ $(this).find('#reply_remove').addClass('none') }) //点击回复 // 判断是否对自己回复 对自己回复则 return // 判断是否存在评论框 不存在创建 同时设置文本域值 @xxxx ++++++++++++++++++++++ $('#talk_content').on('click','.reply_fn',function(){ if($(this).attr('data-userid') == currentUserID){ return; } let areachild = $('#talk_content').find('.talk_box_s') if($(areachild).length == 0){ let textBox = setchildTextarea(); $(this).parents('.comment').append(textBox) }else{ $('#talk_content').find('.talk_box_s').remove(); let textBox = setchildTextarea(); $(this).parents('.comment').append(textBox) } let val = $(this).attr('data-username'); $('#talk_content').find('#textareaBox_s').val('@'+val+' ') replyUser = val; replyUserID = $(this).attr('data-userid'); }) //回复发布 $('#talk_content').on('click','#talk_submit_s',function(){ // 替换 @ xxx 为空 let content = ($.trim($('#textareaBox_s').val())).replace((replyUser),'') content = content.replace('@','') let talkID = $(this).parents('.comment').attr('data-id') if(content.length > 0){ let data = { talkID, content, fromID:currentUserID, fromUser:currentUserName, toID:replyUserID, toUser:replyUser, } commonfun.request(serverApi.addreply,data,replyfun,replyfail) }else{ tipObj.setErrmsg('请输入评论内容',1); } }) //回复发布成功 function replyfun(){ getTalkData(); $(this).parents('.talk_box_s').remove(); } //回复发布失败 function replyfail(){ tipObj.setErrmsg('请求失败,请重试',1) } //回复发布 回车事件处理 $('#talk_content').keypress('#textareaBox_s',function(e){ if(e.ctrlKey && e.which == 13 || e.which == 10 || e.which == 13) { $('#talk_content').find('#talk_submit_s').trigger('click') e.preventDefault(); //屏蔽enter对系统作用。按后增加\r\n等换行 } }); //删除回复 $('#talk_content').on('click','#reply_remove',function(){ let id = $(this).parents('.one_reply').attr('data-id') let data = { id:id } commonfun.request(serverApi.removereply,data,removeReplyfun,removeReplyfail) }) //删除回复成功 function removeReplyfun(){ //初始化查询评论数据 getTalkData(); } //删除回复失败 function removeReplyfail(){ tipObj.setErrmsg('请求失败,请重试',1) } //点击查看 获取评论并且根据talkID获取全部评论 $('#talk_content').on('click','#see_reply',function(){ seeAlltalkID = $(this).parents('.comment').attr('data-id') let replyTotal = $(this).attr('data-total') if(replySize == replyTotal){ replySize = replyCount; getTalkData(); }else{ replySize = replyTotal; //初始化查询评论数据 getTalkData(seeAlltalkID); } }) //回复取消 $('#talk_content').on('click','#cancelbtn_s',function(){ $(this).parents('.talk_box_s').remove(); }) //回复评论框 function setchildTextarea(){ return '
'+ ''+ '
' }

你可能感兴趣的:(评论插件)