springboot+vue实现文章公告通知管理

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

分类: springboot vue 专栏: springboot vue 常用功能 标签: springboot+vue实现文章公告通知管理

2025-02-19 22:20:15 250浏览

springboot+vue实现文章公告通知管理

sql

-- ----------------------------
DROP TABLE IF EXISTS `xl_article`;
CREATE TABLE `xl_article`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `cts` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `atitle` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `acont` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
  `adesc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `uid` int(0) DEFAULT NULL,
  `aimg` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci,
  `sh` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `tags` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `tid` int(0) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

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_article")
public class XlArticle {

    @TableId(type = IdType.AUTO)
      Integer id;

      Integer uid;
      Integer tid;
      String cts;
      String atitle;
      String acont;
      String adesc;
      String aimg;
      String sh;
      String msg;
      String tags;
    @TableField(exist = false)
    String tname;
    @TableField(exist = false)
    String timg;
    @TableField(exist = false)
    String nickname;
    @TableField(exist = false)
    String faceimg;
    @TableField(exist = false)
    String keywords;
    @TableField(exist = false)
    private List<String> tagsli;
}

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




    <select id="getListJoin" resultType="com.jff.xinli.bean.XlArticle" parameterType="com.jff.xinli.bean.XlArticle">
        select a.*,u.nickname,u.faceimg,t.tname,t.timg
        from xl_article a
        left join xl_users u on u.id=a.uid
        left join xl_type t on t.id=a.tid
        WHERE  1=1

        <if test=" sh != null and sh != ''">
            and  a.sh  = #{sh}
        </if>

        <if test=" keywords != null and keywords != ''">
            and(
            a.atitle  like concat('%',#{keywords},'%')
            or a.acont  like concat('%',#{keywords},'%')
            or a.tags  like concat('%',#{keywords},'%')
            or u.nickname  like concat('%',#{keywords},'%')
            or t.tname  like concat('%',#{keywords},'%')
            )
        </if>
        <if test=" uid != null  ">
            and  u.id = #{uid}
        </if>
        <if test=" tid != null  ">
            and  t.id = #{tid}
        </if>
    </select>

    <select id="getIdJoin" resultType="com.jff.xinli.bean.XlArticle" parameterType="java.lang.Integer">
     select a.*,u.nickname,u.faceimg,t.tname,t.timg
        from xl_article a
        left join xl_users u on u.id=a.uid
        left join xl_type t on t.id=a.tid
        WHERE   a.id = #{id}

    </select>

</mapper>

dao

package com.jff.xinli.dao;


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

import java.util.List;


@Component
@Mapper
public interface XlArticleMapper extends BaseMapper<XlArticle> {
List<XlArticle> getListJoin(XlArticle o);
XlArticle getIdJoin(Integer id);

}

service

package com.jff.xinli.service;

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

import java.util.List;

@Service
public class XlArticleService extends ServiceImpl<XlArticleMapper, XlArticle> {

    @Autowired
    XlArticleMapper articleMapper;
    public  List<XlArticle> getListJoin(XlArticle o){
        return articleMapper.getListJoin(o);
    }
    public XlArticle getIdJoin(Integer id) {
        return articleMapper.getIdJoin(id);
    }






}

controller

package com.jff.xinli.control.api;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jff.xinli.bean.XlArticle;
import com.jff.xinli.bean.XlForum;
import com.jff.xinli.bean.XlPsyer;
import com.jff.xinli.service.XlArticleService;
import com.jff.xinli.util.DateUtils;
import com.jff.xinli.util.MessUntil;
import com.jff.xinli.util.DocumentUntil;
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 java.util.ArrayList;
import java.util.List;

@CrossOrigin
@RestController
@RequestMapping("/article")
public class XlArticleController {

	@Autowired
	XlArticleService articleService;





	@RequestMapping("/page")
	public MessUntil page(@RequestParam(value="pageNo",defaultValue="1")int pageNo,
						  @RequestParam(value="pageSize",defaultValue="10")int pageSize,  XlArticle u )  {
		MessUntil mess=new MessUntil();




		 PageHelper.startPage(pageNo,pageSize," id desc ");
    	 List<XlArticle> li=articleService.getListJoin(u);
    	 PageInfo<XlArticle> pageInfo = new  PageInfo(li,pageSize);




		return mess.succ(pageInfo);
	}



	@RequestMapping("/save")
	public MessUntil save(XlArticle o)   {
		MessUntil mess=new MessUntil();
		if(o.getId()==null){
			o.setCts(DateUtils.getNowDateTsString());
		}
		o.setSh("0");
		if(o.getAcont()!=null&&o.getAcont().trim().length()>0){
			o.setAdesc(DocumentUntil.getP(o.getAcont(),200));
			o.setAimg(DocumentUntil.getFirstImg(o.getAcont()));
		}
		articleService.saveOrUpdate(o); 
		return mess.succ();
	}

	@RequestMapping("/update")
	public MessUntil update(XlArticle o)   {
		MessUntil mess=new MessUntil();

		articleService.updateById(o);
		return mess.succ();
	}



	@RequestMapping("detail")
	public MessUntil detail(Integer id )   {
		MessUntil mess=new MessUntil();


		if(id==null )return mess.error( "参数错误");

		 XlArticle o=articleService.getIdJoin(id);

		if(o!=null && o.getSh()!=null&& o.getSh().equals("1")) {
			o.setTagsli(getTagsli(o));

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




	@RequestMapping("del")
	public MessUntil del(Integer id )   {
		MessUntil mess=new MessUntil();


		if(id==null )return mess.error( "参数错误");

		 try{
		 	articleService.removeById(id);
		 }catch (Exception e){
			 return mess.error( "删除失败,请先删除关联数据");
		 }
		return mess.succ(  );
	}

	private List<String> getTagsli(XlArticle o){
		List<String> s=new ArrayList<>();
		if(o==null)return s;
		String tags=o.getTags();
		if(tags!=null&&tags.trim().length()>0){
			tags= tags.replace(",","@#@").replaceAll(",","@#@");
			String[] arr=tags.split("@#@");
			for(String ss:arr){
				if(ss!=null&&ss.trim().length()>0)s.add(ss);
			}
		}
		return s;
	}


}

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.atitle}}</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">
                                <el-row>
                                    <el-col :span="4">
                                        <div style="width: 90%;height: 100px;overflow: hidden;">
                                            <img :src="t.aimg" style="width: 100px; ">
                                        </div>

                                    </el-col>
                                    <el-col :span="20">
                                        {{t.adesc}}..<span @click="seeinfoHandle(t)" style="color:blue;font-size: 12px;">【查看详情】</span>
                                        <br>
                                        <br>
                                        <p style="font-size: 13px;color: #666;">标签:{{t.tags}}</p>

                                        <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}}</span>
                                        </div>
                                    </el-col>
                                </el-row>


                            </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.atitle}}</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}}</span>
                </div>
                <el-divider></el-divider>
                <br>

                 <div v-html="infoObj.acont"></div>
                <br>
                <br>
                <p style="font-size: 13px;color: #666;">标签:{{infoObj.tags}}</p>

                <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="atitle">
                            <el-input v-model="ruleForm.atitle"></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="标签" prop="tags">
                        <el-input v-model="ruleForm.tags" type="textarea"></el-input>
                        <p>逗号分隔</p>

                    </el-form-item>
                        <el-form-item label="内容"   >
                            <quill-editor ref="myQuillEditor" v-model="ruleForm.acont"  :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=article_detail';


    import vHeader from "./Header.vue";
    import vSidebar from "./Sidebar.vue";
    import {
        article_page,
        article_add,
        article_del, type_list, article_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: {
                        atitle: '', 
                        tid: '',
                        acont: '',
                        tags:'',

                },
                rules: {
                    atitle: [  {required: true, message: '请输入', trigger: 'blur'},   ],
                    tid: [  {required: true, message: '请输入', trigger: 'blur'},   ],
                    tags: [  {required: true, message: '请输入', trigger: 'blur'},   ],
                    acont: [  {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("useatitle")
                            //     ? this.getCookie("useatitle").token_type +
                            //         this.getCookie("useatitle").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'){
                    article_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 }) => {
                        article_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.acont!=null){
                     this.infoObj.acont=  this.infoObj.acont.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(){
                article_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.atitle=row.atitle;

                this.ruleForm.tid=row.tid;
                this.ruleForm.tags=row.tags;



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






                this.addVisible=true;
            },

            delHandle(row) {
                this.$confirm('确定删除?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    article_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) {


                        article_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:'article'} ).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;

            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 -->

        <section>
            <div class="container">
                <div  style="text-align: right;">
                    <el-input placeholder="标题" style="width: 200px;"  v-model="query.keywords"></el-input>
                    <el-button type="success" icon="el-icon-search"   @click="searchHandle">搜索</el-button>

                </div>

                <div class="row">
                    <div class="col-lg-2 col-md-2 ">
                        <ul id="filters" class="s2">
                            <li><a @click="seltype('')"   :class="query.tid==''?'selected':''">全部分类</a></li>
                            <li v-for="(t,i) in typeli"><a @click="seltype(t.id)" :class="query.tid==t.id?'selected':''" >{{t.tname}}</a></li>
                        </ul>
                    </div>
                    <div class="col-lg-8 col-md-8 ">
                        <div class="mb10" v-for="(t,i) in tableData">
                            <div class="rounded-20px">
                                <el-row>
                                    <el-col :span="8">
                                        <div class="post-image rounded-10px">
                                            <div class="d-tagline">
                                                <span>{{t.tname}}</span>
                                            </div>
                                            <img alt="" :src="t.aimg" class="lazy">
                                        </div>
                                    </el-col>
                                    <el-col :span="15" :offset="1">
                                        <div class="pt-2 h-100">
                                            <h4><router-link :to="'QtArticleDetail?id='+t.id" class="text-dark"  target="_blank">{{t.atitle}}</router-link></h4>
                                            <p class="mb-3">{{t.adesc}}... <router-link :to="'QtArticleDetail?id='+t.id"  style="color: green;font-size: 12px;"  target="_blank">【查看详情】</router-link></p>
                                            <div class="relative bg-grey p-1 px-3 rounded-10px">
                                                <img :src="FILE_URL+t.faceimg" class="w-20px me-2 circle" alt="">
                                                <div class="d-inline fs-14 fw-bold me-3">{{t.nickname}}</div>
                                                <div class="d-inline fs-14 fw-600"><i class="icofont-ui-calendar id-color me-2"></i>{{t.cts}}</div>
                                            </div>
                                        </div>
                                        <el-divider></el-divider>
                                    </el-col>
                                </el-row>


                            </div>
                        </div>

                        <el-pagination
                                v-if="tableData.length>0"
                                :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 v-if="tableData.length==0" style="line-height: 200px;text-align: center;">

                            <img src="../../assets/img/nosj.png">
                            <br>
                            没搜索到数据哦</div>

                        <br>
                        <br>
                        <br>

                    </div>



                </div>




            </div>


        </section>




    </div>











</template>
<script>

    import {article_page, type_list} from '../../api';
export default {
    name:'Uinfo',
    components: {

    },

    data() {

        return {

            typeli:[],
            islogin:0,
            FILE_URL : '',


            lander :{},

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

            },
            total:0,
            tableData:[],




        };
    },
    methods:{
        seltype(tid){
            this.query.tid=tid;
            this.query.keywords='';
            this.query.pageNo=1;
            this.getPage();
        },
        gettypeli(){

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

            })
        },

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

            article_page( this.query ).then((res)=>{
                let data=res.data;
                this.tableData=data.obj.list;
                this.total=data.obj.total;
            })
        },
        searchHandle(){
            this.query.pageNo=1;
            this.getPage();
        },



    },mounted() {

        this.query.keywords  = this.$route.query.keywords;
        try{
            this.islogin=1;
            this.lander=JSON.parse(localStorage.loginUser);
        }catch(err){
            this.islogin=0;

        }



        this.FILE_URL=process.env.VUE_APP_API_ROOT;



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



    },
    watch:{
        $route:function(value){
            this.query.keywords =value.query.keywords;
            this.query.pageNo=1;
            this.getPage();

        }

    }
};
</script>
<style scoped>
 /deep/ .el-input__icon {
 height:auto;}
</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.atitle}}</li>
                        </ul>
                    </div>
                </div>
            </div>
        </section>
        <!-- section close -->

        <section style="background-size: cover; background-repeat: no-repeat;">
            <div class="container" style="background-size: cover; background-repeat: no-repeat;">
                <div class="row gx-5" style="background-size: cover; background-repeat: no-repeat;">
                    <div class="col-lg-8" style="background-size: cover; background-repeat: no-repeat;">
                        <div style="background-size: cover; background-repeat: no-repeat;">

                            <h2>{{obj.atitle}}</h2>
                            <div class="relative bg-grey p-1 px-3 rounded-10px">
                                <img :src="FILE_URL+obj.faceimg" class="w-20px me-2 circle" alt="">
                                <div class="d-inline fs-14 fw-bold me-3">{{obj.nickname}}</div>
                                <div class="d-inline fs-14 fw-600"><i class="icofont-ui-calendar id-color me-2"></i>{{obj.cts}}</div>
                            </div>
                            <div  v-html="obj.acont">   </div>

                        </div>


                        <div id="blog-comment" style="background-size: cover; background-repeat: no-repeat;">
                            <h4>评论 ({{pageTotal}})</h4>

                            <div class="spacer-half" style="background-size: cover; background-repeat: no-repeat;"></div>

                            <ol>
                                <li  v-for="(t,i) in tableData">
                                    <div class="avatar" style="background-size: cover; background-repeat: no-repeat;">
                                        <img :src="FILE_URL+t.faceimg" alt=""></div>
                                    <div class="comment-info" style="background-size: cover; background-repeat: no-repeat;">
                                        <span class="c_name">{{t.userNickname}}</span>
                                        <span class="c_date id-color">{{t.cts}}</span>
                                        <span class="c_reply"><a style="color: red;" @click="delC(t,i)" v-if="islogin==1&&t.uid==lander.id"  >删除该评论</a></span>
                                        <div class="clearfix" style="background-size: cover; background-repeat: no-repeat;"></div>
                                    </div>

                                    <div class="comment" style="background-size: cover; background-repeat: no-repeat;">  {{t.context}}</div>

                                </li>



                            </ol>

                            <div v-if="tableData.length==0" style="line-height: 200px;text-align: center;">

                                <img src="../../assets/img/nopl.png">
                                <br>
                                暂时没人评论哦</div>
                            <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="spacer-single" style="background-size: cover; background-repeat: no-repeat;"></div>

                            <div id="comment-form-wrapper" style="background-size: cover; background-repeat: no-repeat;">
                                <h4>说两句吧</h4>
                                <div class="comment_form_holder" style="background-size: cover; background-repeat: no-repeat;">




                                        <textarea cols="10"  v-model="acont" rows="10" name="message" placeholder="请输入评论" class="form-control"></textarea>

                                    <br>
                                    <br>
                                        <p id="btnsubmit">
                                            <input type="button" @click="saveC" value="发布评论" class="btn-main"></p>




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

                    </div>

                    <div class="col-lg-4" style="background-size: cover; background-repeat: no-repeat;">
                        <div class="widget widget-post" style="background-size: cover; background-repeat: no-repeat;">
                            <h4>最新知识</h4>
                            <ul class="de-bloglist-type-1">
                                <li v-for="(t,i) in lastArticleli">
                                    <div class="d-image" style="background-size: cover; background-repeat: no-repeat;">
                                        <img :src="t.aimg" alt="">
                                    </div>
                                    <div class="d-content" style="background-size: cover; background-repeat: no-repeat;">
                                        <router-link :to="'/QtArticleDetail?id='+t.id" href="#"><h4>{{t.atitle}}</h4></router-link>
                                        <div class="d-date" style="background-size: cover; background-repeat: no-repeat;">{{t.cts}}</div>
                                    </div>
                                </li>

                            </ul>
                            <p  class="zwsj" v-if="lastArticleli.length==0">
                                <br>
                                <img style="width: 50%" src="../../assets/img/nod.png">
                                <br>
                                暂无数据
                                <br>
                            </p>
                        </div>

                        <div class="widget widget_tags" style="background-size: cover; background-repeat: no-repeat;">
                            <h4>标签</h4>
                            <ul>
                                <li v-for="(t,i) in obj.tagsli"><router-link :to="'/QtArticle?keywords='+t">{{t}}</router-link></li>

                            </ul>
                        </div>

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





    </div>

</template>

<script>


    import {article_detail, comment_page, comment_del, comment_save, article_page} from '../../api';
    export default {
        name: "Detail",
        components: {

        },
        data() {

            return {

                islogin:0,

                lastArticleli:[],

                lander:{},
                id:'',
                 
                obj:{},

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




            };
        },
        methods:{

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



            saveC() {

                if(this.islogin==0){
                    this.$message.info("请登录");return;
                }
                if ( this.acont.trim().length==0) {
                    this.$message.error('请输入内容');
                    return  ;
                }
                let o={uid:this.lander.id,fid:this.id,context: this.acont, ctype:this.query.ctype };

                comment_save(o).then((res) => {

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

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



                    }else{
                        this.$message.info(res.data.msg);
                    }
                })
            },
            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: '已取消'
                        });
                    });
            },
            getPage() {
                this.query.fid=this.id;
                comment_page(this.query).then((res) => {
                    this.tableData =res.data.obj.list;
                    this.pageTotal = res.data.obj.total//该页总共多少条记录

                })
            },

 
            getObj(){
                article_detail({id:this.id}).then((res) => {
                    if(res.data.status==1){


                        this.obj = res.data.obj ;

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

                        }

                        this.getlastarticle();

                    }else{
                        this.$message.error(res.data.msg)
                        localStorage.systip=res.data.msg
                        this.$router.replace("/Tip")

                    }
                })
            },

            getlastarticle(){

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


           
        },
        mounted() {

            this.FILE_URL=process.env.VUE_APP_API_ROOT;
           

            this.id = this.$route.query.id;
            localStorage.tol='/QtArticleDetail?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>
    .zwsj{text-align: center;}
</style>

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

此处可发布评论

评论(0展开评论

暂无评论,快来写一下吧

展开评论

您可能感兴趣的博客

客服QQ 1913284695