Files
learning-system-portal/src/views/portal/article/Index.vue
zhaofang f998be66c8 提交
2022-09-02 18:00:18 +08:00

678 lines
20 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">
<div class="article-banner">
<portal-header current="article" @emitInput="emitInput"></portal-header>
</div>
<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 style="font-size:14px" class="el-icon-time"></i> {{article.sysCreateTime}}</div>
</div>
</router-link>
<!--body-->
<div class="article-body" style="display: flex;justify-content: space-between;">
<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>
<router-link :to="'article/detail?id=' + article.id">
<div class="article-image" v-if="article.coverurl">
<article-image :article="article"></article-image>
</div>
</router-link>
</div>
<!--互动内容-->
<div style="display: flex;justify-content:flex-start;align-items: center;margin-top: 0px;">
<div style="flex:1;">
<author :avatar="article.authorInfo.avatar" :name="article.sysCreateBy" :sex="article.authorInfo.sex"></author>
</div>
<div style="">
<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: 410px;margin-left: 5px;">
<div>
<div id="articleAnking">
<el-button class="write-art" @click="openDialog" type="primary"><svg-icon icon-class="addArticle" style="margin-right: 20px;font-size: 26px;"></svg-icon>写文章</el-button>
<div class="portal-right-box art-bgimg" style="background-color:#fff;">
<p class="portal-title-one" style="padding-bottom:12px" >贡献榜</p>
<ul>
<li v-for="(item, index) in ankingList" :key="index" style="margin-top:30px;line-height: 22px;cursor: pointer;">
<span class="portal-right-text orange-one" v-if="index==0" style="margin-right:94px">
<img src="/images/list-01.png" alt="">
</span>
<span class="portal-right-text orange-tow" v-if="index==1" style="margin-right:94px">
<img src="/images/list02.png" alt="">
</span>
<span class="portal-right-text orange-three" v-if="index==2" style="margin-right:94px">
<img src="/images/list03.png" alt="">
</span>
<span class="portal-right-text" v-if="index==3" style="margin-right:94px">
<img src="/images/list04.png" alt="">
</span>
<span class="portal-right-text" v-if="index==4" style="margin-right:94px">
<img src="/images/list05.png" alt="">
</span>
<span class="portal-title-desc">{{ item.sysCreateUname }}</span>
</li>
</ul>
</div>
</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">
.article-banner{
height: 240px;
background: url('/images/article-banner.png');
}
.write-art{
width: 410px;
height: 67px;
text-align: center;
background: #DDEDFF;
border-radius: 8px;
font-size: 18px;
font-weight: 500;
border: none;
color: #387DF7;
margin-bottom: 22px;
}
::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 {
border: none;
.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: 44px;
height: 26px;
padding: 0;
}
.order-class {
color: #6E7B84;
background-color: #FFFFFF;
border-radius: 4px;
height: 32px;
line-height: 32px;
font-size: 14px;
.el-icon--right {
margin-left: 0;
}
}
.actice {
border: 0px;
background: #387DF7;
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: #999999;
i {
margin-right: 3px;
}
}
.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-left: 18px;
::v-deep .el-image{
border-radius: 4px;
}
}
.article-body {
// margin: 10px 0px;
margin-bottom: 20px;
.article-info {
font-size: 16px;
}
.article-info-summary {
word-break: break-all;
height: 100px;
line-height: 25px;
color: #333333;
font-weight: 400;
font-size: 14px;
}
}
}
::v-deep .item-author{
margin-right: 100px;
margin-top: -7px;
// margin-top: 5px;
}
</style>