springboot+vue实现评论回复功能-论坛2

无敌的宇宙
无敌的宇宙
擅长邻域:Java,HTML,JavaScript,MySQL,支付,退款,图片上传

分类: springboot vue 专栏: springboot vue 常用功能 标签: springboot+vue实现评论回复功能-论坛2

2025-02-19 22:16:42 285浏览

springboot+vue实现评论回复功能-论坛2

sql

-- ----------------------------
DROP TABLE IF EXISTS `xl_comment`;
CREATE TABLE `xl_comment`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `uid` int(0) DEFAULT NULL COMMENT '用户id',
  `context` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '评论',
  `cts` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '评论时间',
  `hf_id` int(0) DEFAULT NULL COMMENT '回复评论id',
  `hf_uid` int(0) DEFAULT NULL COMMENT '回复用户id',
  `fid` int(0) DEFAULT NULL COMMENT '帖子id',
  `ctype` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '保留字段',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 238 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

SET FOREIGN_KEY_CHECKS = 1;

bean

package com.jff.xinli.bean;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.List;

@Data
@TableName("xl_comment")
public class XlComment {
	@TableId(type = IdType.AUTO)
	private Integer id;
	private Integer uid;
	private Integer hfId;
	private Integer hfUid;
	private String cts;
	private String context;
	private String ctype;//article,forum
	private Integer fid;

	@TableField(exist = false)
	private String userNickname;
	@TableField(exist = false)
	private String faceimg;
	@TableField(exist = false)
	private String uhUserNickname;
	@TableField(exist = false)
	private String uhFaceimg;
	@TableField(exist = false)
	private List<XlComment> hfli;
	@TableField(exist = false)
	private String orderby;


	@TableField(exist = false)
	private String fname;
	@TableField(exist = false)
	private String keywords;
	@TableField(exist = false)
	private Integer tid;
	    
}

xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.jff.xinli.dao.XlCommentMapper">

	<sql id="field"> c.*
 ,u.nickname as userNickname,u.faceimg
 ,uh.nickname as uhUserNickname,uh.faceimg as uhFaceimg
  ,f.fname
 </sql>

	<select id="getlistByJoin" resultType="com.jff.xinli.bean.XlComment" parameterType="com.jff.xinli.bean.XlComment">
		select
		<include refid="field"></include>
		from xl_comment c
		left join xl_users u on u.id=c.uid
		left join xl_users uh on uh.id=c.hf_uid
		left join xl_forum f on f.id=c.fid
		left join xl_type t on t.id=f.tid
		where 1=1
		<if test="fid != null ">
			and  c.fid =#{fid}
		</if>
		<if test="uid != null ">
			and  c.uid =#{uid}
		</if>
		<if test="tid != null ">
			and t.id =#{tid}
		</if>
		<if test="hfId != null ">
			and  c.hf_id =#{hfId}
		</if>
		<if test="ctype != null and ctype != ''">
			and  c.ctype = #{ctype}
		</if>
		<if test="keywords != null and keywords != ''">
			and  (
			c.context like concat('%',#{keywords},'%')
			or u.nickname like concat('%',#{keywords},'%')
			or uh.nickname like concat('%',#{keywords},'%')
			or f.fcont like concat('%',#{keywords},'%')
			)
		</if>
		<if test="orderby == 'id_desc' ">
			order by c.id desc
		</if>
	</select>
	<select id="getIdByJoin" resultType="com.jff.xinli.bean.XlComment" parameterType="java.lang.Integer">
		select
		<include refid="field"></include>
		from xl_comment c
		left join xl_users u on u.id=c.uid
		left join xl_users uh on uh.id=c.hf_uid

		left join xl_forum f on f.id=c.fid
		 where
		 c.id=#{0}

	</select>


	<delete id="deleteByHfid" parameterType="java.lang.Integer">
   			delete from xl_comment where hf_id=#{0} and ctype='forum'
  	</delete>

	<delete id="deleteByFid" parameterType="java.lang.Integer">
   			delete from xl_comment where fid=#{0} and ctype='forum'
  	</delete>

	<select id="getCountByFid" resultType="java.lang.Integer" parameterType="java.lang.Integer">
		select
		count(id)
		from xl_comment
		where fid=#{0}  and ctype='forum'
	</select>



</mapper>

dao

package com.jff.xinli.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jff.xinli.bean.XlComment;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
@Mapper
public interface XlCommentMapper extends BaseMapper<XlComment> {
    List<XlComment> getlistByJoin(XlComment o);
    XlComment getIdByJoin(Integer id);
    void deleteByHfid(Integer hfId);

    void deleteByFid(Integer fid);
    Integer getCountByFid(Integer fid);
}

service

package com.jff.xinli.service;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jff.xinli.bean.XlComment;
import com.jff.xinli.dao.XlCommentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class XlCommentService extends ServiceImpl<XlCommentMapper, XlComment> {

    @Autowired
    XlCommentMapper commentMapper;

    public List<XlComment> getlistByJoin(XlComment o) {

        return  commentMapper.getlistByJoin(o);

    }
    public XlComment getIdByJoin(Integer id){
        return commentMapper.getIdByJoin(id);
    }

    public List<XlComment> getListByFid(Integer fid) {
        XlComment o=new XlComment();
        o.setFid(fid);
        return  commentMapper.getlistByJoin(o);
    }

    public List<XlComment> getListByHfid(Integer hfId) {
        if(hfId==null)return null;
        XlComment o=new XlComment();
        o.setHfId(hfId);
        o.setOrderby("id_desc");
        return  commentMapper.getlistByJoin(o);
    }

    public void deleteByHfid(Integer hfId){
        commentMapper.deleteByHfid(  hfId);
    }

    public void deleteByFid(Integer fid){
        commentMapper.deleteByFid(  fid);
    }

    public  Integer getCountByFid(Integer fid){
        return  commentMapper.getCountByFid(fid);
    }
}

controller

package com.jff.xinli.control.api;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jff.xinli.bean.XlComment;
import com.jff.xinli.bean.XlForum;
import com.jff.xinli.service.XlCommentService;
import com.jff.xinli.service.XlForumService;
import com.jff.xinli.util.DateUtils;
import com.jff.xinli.util.MessUntil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; 
import javax.annotation.Resource;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping("/comment")
public class XlCommentController {
	 
	@Resource
	XlCommentService commentService;
	@Resource
	XlForumService forumService;
	@RequestMapping("/page")
	public MessUntil page(@RequestParam(value="pageNo",defaultValue="1")int pageNo  , @RequestParam(value="pageSize",defaultValue="10")int pageSize  , XlComment o) {

		MessUntil mess=new MessUntil();
		PageHelper.startPage(pageNo, pageSize, " id desc ");
		List<XlComment> li=commentService.getlistByJoin(o);
		PageInfo<XlComment> pageInfo = new  PageInfo<XlComment>(li, pageSize);

		for(XlComment c:li){
			if(c.getHfId()==null||c.getHfId()==0){
				c.setHfli(commentService.getListByHfid(c.getId()));
			}
		}
		return mess.succ(pageInfo);
	}


	@RequestMapping("/save")
	public MessUntil save( XlComment o ) {

		MessUntil mess=new MessUntil();
		o.setCts(DateUtils.getNowDateTsString());
		commentService.save(o);

		if(o.getFid()!=null){
			int commentNum=commentService.getCountByFid(o.getFid());
			XlForum f=new XlForum();
			f.setId(o.getFid());
			f.setCommentNum(commentNum);
			forumService.updateById(f);
			return mess.succ(commentNum );
		}



		return mess.succ( );
	}

	@RequestMapping("/del")
	public MessUntil del( XlComment o )  {

		MessUntil mess=new MessUntil();
		o=commentService.getIdByJoin(o.getId());

		try {
			List<XlComment> hfli=commentService.getListByHfid(o.getId());
			if(hfli!=null&&hfli.size()>0){

				commentService.deleteByHfid(o.getId());
			}

			commentService.removeById(o.getId());

		} catch (Exception e) {

			return mess.error("删除失败,请先删除其关联信息");
		}


		if(o.getFid()!=null){
			int commentNum=commentService.getCountByFid(o.getFid());
			XlForum f=new XlForum();
			f.setId(o.getFid());
			f.setCommentNum(commentNum);
			forumService.updateById(f);
			return mess.succ(commentNum);
		}
		return mess.succ();



	}



}

vue 

admin

 <template>
    <div class="about">
        <v-header/>
        <v-sidebar/>
        <div class="content-box">
            <div class="content">
                <div>
                    <div class="crumbs">
                        <el-breadcrumb separator="/">
                            <el-breadcrumb-item>
                                <i class="el-icon-paperclip"></i> 评论管理
                            </el-breadcrumb-item>
                        </el-breadcrumb> 
                    </div>
                    <div class="container">
                        <div class="handle-box">
                            <el-input v-model="query.keywords" placeholder="评论内容,昵称"  style="width: 250px;"></el-input>



                            <el-button type="primary" icon="el-icon-search" @click="handleSearch">搜索</el-button>

                        </div>
                        <el-table   size="mini" :data="tableData" border class="table" ref="multipleTable"
                                  header-cell-class-name="table-header" >
                            <el-table-column  fixed="left"  prop="id" label="ID" width="60" align="center"></el-table-column>

                            <el-table-column  label="评论内容" prop="cont" align="center"  >
                                <template #default="scope">
                                    <div v-html="scope.row.context"></div>

                                </template></el-table-column>
                            <el-table-column  label="评论者" prop="userNickname" align="center" width="120"> </el-table-column>

                            <el-table-column label="头像" width="80" align="center">
                                <template #default="scope">
                                    <img :src="FILE_URL+ scope.row.faceimg" style="width: 30px;height: 30px;"/>


                                </template>
                            </el-table-column>



                            <el-table-column label="评论时间" prop="cts" align="center" width="180"></el-table-column>




                            <el-table-column label="操作" width="90" align="center" fixed="right">
                                <template #default="scope">

                                    <el-dropdown>
                                        <el-button  size="mini" type="primary">
                                            操作<i class="el-icon-arrow-down el-icon--right"></i>
                                        </el-button>
                                        <el-dropdown-menu slot="dropdown">


                                            <el-dropdown-item  @click.native="handleDelete(scope.$index, scope.row)">删除</el-dropdown-item>
                                        </el-dropdown-menu>
                                    </el-dropdown>

                                </template>
                            </el-table-column>
                        </el-table>
                        <div class="pagination">
                            <el-pagination
                                    @size-change="handleSizeChange"
                                    @current-change="handlePageChange"
                                    :current-page="query.pageNo"
                                    :page-sizes="[10,20,50,100, 200, 300, 400,500]"
                                    :page-size="query.pageSize"
                                    layout="total, sizes, prev, pager, next, jumper"
                                    :total="pageTotal">
                            </el-pagination>
                        </div>
                    </div>


                </div>
            </div>
        </div>



        <el-dialog :title="'查看 ' +detailObj.title+ ' 详情'"  :visible.sync="detailVisible"  >



            <el-card>
                 <h4 style="text-align: center;">{{detailObj.title}}</h4>
                <div style="margin-top: 30px;"></div>
                <div>[简介]{{detailObj.cdesc}}</div>
                <div style="margin-top: 30px;"></div>
                <div v-html="detailObj.context"></div>
            </el-card>



        </el-dialog>





    </div>
</template>

<script>
  

    import vHeader from "./Header.vue";
    import vSidebar from "./Sidebar.vue";
    import {
        comment_page,
        comment_del,

    } from '../../api';


    export default {
        name: "System",
        components: {
            vHeader,
            vSidebar,
        },
        data() {

            return {
                detailObj:{},
                detailVisible:false,


                FILE_URL:'',


                lander: {},
                FILE_URL: '',
                tableData: [],
                query: {

                    keywords: '',
                    pageNo: 1,
                    pageSize: 10,
                },
                pageTotal: 0,



            };
        },
        methods: {
            seedetail(row){
                this.detailVisible=true;
                this.detailObj=row;
            },
           

            handleSizeChange(val){
                this.query.pageNo = 1;
                this.query.pageSize=val;
                this.getPage();
            },

            // 查询操作
            handleSearch() {
                console.log(this.query)
                this.query.pageNo = 1;
                this.getPage();
            },

            // 分页导航
            handlePageChange(val) {
                this.query.pageNo = val;
                this.getPage();
            },



            //获取列表数据
            getPage() {

                comment_page(this.query).then((res) => {

                    this.tableData = res.data.obj.list
                    this.pageTotal = res.data.obj.total//该页总共多少条记录
                })
            },

            //删除操作
            handleDelete(index,row){

                // 二次确认删除
                this.$confirm("确定要删除吗?", "提示", {
                    type: "warning",
                })
                    .then(() => {
                        comment_del({id:row.id}).then((res) => {

                            if(res.data.status==1){
                                this.$message.success("删除成功");
                                this.tableData.splice(index, 1);
                                this.getPage();
                            }else{
                                this.$notify({
                                    title: '提示',
                                    message: res.data.msg,
                                    duration: 0
                                });
                            }

                        })

                    })
                    .catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消'
                        });
                    });


            },


        },
        mounted() {
            this.lander=JSON.parse(localStorage.loginUser)
            this.FILE_URL = process.env.VUE_APP_API_ROOT;
            if(this.lander.role=='psy')this.query.uid=this.lander.id;
            if(this.lander.role=='pt')this.query.uid=this.lander.id;

            //去后端查询所有的用户给tableData赋值
            this.getPage();


        }
    }
</script>

<style scoped>
    .handle-box {
        margin-bottom: 20px;
    }

    .handle-select {
        width: 120px;
    }

    .handle-input {
        width: 300px;
        display: inline-block;
    }

    .table {
        width: 100%;
        font-size: 14px;
    }

    .red {
        color: #ff0000;
    }

    .mr10 {
        margin-right: 10px;
        width: 120px;
    }

    /*滚动条的宽度*/
    /deep/ .el-table__body-wrapper::-webkit-scrollbar {
        width: 10px;
        height: 10px;
    }

    /*滚动条滑块*/
    /deep/ .el-table__body-wrapper::-webkit-scrollbar-thumb {
        background-color: #409eff;
        /*border-radius: 3px;*/
    }

    .mytip{
        padding: 20px; background-color: #fef0f0; color: #F56C6C;border-radius: 5px;font-size: 12px;margin: 10 0;
    }
</style>

qt---看文章管理

好博客就要一起分享哦!分享海报

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695