Files
learning-system-portal/src/views/portal/article/Index.vue
LAPTOP-S9RBPPM6\bjxask-2201 fb58529e77 提交
2022-05-31 14:34:23 +08:00

674 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
2<template>
<div id="article-list-content" class="article-list-content">
<portal-header current="article" @emitInput="emitInput"></portal-header>
<div class="xcontent portal-content">
<div class="xrow" style="display: flex;justify-content: space-between;">
<div style="flex: 1;" class="xcol content-div">
<el-row>
<el-card :body-style="{ padding: '0px' }" class="left-div">
<el-row class="search-div">
<el-col>
<!-- <el-input placeholder="请输入关键词搜索" clearable v-model="articleList.keyword" maxlength="20">
<el-button slot="append" icon="el-icon-search" @click="searchData()"></el-button>
</el-input> -->
<!-- <div class="tip">
热门搜索词
<span v-for="(item, index) in searchRecords" :key="index" @click="useHotword(item)">{{ item.keyword }}</span>
</div> -->
</el-col>
</el-row>
<el-row class="order-div">
<div class="quyer-tag">
<el-button
type="text"
class="order-class"
@click="getData(2)"
:class="{ actice: articleList.order == 2 }">
最热
</el-button>
<el-button
type="text"
class="order-class"
@click="getData(1)"
:class="{ actice: articleList.order == 1 }">
最新
</el-button>
</div>
<span class="more"></span>
</el-row>
<div class="data-content" v-if="articleList.list.length > 0">
<div :span="24" v-for="(article, aidx) in articleList.list" :key="aidx" class="article-list">
<div class="article-info">
<!--title-->
<router-link :to="'article/detail?id=' + article.id">
<div style="display: flex;justify-content: space-between;margin-bottom: 10px;">
<div class="article-title one-line-ellipsis" v-html="$keywordActiveShow(article.title,articleList.keyword)"></div>
<div class="article-info-date"><i class="el-icon-time"></i> {{article.sysCreateTime.substring(0,10)}}</div>
</div>
</router-link>
<!--body-->
<div class="article-body" style="display: flex;justify-content: space-between;">
<div class="article-image" v-if="article.coverurl">
<article-image :article="article"></article-image>
</div>
<div style="flex: 1;">
<router-link :to="'article/detail?id=' + article.id">
<div style="padding-top: 5px;">
<div class="article-info-summary" :style="{height:article.coverurl==''? '50px':'100px'}" :class="article.coverurl==''? 'two-line-ellipsis':'four-line-ellipsis'">{{ article.summary }}</div>
</div>
</router-link>
</div>
</div>
<!--互动内容-->
<div style="display: flex;justify-content:flex-start;align-items: center;margin-top: 0px;">
<!-- <div style="width: 120px;"> -->
<author :avatar="article.authorInfo.avatar" :name="article.sysCreateBy" :sex="article.authorInfo.sex"></author>
<!-- </div> -->
<!-- <div> -->
<interactBar nodeWidth="60px" :readonly="true" :type="2" :data="article" :views="false"></interactBar>
<!-- </div> -->
<!-- <author :avatar="article.authorInfo.avatar" :name="article.sysCreateBy" :info="article.authorInfo.orgInfo"></author> -->
</div>
</div>
</div>
</div>
<!-- <div class="pagination-div" v-if="isMore"><span class="pag-text" @click="loadMore()">加载更多</span></div> -->
<div class="pagination-div">
<span class="pag-text" @click="loadMore()" v-if="moreState == 1">加载更多</span>
<span class="pag-text-msg" v-else-if="moreState == 2">数据加载中</span>
<span class="pag-text-msg" v-else-if="moreState == 3 && !isSeach">没有更多数据了</span>
<span class="pag-text-msg" v-else-if="isSeach">没有查询到相关内容</span>
</div>
<div v-if="isSeach" style="height:382px">
</div>
</el-card>
</el-row>
</div>
<div style="width: 245px;margin-left: 5px;">
<div>
<div id="articleAnking">
<el-button @click="openDialog" style="width: 100%;height: 37px;border-radius: 0;margin-bottom:15px;" type="primary">写文章</el-button>
<!-- <a :href="`${webBaseUrl}/article/add`" style="width: 100%;margin-bottom:15px;display: inline-block;" target="_blank"><el-button style="width: 100%;height: 37px;border-radius: 0;" type="primary">写文章</el-button></a> -->
<!-- <el-button style="width: 100%;margin:10px 0" type="primary">发布文章</el-button> -->
<el-card class="ranking-card">
<div slot="header">
<span style="font-size: 14px;font-weight: 600;color: #333333;">贡献榜</span>
</div>
<div style="padding-bottom:10px">
<!-- <el-row class="ranking-title"> -->
<!-- <el-col :span="10" >姓名</el-col>
<el-col :offset="4" :span="10" class="center">发布数</el-col> -->
<!-- <el-col :offset="4" :span="10" style="color: #333333;font-size: 14px;">姓名</el-col>
<el-col :span="10" style="text-align: right;color: #333333;font-size: 14px;">贡献度</el-col> -->
<!-- </el-row> -->
<!-- <el-row class="ranking-title" v-for="(item, index) in ankingList" :key="index">
<el-col :span="4" style="text-align: center;">
<img v-if="index===0" :src="`${webBaseUrl}/images/first.png`"/>
<img v-if="index===1" :src="`${webBaseUrl}/images/second.png`"/>
<img v-if="index===2" :src="`${webBaseUrl}/images/third.png`"/>
<span style="margin-left: 10px" v-if="index!=2&&index!=0&&index!=1">{{index+1}}</span>
</el-col>
<el-col :span="10" style="color: #333333;font-size: 14px;">{{ item.sysCreateUname }}</el-col>
<el-col :span="10" style="text-align: right;color: #333333;font-size: 14px;">{{ item.counts }}</el-col>
</el-row> -->
<el-row style=" line-height: 34px;" class="ranking-title bacolor" v-for="(item, index) in ankingList" :key="index" >
<el-col :span="6" style="height:34px">
<img v-if="index===0" :src="`${webBaseUrl}/images/first.png`"/>
<img v-if="index===1" :src="`${webBaseUrl}/images/second.png`"/>
<img v-if="index===2" :src="`${webBaseUrl}/images/third.png`"/>
<span style="margin-left: 10px" v-if="index!=2&&index!=0&&index!=1">{{index+1}}</span>
</el-col>
<!-- <el-tooltip :enterable="false" @click.native="jumpRouter(item)" effect="light" :content="item.name" placement="top-start"> -->
<el-col :span="18" class="one-line-ellipsis"> {{ item.sysCreateUname }}</el-col>
<!-- </el-tooltip> -->
<!-- <el-col class="center" style="color: #FF8E00;" :span="5">{{ item.score }}</el-col> -->
</el-row>
</div>
</el-card>
</div>
</div>
</div>
</div>
<el-row :gutter="10">
<el-col :span="6" class="right-box" >
</el-col>
</el-row>
</div>
<el-dialog title="创建文章" :visible.sync="diagSync" :close-on-click-modal="false" width="900px" custom-class="g-dialog">
<editItems v-if="diagSync" :jumpLimit="false" :editForm="{}" @success="saveSuccess"></editItems>
</el-dialog>
<portal-footer></portal-footer>
<portalFloatTools></portalFloatTools>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import portalHeader from '@/components/PortalHeader.vue';
import portalFooter from '@/components/PortalFooter.vue';
import portalFloatTools from '@/components/PortalFloatTools.vue';
import interactBar from '@/components/Portal/interactBar.vue';
import timeShow from '@/components/Portal/daytimeShow.vue';
import author from '@/components/Portal/authorInfo.vue';
import apiArticle from '@/api/modules/article.js';
import apiUser from '@/api/system/user.js';
import apiSearchterm from '@/api/modules/searchterm.js';
import articleImage from '@/components/Article/articleImage.vue';
import editItems from '@/components/Article/editItems.vue';
export default {
name: 'index',
components: { editItems,portalHeader, portalFooter,articleImage, portalFloatTools, interactBar, timeShow, author },
computed: {
...mapGetters(['userInfo']),
// isMore() {
// let isOk = true;
// if (this.articleList.list.length === this.count) {
// isOk = false;
// }
// return isOk;
// }
},
data() {
return {
moreState:1,// 1 加载更多 2 加载中 3无数据
searchRecords: [],
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
articleList: {
pageIndex: 1,
pageSize: 10,
order: 2,
keyword:'',
list: []
},
count: 0,
order: 1,
articleForm: {
title: '',
content: ''
},
keyword: '',
searchTags: [],
ankingList: [],
ankingWidth:'100%',
ankingFixed:false,
diagSync:false,//控制弹窗
// articleList: []
isSeach:false,
};
},
mounted() {
// let el_anking = document.querySelector('#articleAnking');
// this.ankingWidth=el_anking.clientWidth;
//console.log(el_anking.clientWidth,'clientWidth');
this.articleList.keyword = this.$route.query.keyword;
if(this.articleList.keyword != '') {
this.isSeach = true;
}
this.getArticleList();
this.getAnkingData();
this.searchterm();
let height = 200;
let $this = this;
window.addEventListener(
"scroll",
this.handleScroll
);
},
beforeDestroy(){
window.removeEventListener("scroll",this.handleScroll);
},
methods: {
emitInput(val){
this.articleList.keyword = val;
this.isSeach =true;
this.searchData();
},
saveSuccess(data){
this.diagSync=false;
this.articleList.pageIndex = 1;
this.articleList.list = [];
this.getArticleList();
},
openDialog(){
this.diagSync=true
},
handleScroll() {
let el_anking = document.querySelector('#articleAnking');
//console.log(el_anking.clientWidth,'clientWidth');
//el_anking.wid
let innerHeight = document.querySelector('#article-list-content').clientHeight
let outerHeight = document.documentElement.clientHeight
let scrollTop = document.documentElement.scrollTop
if ((outerHeight + scrollTop + 350) >= innerHeight) {
if(this.moreState == 1) {
this.debounce(this.loadMore(),5000);
}
}
// console.log(scrollTop,'scrollTop');
// console.log(innerHeight,'innerHeight');
// console.log(outerHeight,'outerHeight');
// if(scrollTop>90){
// if(this.ankingFixed){
// this.ankingFixed=false;
// el_anking.classList.add('anking-fixed');
// }
// }else{
// if(!this.ankingFixed){
// this.ankingFixed=true;
// el_anking.classList.remove('anking-fixed');
// }
// }
if(scrollTop > 400) {
document.querySelector('#articleAnking').style.cssText = "position: fixed;top: 0;width:242.5px";
} else {
document.querySelector('#articleAnking').style.cssText = "position: static";
}
},
debounce(func, wait) {// 非立即执行
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
},
// debounce(func,wait) {//立即执行
// let timeout;
// return function () {
// let context = this;
// let args = arguments;
// if (timeout) clearTimeout(timeout);
// let callNow = !timeout;
// timeout = setTimeout(() => {
// timeout = null;
// }, wait)
// if (callNow) func.apply(context, args)
// }
// },
searchData(){
apiSearchterm.save({ keyword: this.articleList.keyword, type: 2 });
this.articleList.pageIndex = 1;
this.articleList.list = [];
this.getArticleList();
},
getData(num) {
this.articleList.order = num;
this.articleList.pageIndex = 1;
this.articleList.list = [];
this.getArticleList();
},
useHotword(item) {
this.articleList.keyword = item.keyword;
this.articleList.pageIndex = 1;
this.articleList.list = [];
this.getArticleList();
},
searchterm() {
apiSearchterm.list(5, 2).then(res => {
if (res.status === 200) {
this.searchRecords = res.result;
}
});
},
loadMore() {
this.articleList.pageIndex += 1;
this.getArticleList();
},
handleSizeChange(item) {
this.articleList.pageSize = item;
},
handleCurrentChange(item) {
this.articleList.pageIndex = item;
},
getArticleList() {
this.moreState = 2;
let { pageIndex, pageSize, order, keyword } = this.articleList;
const query = { pageIndex, pageSize, order, keyword };
let that = this;
// portalPageList接口换了这是原来的
apiArticle.findPortal(query).then(res => {
if (res.status == 200 && res.result.list.length > 0) {
this.isSeach =false;
let ids = [];
res.result.list.forEach(item => {
item.authorInfo = { name: '', avatar: '', orgInfo: '' ,sex:null};
ids.push(item.sysCreateAid);
});
that.getQaUserData(res.result.list, ids);
this.count = res.result.count;
that.articleList.list.push(...res.result.list);
that.moreState = 1;
if(res.result.count === res.result.list.length) {
this.moreState = 3;
}
} else {
this.moreState = 3;
// this.$message.error(res.message);
}
});
},
getQaUserData(list, ids) {
const noReapetIds = [...new Set(ids)];
apiUser.getByIds(noReapetIds).then(res => {
if (res.status == 200) {
list.forEach(item => {
res.result.some(author => {
if (author.aid == item.sysCreateAid) {
item.authorInfo.avatar = author.avatar;
item.authorInfo.name = author.name;
item.authorInfo.orgInfo = author.orgInfo;
item.authorInfo.sex = author.sex;
}
});
});
} else {
// this.$message({ message: res.message, type: 'error' });
}
});
},
goTarget(href) {
window.open(this.webBaseUrl+href, '_blank');
},
showInApply() {
this.inapply.show = true;
},
findOrg() {
//
},
publishArticle() {
this.$router.push('/article/add');
},
submitCreate() {
this.$refs['applyForm'].validate(valid => {
if (valid) {
}
});
},
getAnkingData() {
apiArticle.countsUsername(5).then(res => {
if (res.status == 200) {
this.ankingList = res.result;
}
});
},
}
};
</script>
<style scoped lang="scss">
::v-deep .el-card__body{
padding: 0;
}
::v-deep .bacolor:nth-child(odd){
background-color: #fff;
padding: 0 5px;
}
::v-deep .bacolor:nth-child(even){
background-color: #f6f6f6;
padding: 0 5px;
}
.anking-fixed {
position: fixed;
top: 0px;
background-color: #f0f0f0;
z-index: 999;
}
.left{
text-align: left;
}
.right{
text-align: right;
}
.one-line-ellipsis{
display: -webkit-box;
white-space:pre-wrap;
overflow: hidden;
text-overflow:ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
box-sizing: border-box;
// width: 80%;
}
.two-line-ellipsis{
display: -webkit-box;
// white-space:pre-wrap;
overflow: hidden;
line-height: 30px;
text-overflow:ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
box-sizing: border-box;
}
.four-line-ellipsis{
display: -webkit-box;
// white-space:pre-wrap;
overflow: hidden;
line-height: 25px;
text-overflow:ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 4;
box-sizing: border-box;
}
.left-div {
.search-div{
padding: 20px;
// padding-top: 20px;
::v-deep .el-input{
width: 420px;
height: 38px;
margin-bottom: 13px;
.el-input__inner{
height: 38px;
border-radius: 0;
}
.el-input-group__append{
width: 44px;
height: 38px;
border: 0;
padding: 0;
background:#3E7FFF;
border-radius: 0;
.el-button{
margin: 0;
border: 0;
width: 100%;
height: 38px;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
.el-icon-search{
color: #fff;
font-size: 22px;
}
}
}
}
.tip{
color:#999999;
font-size: 12px;
span{
margin-right: 8px;
cursor: pointer;
}
}
}
.quyer-tag {
::v-deep .el-button{
width: 52px;
height: 32px;
padding: 0;
}
.order-class {
color: #666666;
// width: 80px;
// text-align: left;
background-color: #FFFFFF;
border: 1px solid #DDDDDD;
border-radius: 0px;
height: 32px;
line-height: 32px;
// padding-left: 5px;
// padding-top: 5px;
// padding-bottom: 5px;
.el-icon--right {
margin-left: 0;
}
}
.actice {
border: 0px;
background: #3e7fff;
color: #fff;
}
}
/* 分页div */
.pagination-div {
text-align: center;
padding: 10px 0;
}
.order-div {
padding: 0 20px;
background-color: #fff;
margin-bottom: 20px;
}
.data-content {
background-color: #fff;
padding: 5px 9px;
min-height: 364px;
.article-list:last-child {
border-bottom: none;
}
.article-list:first-child {
margin-top: -24px;
}
.article-list {
padding: 24px 10px;
border-bottom: 1px solid #E8E8E8;
}
.search-div {
background: #fff;
padding: 10px 25px 0 25px;
.input-with-select {
.tip {
line-height: 35px;
font-size: 12px;
color: #999;
margin-bottom: 10px;
}
}
.tip {
color: #999;
}
}
}
}
.ranking-title {
// padding-top: 20px;
line-height: 34px;
.center-titlt{
font-size: 15px;
color: #333333;
}
.center{
text-align: right;
}
img{
margin-top: 5px;
}
}
.right-box {
.add-btn {
width: 100%;
padding: 15px 0;
}
.ranking-data {
margin: 10px 0;
color: #999999;
}
}
.article-info {
// display: flex;
.article-title {
// height: 30px;
// line-height: 30px;
font-family: PingFang SC-Medium, PingFang SC;
font-size: 18px;
line-height: 30px;
color: #121212;
font-weight: 600;
flex:1;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break:break-all;
}
.article-info-date {
font-size: 12px;
line-height: 30px;
color: #8590A6;
i {
margin-right: 5px;
}
}
.art-box{
position: relative;
p{
position: absolute;
float: left;
top: 20px;
left: 10px;
color: #ffffff;
font-size: 14px;
line-height: 30px;
padding-right: 10px;
}
}
.article-image {
width: 156px;
height: 105px;
margin-right: 15px;
// margin-right: 10px;
}
.article-body {
margin: 10px 0px;
// margin-right: 20px;
// display: flex;
// flex-direction: column;
// justify-content: space-between;
.article-info {
font-size: 16px;
// height: 30px;
}
.article-info-summary {
word-break: break-all;
height: 100px;
line-height: 25px;
color: #121212;
font-weight: 400;
font-size: 15px;
}
}
}
::v-deep .item-author{
margin-right: 100px;
margin-top: -7px;
// margin-top: 5px;
}
</style>