springboot+vue实现帖子功能-论坛

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

分类: springboot vue 专栏: springboot vue 常用功能 标签: springboot+vue实现帖子功能-论坛

2025-02-19 22:07:41 284浏览

springboot+vue实现帖子功能-论坛
-- ----------------------------
DROP TABLE IF EXISTS `xl_forum`;
CREATE TABLE `xl_forum`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `fname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标题',
  `fcont` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci COMMENT '内容',
  `cts` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '创建时间',
  `sh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '0待审核1通过-1不通过',
  `uid` int(0) DEFAULT NULL COMMENT '用户id',
  `imgs` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '图片集合',
  `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '不通过原因',
  `comment_num` int(0) DEFAULT NULL COMMENT '评论数量',
  `csee_num` int(0) DEFAULT NULL COMMENT '浏览量',
  `fdesc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '简介',
  `tid` int(0) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 135 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_forum")
public class XlForum {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer uid;
private Integer tid;
private Integer commentNum;
private Integer cseeNum;
private String fname;
private String fcont;
private String cts;
private String imgs;
private String sh;//0待审核1通过-1不通过
private String msg;
private String fdesc;//简介
/*---*/
@TableField(exist = false)
private String keywords;

@TableField(exist = false)
private String nickname;
@TableField(exist = false)
private String faceimg;
@TableField(exist = false)
private List<String> imgsli;
@TableField(exist = false)
private String tname;

}

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.XlForumMapper">

<sql id="field"> f.*,u.nickname ,u.faceimg,t.tname </sql>





<select id="getlistByJoin" resultType="com.jff.xinli.bean.XlForum" parameterType="com.jff.xinli.bean.XlForum">
select
<include refid="field"></include>
from xl_forum f
left join xl_users u on u.id=f.uid
left join xl_type t on t.id=f.tid

where 1=1
<if test="sh != null and sh!='' ">
and f.sh=#{sh}
</if>
<if test="uid != null ">
and f.uid = #{uid}
</if>
<if test="tid != null ">
and f.tid = #{tid}
</if>
<if test="keywords != null and keywords != ''">
and (

u.nickname like concat('%',#{keywords},'%')
or f.fname like concat('%',#{keywords},'%')
or f.fcont like concat('%',#{keywords},'%')
)
</if>

</select>


<select id="getByIdJoin" resultType="com.jff.xinli.bean.XlForum"
parameterType="java.lang.Integer">
select
<include refid="field"></include>
from xl_forum f
left join xl_users u on u.id=f.uid
left join xl_type t on t.id=f.tid

where f.id=#{0}
</select>



</mapper>

dao

package com.jff.xinli.dao;

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

import java.util.List;

@Component
@Mapper
public interface XlForumMapper extends BaseMapper<XlForum> {
List<XlForum> getlistByJoin(XlForum o);
XlForum getByIdJoin(Integer id);

}

service

package com.jff.xinli.service;

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

import java.util.List;

@Service
public class XlForumService extends ServiceImpl<XlForumMapper, XlForum> {

    @Autowired
    XlForumMapper forumMapper;

    public List<XlForum> getlistByJoin(XlForum o) {

        return  forumMapper.getlistByJoin(o);

    }
    public XlForum getByIdJoin(Integer id){
        return forumMapper.getByIdJoin(id);
    }


}


controller

package com.jff.xinli.control.api;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import com.github.pagehelper.PageInfo;
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.DocumentUntil;
import com.jff.xinli.util.MessUntil;
import com.jff.xinli.util.UploadFile;
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 com.github.pagehelper.PageHelper;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;


@CrossOrigin
@RestController
@RequestMapping("/forum")
public class XlForumController {
	 
	@Resource
	XlForumService forumService;
	@Resource
	XlCommentService commentService;
	 
	 
	@RequestMapping("/page")
	public MessUntil page(@RequestParam(value="pageNo",defaultValue="1")int pageNo  , @RequestParam(value="pageSize",defaultValue="10")int pageSize  ,
						  XlForum o)  {
		MessUntil mess=new MessUntil();

		
		PageHelper.startPage(pageNo, pageSize," id desc ");
    	 List<XlForum> li=forumService.getlistByJoin(o);
    	 PageInfo<XlForum> pageInfo = new  PageInfo<XlForum>(li, pageSize);

    	 for(XlForum f:pageInfo.getList()){
    	 	f.setImgsli(strToList(f.getImgs()));
		 }



		return mess.succ(pageInfo);
	} 
	
	
	@RequestMapping("/detail")
	public MessUntil detail( XlForum o)  {
		MessUntil mess=new MessUntil();
		o=forumService.getByIdJoin(o.getId());
		if(o!=null && o.getSh()!=null&& o.getSh().equals("1")) {
			XlForum n=new XlForum();
			n.setId(o.getId());
			n.setCseeNum(o.getCseeNum()+1);
			forumService.updateById(n);

			return mess.succ(o) ;
		}
		return  mess.error("该数据不存在或待审核");
	}


	private String getimgs(String cont){
		List<String> li= DocumentUntil.getIimgs(cont);
		String p="";
		for(String img:li){
			p+=img+",";
		}
		if(p.lastIndexOf(",")>-1)p=p.substring(0,p.length()-1);
		return p;

	}
	@RequestMapping("/save")
	public MessUntil save( XlForum o,Integer jf)  {
		MessUntil mess=new MessUntil();

		if(o.getId()!=null){
			XlForum ol=forumService.getById(o.getId());
			if(ol.getSh().equals("-1"))o.setSh("1");

			o.setImgs(getimgs(o.getFcont()));
			o.setFdesc(DocumentUntil.getP(o.getFcont(),200));


			forumService.updateById(o);
		}else {
			o.setSh("1");
			o.setCts(DateUtils.getNowDateTsString());
			o.setImgs(getimgs(o.getFcont()));
			o.setFdesc(DocumentUntil.getP(o.getFcont(),200));

			o.setCommentNum(0);
			o.setCseeNum(0);


			forumService.save(o);

		}

		return  mess.succ();
	}
	@RequestMapping("/update")
	public MessUntil update( XlForum o)  {
		MessUntil mess=new MessUntil();

			forumService.updateById(o);


		return  mess.succ();
	}
	@RequestMapping("/del")
	public MessUntil del( Integer id)  {
		MessUntil mess=new MessUntil();
		try{

			XlForum ol=forumService.getByIdJoin(id);

			commentService.deleteByFid(id);
			forumService.removeById(id);




		}catch (Exception e){
			e.printStackTrace();
			return  mess.error("删除失败,请先删除关联信息");

		}
		return  mess.succ();
	}
	private List<String> strToList(String imgs){
		List<String> imgli=new ArrayList<>();
		if(imgs !=null&&imgs.trim().length()>0){
			String[] arr=imgs.split(",");
			for(String img:arr){
				if(img!=null&&img.trim().length()>0){
					imgli.add(img);
				}
			}
		}
		return imgli;
	}



}

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-s-home"></i>
                                帖子管理


                            </el-breadcrumb-item>
                        </el-breadcrumb>
                    </div>
                    <div class="container">
                        <div class="handle-box">

                            <el-input placeholder="标题,内容,作者昵称" style="width:250px;"  v-model="query.keywords"></el-input>

                            <el-select   placeholder="请选择分类" v-model="query.tid" filterable>
                                <el-option    label="请选择分类"  value=""></el-option>
                                <el-option v-for="(t,i) in typeli" :label="t.tname" :value="t.id"></el-option>
                            </el-select>
                            <el-select    v-model="query.sh" placeholder="请选择状态" >
                                <el-option label="请选择状态" value=""></el-option>
                                <el-option label="待审核" value="0"></el-option>
                                <el-option label="审核通过" value="1"></el-option>
                                <el-option label="审核不通过" value="-1"></el-option>
                            </el-select>

                            <el-button type="primary" @click="searchHandle">查找</el-button>
                            <el-button  type="danger" @click="addHandle">发布帖子</el-button>



                        </div>
                        <el-card  style="margin-bottom: 10px;" class="box-card" v-for="(t,i) in tableData" >
                            <div slot="header" class="clearfix">
                                <span>{{t.fname}}</span>&nbsp;
                                <el-tag type="info" v-if="t.sh=='0'">待审核</el-tag>
                                <el-tag type="danger" v-if="t.sh=='-1'">不通过</el-tag>
                                <el-tag type="success" v-if="t.sh=='1'">审核通过</el-tag>
                                <span v-if="t.sh=='-1'" style="color: red">({{t.msg}})</span>


                                <el-button  v-if="lander.id==t.uid"  style="float: right;" size="mini" type="danger"  @click="delHandle(t)">删除</el-button>
                                <el-button   v-if="lander.id==t.uid"   style="float: right;" size="mini" type="success"  @click="editHandle(t)">编辑</el-button>
                                <el-button v-if="lander.role=='admin'"   style="float: right;" size="mini" type="warning"  @click="seeinfoHandle(t)">审核</el-button>


                            </div>
                            <div  class="hh">




                                        {{t.fdesc}}..<span @click="seeinfoHandle(t)" style="color:blue;font-size: 12px;">【查看详情】</span>
                                        <br>
                                        <br>

                                <div style="flex-direction:row;display: flex;">
                                    <div v-for="(t2,i2) in t.imgsli" style="width: 100px;height: 100px;overflow: hidden;border-radius: 10px;background-color: #f3f3f3;margin: 1px;">
                                        <img :src="t2" style="width: 100px;height: 100px; ">
                                    </div>
                                </div>


                                        <br>
                                        <div >
                                            <img :src="FILE_URL+t.faceimg" style="width: 30px;height:30px;border-radius: 50%;float: left;">
                                            <span style="font-size: 13px;color: #666;line-height: 30px;margin-left: 5px;">{{t.nickname}}  &nbsp;&nbsp;{{t.cts}}发布 &nbsp;&nbsp;, &nbsp;&nbsp;分类:{{t.tname}}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{t.commentNum}}评论 &nbsp;&nbsp;&nbsp;&nbsp;{{t.cseeNum}}浏览</span>
                                        </div>





                            </div>
                        </el-card>

                        <div v-if="tableData.length==0" style="text-align:center;">
                            <br>
                            <br>
                            <img src="../../assets/img/nosj.png">
                            <br>
                            <br>
                            暂无数据
                            <br>
                            <br>
                        </div>





                        <el-pagination v-else
                                       :page-sizes="[10,20,50,100,500]"
                                       @size-change="handleSizeChange"
                                       @current-change="handleCurrentChange"
                                       :current-page.sync="query.pageNo"
                                       :page-size="query.pageSize"
                                       layout="total, sizes, prev, pager, next, jumper"
                                       :total="total">
                        </el-pagination>
                    </div>




                </div>
            </div>
        </div>
        <el-dialog   title="查看 " fullscreen   :visible.sync="infoVisible"    >
            <h1 style="text-align: center;">{{infoObj.fname}}</h1>
            <div  class="hh" style="padding: 50px 10%;">
                <br>
                <div>
                    <img :src="FILE_URL+infoObj.faceimg" style="width: 30px;height:30px;border-radius: 50%;float: left;">
                    <span style="font-size: 13px;color: #666;line-height: 30px;margin-left: 5px;">{{infoObj.nickname}}  &nbsp;&nbsp;{{infoObj.cts}}发布 &nbsp;&nbsp;, &nbsp;&nbsp;分类:{{infoObj.tname}}
                    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{infoObj.commentNum}}评论 &nbsp;&nbsp;&nbsp;&nbsp;{{infoObj.cseeNum}}浏览</span>
                </div>
                <el-divider></el-divider>
                <br>

                <div v-html="infoObj.fcont"></div>
                <br>
                <br>


                <br>
                <div style="text-align: center;" v-if="lander.role=='admin'">
                    <el-divider></el-divider>
                    <el-button type="danger" @click="savestate(-1)">审核不通过</el-button>
                    <el-button type="primary" @click="savestate(1)">审核通过</el-button>

                </div>
            </div>
        </el-dialog>

        <el-dialog  :title="(ruleForm.id?'编辑':'添加') " fullscreen   :visible.sync="addVisible"    >


            <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="120px" class="demo-ruleForm">

                <el-form-item label="标题" prop="fname">
                    <el-input v-model="ruleForm.fname"></el-input>

                </el-form-item>

                <el-form-item label="分类" prop="tid">
                    <el-select v-model="ruleForm.tid" filterable>
                        <el-option v-for="(t,i) in typeli" :label="t.tname" :value="t.id"></el-option>
                    </el-select>
                </el-form-item>

                <el-form-item label="内容"   >
                    <quill-editor ref="myQuillEditor" v-model="ruleForm.fcont"  :options="editorOption"  />
                </el-form-item>




            </el-form>
            <span slot="footer" class="dialog-footer">
            <el-button @click="addVisible = false">取 消</el-button>
            <el-button type="primary" @click="submitForm">确 定</el-button>
          </span>
        </el-dialog>
    </div>
</template>

<script>
    import { quillEditor,Quill} from 'vue-quill-editor'
    import {container, ImageExtend, QuillWatch} from 'quill-image-extend-module'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    Quill.register('modules/ImageExtend', ImageExtend)
    import '../../api/image-paste.min.js';
    let  CON_ACTION=process.env.VUE_APP_API_ROOT+'/common/upimg?type=forum_detail';


    import vHeader from "./Header.vue";
    import vSidebar from "./Sidebar.vue";
    import {
        forum_page,
        forum_add,
        forum_del, type_list,
        forum_update,
    } from '../../api/index'

    export default {
        name: "users",
        components: {
            vHeader,
            vSidebar,
            quillEditor
        },
        data() {
            return {
                FILE_URL:'',

                typeli:[],
                infoVisible:false,
                infoObj:{},

                lander:{},


                query:{
                    pageNo:1,
                    pageSize:10,
                    keywords:'',
                    sh:'',

                },
                total:0,
                tableData:[],
                addVisible: false,

                ruleForm: {
                    fname: '',
                    tid: '',
                    fcont: '',


                },
                rules: {
                    fname: [  {required: true, message: '请输入', trigger: 'blur'},   ],
                    tid: [  {required: true, message: '请输入', trigger: 'blur'},   ],

                    fcont: [  {required: true, message: '请输入', trigger: 'blur'},   ],


                },
                editorOption: {
                    modules: {

                        /* 还有一些其他的模块*/
                        imagePaste: {
                            addImageBlob: function (blob, callback) {
                                var formData = new FormData()
                                formData.append('file', blob)
                                // your upload function, get the uploaded image url, add then
                                let config = {
                                    headers: {
                                        "Content-Type": "multipart/form-data",
                                        "Accept": "*/*"
                                    }

                                }
                                // 上传接口
                                axios.post(CON_ACTION, formData, config).then(res => {
                                    console.log(res);
                                    let imgUrl = res.data.obj // 服务器返回的图片url
                                    callback(imgUrl)

                                })
                            }
                        },

                        ImageExtend: { // 如果不作设置,即{}  则依然开启复制粘贴功能且以base64插入
                            loading: true,//可选参数 是否显示上传进度和提示语
                            name: 'file', // 图片参数名
                            size: 3, // 可选参数 图片大小,单位为M,1M = 1024kb
                            action: CON_ACTION, // 服务器地址, 如果action为空,则采用base64插入图片
                            // response 为一个函数用来获取服务器返回的具体图片地址
                            // 例如服务器返回{code: 200; data:{ url: 'baidu.com'}}
                            // 则 return res.data.url
                            response: res => {
                                return res.obj;
                            },
                            // headers: xhr => {
                            // 上传图片请求需要携带token的 在xhr.setRequestHeader中设置
                            // xhr.setRequestHeader(
                            //     "Authorization",
                            //     this.getCookie("usefname")
                            //     ? this.getCookie("usefname").token_type +
                            //         this.getCookie("usefname").access_token
                            //     : "Basic emh4eTp6aHh5"
                            // );
                            // }, // 可选参数 设置请求头部
                            sizeError: () => {
                            }, // 图片超过大小的回调
                            start: () => {
                            }, // 可选参数 自定义开始上传触发事件
                            end: () => {
                            }, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
                            error: () => {
                            }, // 可选参数 上传失败触发的事件
                            success: () => {
                            }, // 可选参数  上传成功触发的事件
                            // change: (xhr, formData) => {
                            // xhr.setRequestHeader('myHeader','myValue')
                            // formData.append('token', 'myToken')
                            // } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
                        },
                        toolbar: {

                            container: container,
                            handlers: {
                                'image': function () {
                                    QuillWatch.emit(this.quill.id)
                                }
                            }

                        }
                    },
                    //主题
                    theme: "snow",
                    placeholder: "请输入正文"

                },



            };
        },
        methods:{
            savestate( sh){
                if(sh=='1'){
                    forum_update({id: this.infoObj.id,sh:sh,msg:''}).then((res) => {
                        let data = res.data;
                        if(data.status==1){
                            this.$message.success(data.msg);
                            this.getPage();
                            this.infoVisible=false;
                        }else{
                            this.$message.error(data.msg);
                        }

                    })

                }else{
                    this.$prompt('请输入审核不通过 的原因', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                    }).then(({ value }) => {
                        forum_update( { id:this.infoObj.id,sh:sh,msg:value } ).then((res)=>{
                            this.getPage();
                            this.infoVisible=false;
                        })
                    }).catch((e) => {
                        console.log(e)
                        this.$message({
                            type: 'info',
                            message: '取消输入'
                        });
                    });
                }
            },
            seeinfoHandle(t) {
                this.infoVisible=true;
                this.infoObj=t;

                if( this.infoObj.fcont!=null){
                    this.infoObj.fcont=  this.infoObj.fcont.replace(/<img/g,"<img style='max-width:100%;height:auto;'");;
                }
            },


            searchHandle(){
                this.query.pageNo=1;
                this.getPage();
            },
            handleSizeChange(val) {
                this.query.pageSize=val;
                this.query.pageNo=1;
                this.getPage();
            },
            handleCurrentChange(val) {
                this.query.pageNo=val;
                this.getPage();
            },
            getPage(){
                forum_page( this.query ).then((res)=>{
                    let data=res.data;
                    this.tableData=data.obj.list;
                    this.total=data.obj.total;
                })
            },


            addHandle(){
                this.ruleForm={};
                this.addVisible=true;

                this.ruleForm.uid=this.lander.id;

                this.ruleForm.ntype =this.query.ntype;


            },
            editHandle(row){
                this.ruleForm.id=row.id;
                this.ruleForm.fname=row.fname;

                this.ruleForm.tid=row.tid;



                if(row.fcont!=null){
                    this.ruleForm.fcont= row.fcont.replace(/<img/g,"<img style='max-width:100%;height:auto;'");;
                }






                this.addVisible=true;
            },

            delHandle(row) {
                this.$confirm('确定删除?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    forum_del({id: row.id}).then((res) => {
                        let data = res.data;
                        if(data.status==1){

                            this.getPage();
                        }else{
                            this.$message.error(data.msg);
                        }

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


            submitForm() {
                this.$refs.ruleForm.validate((valid) => {
                    if (valid) {


                        forum_add(this.ruleForm).then((res)=>{

                            let data=res.data;
                            if(data.status==1){

                                this.addVisible=false;

                                this.getPage();
                            }else{
                                this.$message.error(data.msg);
                            }

                        })
                    } else {
                        this.$message.info("请按要求输入")
                        return false;
                    }
                });
            },


            gettypeli(){

                type_list( {ttype:'forum'} ).then((res)=>{
                    let data=res.data;
                    this.typeli=data.obj ;

                })
            },


        },
        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;
            this.getPage();
            this.gettypeli();





        },

    }
</script>

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


    .hh{ word-wrap: break-word; word-break:break-all }
</style>


qt

<template>
    <div>
        <!-- section begin -->
        <section id="de-subheader" class="mt-sm-60 pt20 pb20 bg-gradient-45-deg text-light">
            <div class="container relative z-index-1000">
                <div class="row align-items-center">
                    <div class="col-lg-6">
                        <h3 class="mb-0"></h3>
                    </div>

                    <div class="col-lg-6 text-lg-end">
                        <ul class="crumb">
                            <li><router-link to="/Index">首页</router-link></li>
                            <li class="active">论坛</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
        <!-- section close -->
        <div style="width:80%;margin-left:10%;margin-top:50px;">
            <el-row>
                <el-col :span="4"  >
                    <div @click="searchbytid('')" :class="'typeitem ' +(query.tid==''?'typeitemsel':'')">
                        全部
                    </div>
                </el-col>
                <el-col :span="4" v-for="(t,i) in tli">
                    <div @click="searchbytid(t.id)" :style="'background-image:url('+FILE_URL+t.timg+');background-size:100% 100%;'"
                         :class="'typeitem ' +(query.tid==t.id?'typeitemsel':'')">
                       <span> {{t.tname}}</span>
                    </div>
                </el-col>
            </el-row>
            <br>
            <br>
            <br>

            <!--/content-inner-section-->
            <div class="row" >
                <div class="col-md-8 ">
                    <el-row>
                        <el-col :span="20">
                            <el-input  v-model="query.keywords"   placeholder="请输入标题,昵称,内容" type="text"/>

                        </el-col>
                        <el-col :span="4">
                            <el-button icon="el-icon-search"  type="success" @click="handleSearch"> 搜索</el-button>

                        </el-col>
                    </el-row>
                    <br>




                    <div class="zwsj" v-if="tableData.length==0">

                        <img style="width:50%" src="../../assets/img/notz.png">
                        <br>
                        <br>
                        <br>
                    </div>

                    <el-row  v-for="(t,i) in tableData" >
                        <el-col :span="4">
                            <router-link :to="'/QtForumDetail?id='+t.id" target="_blank" title="w3ls" rel="author"><img :src="FILE_URL+t.faceimg" alt="" class="txx"></router-link>

                        </el-col>
                        <el-col :span="20">
                            <h5 class="hh"><router-link :to="'/QtForumDetail?id='+t.id" target="_blank">{{t.fname}}</router-link></h5>
                            <p class="hh">{{t.fdesc}}...<router-link :to="'/QtForumDetail?id='+t.id" target="_blank" style="color: blue">详情</router-link></p>
                            <div class="imgsdiv" v-if="t.imgsli!=null&&t.imgsli.length>0">
                                <div class="imgsitem" v-for="(t2,i2) in t.imgsli" v-if="i2<4"><router-link :to="'/QtForumDetail?id='+t.id" target="_blank"><img :src="t2"></router-link></div>
                            </div>
                            <div class="clearfix"></div>
                            <div class="agile-post">
                                <router-link :to="'/QtForumDetail?id='+t.id" target="_blank"  style="color: #f40;">{{t.nickname}}</router-link> 于 {{t.cts}} 发布 <router-link :to="'/QtForumDetail?id='+t.id" target="_blank">{{t.commentNum}}
                                评论</router-link>,{{t.cseeNum}}浏览,{{t.tname}}
                                <el-button @click="delForum(t)" v-if="lander!=null&&lander.id==t.uid" style="color: red;float:right;" type="text"><i class="el-icon-delete"></i>删除</el-button>

                            </div>
                            <hr>
                        </el-col>
                    </el-row>


                    <div class="pagination"  v-if="tableData.length>0">
                        <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>

                    <el-card id="fatiediv">
                        <div slot="header" class="clearfix">
                            <span>发布帖子</span>
                        </div>
                        <div>
                            <el-form
                                    label-width="70px"
                                    :model="dataForm"
                                    :rules="dataFormRule"
                                    ref="dataForm"
                            >
                                <el-form-item label="标题" prop="fname"  >
                                    <el-input   v-model="dataForm.fname" ></el-input>
                                </el-form-item>
                                <el-form-item label="内容" prop="fcont"  >
                                    <quill-editor ref="myQuillEditor" v-model="dataForm.fcont"  :options="editorOption" />
                                </el-form-item>
                                <el-form-item label="交流圈" prop="tid"  v-if="query.tid==''">
                                    <el-select filterable   v-model="dataForm.tid" >

                                        <el-option  v-for="t in tli"
                                                    :key="t.id"
                                                    :label="t.tname"
                                                    :value="t.id"></el-option>
                                    </el-select>
                                </el-form-item>

                            </el-form>
                            <div style="padding-left:100px;">
                                <el-button v-if="islogin==1" type="primary" @click="saveEdit">确 定 发 布</el-button>
                                <el-button v-else type="primary" @click="gologin">请登录</el-button>



                            </div>
                        </div>


                    </el-card>



                </div>
                <div class="col-md-4 ">

                    <div>
                        <table style="width: 100%;text-align: center;">
                            <tr>
                                <td> <el-button style="width:90%" type="danger" @click="fatie()">发布帖子</el-button></td>
                                <td>
                                    <el-button @click="manageForum" style="width: 90%" type="success" v-if="islogin==1">管理帖子</el-button>
                                    <el-button @click="needlogin" style="width: 90%" type="success" v-else>管理帖子</el-button>
                                </td>
                            </tr>
                        </table>
                    </div>
                    <br>
                    <br>
                    <h4 >最新评论</h4>


                    <table v-for="(t,i) in cList" width="100%" style="border-bottom: 1px solid #f3f3f3;margin-bottom: 10px;margin-top: 10px;">
                        <tr>
                            <td width="60px;"> <img :src="FILE_URL+t.faceimg" class="pftx"></td>
                            <td class="hh">{{t.userNickname}}<small style="float: right;">{{t.cts}}</small><div style="font-size: 12px;color: #666666;" v-html="t.context"></div> </td>
                        </tr>
                    </table>



                    <p  class="zwsj" v-if="cList.length==0">
                        <br>
                        <img style="width: 50%" src="../../assets/img/nopj.png">
                        <br>
                        暂无评论
                        <br>
                    </p>


                    <div class="clearfix"></div>

                </div>
                <div class="clearfix"></div>
            </div>
            <!--//content-inner-section-->

        </div>


    </div>

</template>

<script>
    import { quillEditor,Quill} from 'vue-quill-editor'
    import {container, ImageExtend, QuillWatch} from 'quill-image-extend-module'
    import 'quill/dist/quill.core.css'
    import 'quill/dist/quill.snow.css'
    import 'quill/dist/quill.bubble.css'
    Quill.register('modules/ImageExtend', ImageExtend)
    import '../../api/image-paste.min.js';

    let  CON_ACTION=process.env.VUE_APP_API_ROOT+'/common/upimg?type=forum_detail';

    import {
        forum_add,
        forum_page,
        comment_page,
        forum_del,
        type_list
    } from '../../api';
    export default {
        name: "Index",
        components: {
            quillEditor,
        },
        data() {

            return {

                islogin:0,




                cList:[],


                lander:{},
                FILE_URL : '',


                tli: [],
                tableData: [],
                query: {
                    tid: '',
                    keywords: '',
                    pageNo: 1,
                    pageSize: 10,
                    sh:1,
                },
                pageTotal: 0,


                dataForm: {
                    fname: '',
                    fcont:'',
                    tid:'',

                },
                dataFormRule: {
                    fname: [{required: true, message: '不能为空', trigger: 'blur'}],
                    tid: [{required: true, message: '不能为空', trigger: 'blur'}],
                },

                editorOption: {
                    modules: {

                        /* 还有一些其他的模块*/
                        imagePaste: {
                            addImageBlob: function (blob, callback) {
                                var formData = new FormData()
                                formData.append('file', blob)
                                // your upload function, get the uploaded image url, add then
                                let config = {
                                    headers: {
                                        "Content-Type": "multipart/form-data",
                                        "Accept": "*/*"
                                    }

                                }
                                // 上传接口
                                axios.post(CON_ACTION, formData, config).then(res => {
                                    console.log(res);
                                    let imgUrl = res.data.obj // 服务器返回的图片url
                                    callback(imgUrl)

                                })
                            }
                        },

                        ImageExtend: { // 如果不作设置,即{}  则依然开启复制粘贴功能且以base64插入
                            loading: true,//可选参数 是否显示上传进度和提示语
                            name: 'file', // 图片参数名
                            size: 3, // 可选参数 图片大小,单位为M,1M = 1024kb
                            action: CON_ACTION, // 服务器地址, 如果action为空,则采用base64插入图片
                            // response 为一个函数用来获取服务器返回的具体图片地址
                            // 例如服务器返回{code: 200; data:{ url: 'baidu.com'}}
                            // 则 return res.data.url
                            response: res => {
                                return res.obj;
                            },
                            // headers: xhr => {
                            // 上传图片请求需要携带token的 在xhr.setRequestHeader中设置
                            // xhr.setRequestHeader(
                            //     "Authorization",
                            //     this.getCookie("username")
                            //     ? this.getCookie("username").token_type +
                            //         this.getCookie("username").access_token
                            //     : "Basic emh4eTp6aHh5"
                            // );
                            // }, // 可选参数 设置请求头部
                            sizeError: () => {
                            }, // 图片超过大小的回调
                            start: () => {
                            }, // 可选参数 自定义开始上传触发事件
                            end: () => {
                            }, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
                            error: () => {
                            }, // 可选参数 上传失败触发的事件
                            success: () => {
                            }, // 可选参数  上传成功触发的事件
                            // change: (xhr, formData) => {
                            // xhr.setRequestHeader('myHeader','myValue')
                            // formData.append('token', 'myToken')
                            // } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
                        },
                        toolbar: {

                            container: container,
                            handlers: {
                                'image': function () {
                                    QuillWatch.emit(this.quill.id)
                                }
                            }

                        }
                    },
                    //主题
                    theme: "snow",
                    placeholder: "请输入正文"

                },

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

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

                        })

                    })
                    .catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消'
                        });
                    });
            },
            gologin(){
                this.$router.push('/Login');
            },
            needlogin(){
                this.$message.info('请登录')
            },
            manageForum(){
                this.$router.push('/Forum');
            },
            fatie(){
                window.location='#fatiediv';
            },
            saveEdit() {

                if(this.islogin==0){
                    this.$message.error('请登录');
                    return  ;
                }
                if (this.$refs.myQuillEditor.value == ''||this.dataForm.fcont.trim().length==0) {
                    this.$message.error('请输入内容');
                    return  ;
                }
                this.dataForm.uid=this.lander.id;

                this.$refs.dataForm.validate(valid => {
                    //表单验证失败
                    if (!valid) {

                        //提示语
                        this.$message.error("请按提示填写表单");
                        return false;
                    } else {

                        this.loading = this.$loading({
                            lock: true,
                            text: "发布中,请稍等,,,,",
                            spinner: "el-icon-loading",
                            background: "rgba(0, 0, 0, 0.5)",
                        });
                        forum_add(this.dataForm).then((res) => {
                            this.loading.close();
                            if(res.data.status==1){
                                this.query.pageNo=1;
                                this.getPage();

                                if(res.data.obj!=null&&res.data.obj>0&&this.vobj!=null&&this.vobj.forumNum!=undefined){
                                    this.vobj.forumNum=res.data.obj;
                                }

                                this.dataForm.fname='';
                                this.dataForm.fcont='';
                                this.$message.success("已发布")
                            }else{
                                this.$message.error(res.data.msg)
                            }

                        })
                    }
                })
            },
            gettypeli(){
                type_list({ttype:'forum'}).then((res) => {
                    this.tli = res.data.obj
                })
            },
            getPage() {
                forum_page(this.query).then((res) => {
                    this.tableData = res.data.obj.list
                    this.pageTotal = res.data.obj.total//该页总共多少条记录
                })
            },
            handleSizeChange(val){
                this.query.pageNo = 1;
                this.query.pageSize=val;
                this.getPage();
            },

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

            // 分页导航
            handlePageChange(val) {
                this.query.pageNo = val;
                this.getPage();
            },
            getCPage(){
                comment_page({pageNo:1,pageSize:30,ctype:'forum',tid:this.query.tid}).then((res) => {
                    if(res.data.status==1){
                        this.cList=res.data.obj.list;
                    }
                })
            },
            searchbytid(tid){
                this.query.tid=tid;
                this.dataForm.tid=tid;
                this.query.pageNo=1;
                this.query.keywords='';
                this.getPage();
                this.getCPage();
            }

        },
        mounted() {
            this.FILE_URL=process.env.VUE_APP_API_ROOT;

            try{
                this.lander=JSON.parse(localStorage.loginUser);
                this.islogin=1;
            }catch (e) {
                this.islogin=0;
            }
            this.gettypeli();

            this.getPage();
            this.getCPage();

        },
        watch:{
            $route:function(value){


            }
        }
    }
</script>

<style scoped>
    .sel{color: darkgreen;font-weight: bolder;}
    .imgsdiv{height: 120px;}
    .imgsdiv .imgsitem{width: 100px;
        overflow: hidden;
        height: 100px;float: left;margin-right: 10px;background: #dddddd;text-align: center;border-radius: 5px;}
    .imgsdiv .imgsitem img{ width: 100%; height: 100%;}
    .txx{width: 90px;height: 90px;border-radius: 50%;}
    .pftx{width: 50px;height: 50px;border-radius: 50%;margin-right: 10px; }
    .agile-post{font-size: 12px;color: #666;}
    .zwsj{text-align: center;}

    .typeitem{
        width:150px;
        height:150px;
        line-height:150px;
        background-color: #7df374;
        border-radius: 50%;
        border:3px dotted #ddd;
        margin:5px auto  ;
        text-align: center;
        cursor: pointer;
    }
    .typeitem span{  background-color: rgba(0,0,0,0.5);color: #fff; padding: 10px;font-size: 13px;}
    .typeitemsel{

        border:3px dotted darkgreen;

    }
    .typeitemsel span{
        background-color: rgba(0,0,0,0.8);color: #fff; padding: 10px;

    }
</style>

详情


<template>
<div>
<!-- section begin -->
<section id="de-subheader" class="mt-sm-60 pt20 pb20 bg-gradient-45-deg text-light">
<div class="container relative z-index-1000">
<div class="row align-items-center">
<div class="col-lg-6">
<h3 class="mb-0"></h3>
</div>

<div class="col-lg-6 text-lg-end">
<ul class="crumb">
<li><router-link to="/Index">首页</router-link></li>
<li class="active">{{obj.fname}}</li>
</ul>
</div>
</div>
</div>
</section>
<!-- section close -->
<div class="container" >

<el-row>
<el-col :span="16">


<table style="width: 100%;margin-top: 30px;margin-bottom: 30px;">
<tr>
<td valign="top" class="td td1 hh">
<img class="touxx" :src="FILE_URL+obj.faceimg">
<br>
<el-tag size="mini" type="danger">作者</el-tag>
<br>
<p>{{obj.nickname}}</p>

</td>
<td class="td hh">
<h1>{{obj.fname}}</h1>
<br>
<div v-html="obj.fcont"></div>

<div>
<hr>
<div class="row actions">

<div class="col-sm-6">发布时间 &nbsp; &nbsp; &nbsp;{{obj.cts}}</div>
<div class="col-sm-2">浏览 &nbsp; &nbsp;{{obj.cseeNum}}</div>
<div class="col-sm-2">评论 &nbsp; &nbsp;{{obj.commentNum}}</div>
<div class="col-sm-2"><el-button @click="delForum()" v-if="lander!=null&&lander.id==obj.uid" style="color: red;" type="text"><i class="el-icon-delete"></i>删除</el-button></div>

</div>
</div>

</td>

</tr>
<tr v-for="(t,i) in tableData">
<td valign="top" class="td td1 hh">
<img class="touxx" :src="FILE_URL+t.faceimg">
<br>
<el-tag v-if="t.uid==obj.uid" size="mini" type="danger">作者</el-tag>
<br>
<p>{{t.userNickname}}</p>

</td>
<td class="td hh">
<div v-html="t.context"></div>
<br>
<div>
<hr>
<div class="row actions">

<div class="col-sm-6">评论时间 &nbsp; &nbsp; &nbsp;{{t.cts}}</div>
<div class="col-sm-2">回复 &nbsp; &nbsp;{{t.hfli!=null?t.hfli.length:'0'}}</div>
<div class="col-sm-2"><el-button @click="replyC(t,i)" v-if="lander!=null " style="color: green;" type="text"><i class="el-icon-news"></i>回复</el-button></div>
<div class="col-sm-2"><el-button @click="delC(t,i)" v-if="lander!=null&&lander.id==t.uid" style="color: red;" type="text"><i class="el-icon-delete"></i>删除</el-button></div>

</div>
</div>
<div v-if="t.hfli!=null&&t.hfli.length>0">
<div v-for="(t2,i2) in t.hfli" v-if="i2<5" class="ritem">
<p><img class="xtxx" :src="FILE_URL+t2.faceimg">
<span style="color: blue">{{t2.userNickname}}</span>
<el-tag v-if="t2.uid==obj.uid" size="mini" type="danger">作者</el-tag>
回复
<img class="xtxx" :src="FILE_URL+t2.uhFaceimg">
<span style="color: blue">{{t2.uhUserNickname}}</span>
<el-tag v-if="t2.hfUid==obj.uid" size="mini" type="danger">作者</el-tag>
</p>
<div style="padding: 20px;" v-html="t2.context"></div>
<hr>
<div class="row actions">

<div class="col-sm-8">回复时间 &nbsp; &nbsp; &nbsp;{{t2.cts}}</div>
<div class="col-sm-2"><el-button @click="replyC(t,i)" v-if="lander!=null&&lander.id==t2.uid" style="color: green;" type="text"><i class="el-icon-news"></i>回复</el-button></div>
<div class="col-sm-2"><el-button @click="delC(t2,i2)" v-if="lander!=null&&lander.id==t2.uid" style="color: red;" type="text"><i class="el-icon-delete"></i>删除</el-button></div>

</div>
</div>
<div v-for="(t2,i2) in t.hfli" v-if="i2>=5&&t.showsy" class="ritem">
<p><img class="xtxx" :src="FILE_URL+t2.faceimg">
<span style="color: blue">{{t2.userNickname}}</span>
<el-tag v-if="t2.uid==obj.uid" size="mini" type="danger">作者</el-tag>
回复
<img class="xtxx" :src="FILE_URL+t2.uhFaceimg">
<span style="color: blue">{{t2.uhUserNickname}}</span>
<el-tag v-if="t2.hfUid==obj.uid" size="mini" type="danger">作者</el-tag>
</p>
<div style="padding: 20px;" v-html="t2.context"></div>
<hr>
<div class="row actions">

<div class="col-sm-8">回复时间 &nbsp; &nbsp; &nbsp;{{t2.cts}}</div>
<div class="col-sm-2"><el-button @click="replyC(t,i)" v-if="lander!=null&&lander.id==t2.uid" style="color: green;" type="text"><i class="el-icon-news"></i>回复</el-button></div>
<div class="col-sm-2"><el-button @click="delC(t2,i2)" v-if="lander!=null&&lander.id==t2.uid" style="color: red;" type="text"><i class="el-icon-delete"></i>删除</el-button></div>

</div>
</div>
<div @click="t.showsy=!t.showsy" class="zwsj" v-if="t.hfli.length-5>0">{{t.showsy?'隐藏':'查看'}}剩余{{t.hfli.length-5}}条数据</div>


</div>
</td>

</tr>
</table>
<div class="pagination" v-if="tableData.length>0">
<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 class="all-comments-info">
<h5>发布评论</h5>
<div class="agile-info-wthree-box">


<div class="col-md-12 form-info">

<quill-editor ref="myQuillEditor" v-model="context" :options="editorOption" />
<br>
<el-button @click="saveC()" type="success" >发布评论</el-button>

</div>
<div class="clearfix"> </div>

<br>
<br>
<br>



</div>
</div>


</el-col>
<el-col :span="8" >

<br>

<div style="border: 1px solid #ddd;padding: 10px;margin-left: 10px;">

<h4 >最新帖子</h4>
<br>

<table v-for="(t,i) in lastforumli" width="100%" style="border-bottom: 1px solid #f3f3f3;margin-bottom: 10px;margin-top: 10px;">
<tr>
<td width="60px;"> <img :src="FILE_URL+t.faceimg" class="pftx"></td>
<td class="hh">{{t.nickname}}<small style="float: right;">{{t.cts}}</small><div style="font-size: 12px;color: #666666;" >
<router-link :to="'/QtForumDetail?id='+t.id"> {{t.fname}}</router-link>
</div> </td>
</tr>
</table>



<p class="zwsj" v-if="lastforumli.length==0">
<br>
<img style="width: 50%" src="../../assets/img/nopj.png">
<br>
暂无评论
<br>
</p>

</div>


</el-col>
</el-row>


<!-- 上传图片弹出框 -->
<el-dialog title="回复" :visible.sync="replayVisible" >
<quill-editor ref="myQuillEditor2" v-model="replay_context" :options="editorOption" />
<el-button @click="saveR()" type="primary" >确定回复</el-button>

</el-dialog>

</div>

</div>

</template>

<script>
import { quillEditor,Quill} from 'vue-quill-editor'
import {container, ImageExtend, QuillWatch} from 'quill-image-extend-module'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Quill.register('modules/ImageExtend', ImageExtend)
import '../../api/image-paste.min.js';
let CON_ACTION=process.env.VUE_APP_API_ROOT+'/common/upimg?type=comment_detail';


import {
forum_detail

, comment_page
, comment_save
, forum_del

, comment_del, forum_page
} from '../../api';
export default {
name: "Detail",
components: {
quillEditor,
},
data() {

return {
lastforumli:[],

islogin:0,
replay_context:'',
replayObj:{},
replayVisible:false,
iscollect:false,
context:'',
FILE_URL:'',
lander:{},
id:'',

obj:{},

query: {
fid: '',
pageNo: 1,
pageSize: 10,
},
tableData: [],
pageTotal: 0,


editorOption: {
modules: {

/* 还有一些其他的模块*/
imagePaste: {
addImageBlob: function (blob, callback) {
var formData = new FormData()
formData.append('file', blob)
// your upload function, get the uploaded image url, add then
let config = {
headers: {
"Content-Type": "multipart/form-data",
"Accept": "*/*"
}

}
// 上传接口
axios.post(CON_ACTION, formData, config).then(res => {
console.log(res);
let imgUrl = res.data.obj // 服务器返回的图片url
callback(imgUrl)

})
}
},

ImageExtend: { // 如果不作设置,即{} 则依然开启复制粘贴功能且以base64插入
loading: true,//可选参数 是否显示上传进度和提示语
name: 'file', // 图片参数名
size: 3, // 可选参数 图片大小,单位为M1M = 1024kb
action: CON_ACTION, // 服务器地址, 如果action为空,则采用base64插入图片
// response 为一个函数用来获取服务器返回的具体图片地址
// 例如服务器返回{code: 200; data:{ url: 'baidu.com'}}
// return res.data.url
response: res => {
return res.obj;
},
// headers: xhr => {
// 上传图片请求需要携带token的 在xhr.setRequestHeader中设置
// xhr.setRequestHeader(
// "Authorization",
// this.getCookie("username")
// ? this.getCookie("username").token_type +
// this.getCookie("username").access_token
// : "Basic emh4eTp6aHh5"
// );
// }, // 可选参数 设置请求头部
sizeError: () => {
}, // 图片超过大小的回调
start: () => {
}, // 可选参数 自定义开始上传触发事件
end: () => {
}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
error: () => {
}, // 可选参数 上传失败触发的事件
success: () => {
}, // 可选参数 上传成功触发的事件
// change: (xhr, formData) => {
// xhr.setRequestHeader('myHeader','myValue')
// formData.append('token', 'myToken')
// } // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
},
toolbar: {

container: container,
handlers: {
'image': function () {
QuillWatch.emit(this.quill.id)
}
}

}
},
//主题
theme: "snow",
placeholder: "请输入正文"

},
};
},
methods:{
// 分页导航
handlePageChange(val) {
this.query.pageNo = val;
this.getPage();
},
handleSizeChange(val){
this.query.pageNo = 1;
this.query.pageSize=val;
this.getPage();
},

replyC(t,i){
this.replayVisible=true;
this.replayObj=t;
this.replayObj.index=i;
},
saveR() {

if(this.islogin==0){
this.$message.info("请登录");return;
}
if (this.$refs.myQuillEditor2.value == ''||this.replay_context.trim().length==0) {
this.$message.error('请输入内容');
return ;
}
comment_save({uid:this.lander.id,fid:this.id,context: this.replay_context,hfId:this.replayObj.id,ctype:'forum',hfUid:this.replayObj.uid }).then((res) => {

if(res.data.status==1){
this.replay_context='';
this.$message.success("回复成功");
this.replayVisible=false;

this.getPage();

this.obj.commentNum=res.data.obj;

}else{
this.$message.info(res.data.msg);
}
})
},
saveC() {

if(this.islogin==0){
this.$message.info("请登录");return;
}
if (this.$refs.myQuillEditor.value == ''||this.context.trim().length==0) {
this.$message.error('请输入内容');
return ;
}
comment_save({uid:this.lander.id,fid:this.id,context: this.context,hfId:0,ctype:'forum' }).then((res) => {

if(res.data.status==1){
this.context='';
this.$message.success("评论成功");

this.query.pageNo=1;
this.getPage();

this.obj.commentNum=res.data.obj;

}else{
this.$message.info(res.data.msg);
}
})
},
getPage() {
this.query.fid=this.id;
this.query.hfId=0;
comment_page(this.query).then((res) => {
this.tableData = [];
this.pageTotal = res.data.obj.total//该页总共多少条记录

for(let i=0;i<res.data.obj.list.length;i++){
res.data.obj.list[i].showsy=false;

this.tableData.push(res.data.obj.list[i])
}
})
},
getObj(){
forum_detail({id:this.id}).then((res) => {
if(res.data.status==1){

this.obj = res.data.obj ;

this.getlastforum();
}else{
localStorage.systip=res.data.msg;
this.$router.replace("/Tip")
}
})
},
delForum(){
// 二次确认删除
this.$confirm("确定要删除吗?", "提示", {
type: "warning",
})
.then(() => {
forum_del({id:this.obj.id}).then((res) => {

if(res.data.status==1){
this.$message.success("删除成功");
localStorage.systip="该数据已删除!"
this.$router.replace("/Tip")
}else{
this.$notify({
title: '提示',
message: res.data.msg,
duration: 0
});
}

})

})
.catch(() => {
this.$message({
type: 'info',
message: '已取消'
});
});
},
delC(t,index){
// 二次确认删除
this.$confirm("确定要删除吗?", "提示", {
type: "warning",
})
.then(() => {
comment_del({id:t.id}).then((res) => {

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

})

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

forum_page( {tid:this.obj.tid,sh:1} ).then((res)=>{
let data=res.data;
this.lastforumli=data.obj.list;
})
},


},
mounted() {
this.FILE_URL=process.env.VUE_APP_API_ROOT;


this.id = this.$route.query.id;
localStorage.tol='/QtForumDetail?id='+this.id;
try{
this.lander=JSON.parse(localStorage.loginUser);
this.islogin=1;
}catch (e) {
this.islogin=0;
}

this.getObj();
this.getPage();
},
watch:{
$route:function(value){
this.id =value.query.id;
this.getObj();
this.getPage();

}

}
}
</script>

<style scoped>
.ritem{background: #f3f3f3;margin-bottom: 5px;padding: 10px;}
.xtxx{width: 20px;height:20px;border-radius: 50%;margin-right: 5px;}
.touxx{width: 70px;height: 70px;border-radius: 50%}
.td{border: 1px solid #dddddd;padding: 20px;}
.center{text-align: center;}
.td1{text-align: center;background: #f3f3f3;width: 150px ;}
.actions{width: 100%;font-size: 12px;color: #666666;line-height: 50px;}
.zwsj{text-align: center;}
.pftx{width: 50px;height: 50px;border-radius: 50%;margin-right: 10px; }
</style>

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

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695