Files
learning-system-portal/src/views/portal/article/Index.vue
2023-03-15 18:45:39 +08:00

940 lines
28 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" textColor="#ffffff" @emitInput="emitInput" @showClass="showClass"></portal-header>
</div>
<!--内容区域-->
<div style="padding-top:30px" class="">
<div class="xcontent2">
<div class="xcontent2-main" style="margin-right: 30px;background-color: #fff;padding-top: 50px;">
<div>
<div style="padding:0px" class="left-div">
<div 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>
</div>
<div class="data-content" v-if="articleList.list.length > 0">
<div 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" :aid="article.authorInfo.aid"></author>
</div>
<div style="">
<interactBar nodeWidth="60px" :readonly="true" :type="2" :data="article" :shares="false" :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>
</div>
</div>
</div>
<div class="xcontent2-minor">
<div>
<div class="portal-model-btn pointer" @click="openDialog">
<svg-icon style="margin-right: 10px;font-size: 24px;" icon-class="addArticle"></svg-icon>
写文章
</div>
<div id="articleAnking">
<div>
</div>
<div class="portal-ranking ranking-bg">
<p class="ranking-title">贡献榜</p>
<ul class="ranking-data">
<li class="index-one-line-ellipsis" v-for="(item, index) in ankingList" :key="index" style="margin-top:30px;line-height: 22px;cursor: pointer;">
<!-- <router-link :to="'article/detail?id=' + item.id"> -->
<span class="portal-right-text orange-one" v-if="index==0" style="margin-right:20px">
<img :src="`${webBaseUrl}/images/listblue01.png`" alt="">
</span>
<span class="portal-right-text orange-tow" v-if="index==1" style="margin-right:20px">
<img :src="`${webBaseUrl}/images/listblue02.png`" alt="">
</span>
<span class="portal-right-text orange-three" v-if="index==2" style="margin-right:20px">
<img :src="`${webBaseUrl}/images/listblue03.png`" alt="">
</span>
<span class="portal-right-text" v-if="index==3" style="margin-right:20px">
<img :src="`${webBaseUrl}/images/list04.png`" alt="">
</span>
<span class="portal-right-text" v-if="index==4" style="margin-right:20px">
<img :src="`${webBaseUrl}/images/list05.png`" alt="">
</span>
<span class="portal-title-desc ">{{ item.sysCreateUname }}<span class="orinfo-text"> {{ item.orinfo }}</span> </span>
<!-- {{ item.sysCreateAid }} -->
<!-- </router-link> -->
</li>
</ul>
</div>
<!-- <div class="course-resources pointer"> -->
<!-- 资源位 -->
<!-- <img @click="banJump()" :src="fileBaseUrl + resonimg.image" alt="">
</div> -->
</div>
</div>
</div>
</div>
</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 class="uClass">
<el-dialog :visible.sync="showUClass" width="833px">
<div class="ClassBoxContentx">
<img src="../../../assets/images/u_class.png" alt="" class="imgx" />
<div class="ContentBoxx">
<div class="leftBox">
<div class="titlex">U选小课堂</div>
<div class="jyx">项目简介</div>
<div class="msgx">
于22年首推是一个面向全集团员工开放的职业通识类数字化培养项目旨在帮助员工开阔眼界加厚职业素养在原有外部精选通用力课程基础上2023年引入创新专区以新鲜的话题新颖的形式带给全员丰富有趣的学习体验
</div>
<div class="bottomx"></div>
</div>
<div class="rightBox">
<div class="tylx" @click="tylClick">
<div class="tyl_titlex">
<img
src="../../../assets/images/dc.png"
alt=""
class="tyl_title_imgx"
/>
<span class="tyl_title_msgx">通用力专区</span>
</div>
<div class="tyl_jyx">加厚职业素养轻学习快成长</div>
<div class="tyl_msgx">
内容涵盖领导力市场营销职场技能财务知识法律常识人力资源经典国学人文社科
</div>
</div>
<div class="cylx" @click="cylClick">
<div class="tyl_titlex">
<img
src="../../../assets/images/cyl.png"
alt=""
class="tyl_title_imgx"
/>
<span class="tyl_title_msgx">创新力专区</span>
</div>
<div class="tyl_jyx">激发创新潜力拓视野促思考</div>
<div class="tyl_msgx">
内容涵盖组合创新单点破局错位竞争分形创新第二曲线数字化元宇宙
</div>
</div>
</div>
</div>
</div>
</el-dialog>
</div>
</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';
import apiPlace from "@/api/phase2/place.js"
import {cutOrgNamePath} from "@/utils/tools.js";
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 {
showUClass: false,
ankIds:[],
resonimg:{},
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');
if(this.$route.query){
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
);
this.couresreso();
},
beforeDestroy(){
window.removeEventListener("scroll",this.handleScroll);
},
methods: {
tylClick() {
window.open("https://m.qingxuetang.com/x/?appId=qxtcorp306130");
},
cylClick() {
window.open("https://u.boe.com/pc/course?keyword=创新力专区");
},
showClass(flag) {
if (flag) {
this.showUClass = flag;
}
},
banJump() {
if(this.resonimg.JumpUrl) {
window.open(this.resonimg.JumpUrl);
}
},
couresreso(){
let key = 'article';
apiPlace.detail(key).then(res=>{
let lmj = JSON.parse(res.result.content)
this.resonimg = lmj[0]
})
},
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 outerWidth = el_anking.clientWidth;
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:"+outerWidth+"px";
} 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 = {aid:'', 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.aid = author.aid;
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() {
let $this=this;
apiArticle.countsUsername(5).then(res => {
if (res.status == 200) {
let ids = [];
res.result.forEach(item =>{
item.orinfo='';
ids.push(item.sysCreateAid);
})
$this.ankingList = res.result;
apiUser.getByIds(ids).then(rs=>{
rs.result.forEach(u=>{
$this.ankingList.forEach((sub) => {
if(sub.sysCreateAid==u.aid){
sub.orinfo=cutOrgNamePath(u.orgInfo);
}
})
})
// console.log(this.ankingList);
})
}
});
},
}
};
</script>
<style scoped lang="scss">
.uClass {
::v-deep .el-dialog {
border-radius: 15px;
.el-dialog__headerbtn .el-dialog__close {
color: white;
position: absolute;
z-index: 99;
right: 15px;
}
}
::v-deep .el-dialog__body {
padding: 0px;
}
.ClassBoxContentx {
width: 100%;
height: 456px;
// background: red;
border-radius: 15px;
.ContentBoxx {
width: 100%;
height: 100%;
position: absolute;
z-index: 9;
display: flex;
.leftBox,
.rightBox {
height: calc(100% - 30px);
}
.leftBox {
padding-left: 30px;
width: 48%;
.titlex {
width: 200px;
height: 59px;
line-height: 59px;
text-align: center;
margin-left: -8px;
font-size: 38px;
color: white;
margin-top: 42.97px;
padding-top: 5px;
text-shadow: 0 6px 3px rgba(96, 85, 243, 0.4);
}
.jyx {
color: white;
font-size: 20px;
margin-top: 87.53px;
font-weight: 400;
}
.msgx {
margin-top: 5px;
color: rgba(255, 255, 255, 0.85);
width: 326px;
text-align: justify;
line-height: 20px;
}
.bottomx {
width: 100px;
height: 1px;
background: rgba(255, 255, 255, 0.85);
margin-top: 40px;
}
}
.rightBox {
// padding-left: 10px;
width: 50%;
.tylx {
cursor: pointer;
width: calc(100% - 20px);
background: rgba(255, 255, 255, 0.95);
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
height: 160px;
margin-top: 83px;
.tyl_titlex {
width: 100%;
padding-left: 20px;
padding-top: 20px;
.tyl_title_imgx {
width: 18px;
height: 18px;
}
.tyl_title_msgx {
font-size: 20px;
margin-left: 10px;
color: #333333;
font-weight: 600;
}
}
.tyl_jyx {
margin-top: 6.5px;
font-size: 14px;
font-weight: 600;
padding-left: 20px;
color: #333333;
}
.tyl_msgx {
width: 350.36px;
margin-top: 13px;
margin-left: 20px;
font-size: 14px;
color: #666666;
font-weight: 400;
letter-spacing: 0;
text-align: justify;
}
}
.tylx:hover {
border: 0.96px solid rgba(140, 105, 242, 1);
box-shadow: 7px 5px 6px 0px rgba(76, 31, 221, 0.3);
}
.cylx {
cursor: pointer;
width: calc(100% - 20px);
background: rgba(255, 255, 255, 0.95);
box-shadow: 0px 2px 12px 0px rgba(0, 0, 0, 0.1);
border-radius: 4px;
height: 160px;
margin-top: 10px;
.tyl_titlex {
width: 100%;
padding-left: 20px;
padding-top: 20px;
.tyl_title_imgx {
width: 18px;
height: 18px;
}
.tyl_title_msgx {
font-size: 20px;
margin-left: 10px;
color: #333333;
font-weight: 600;
}
}
.tyl_jyx {
margin-top: 6.5px;
font-size: 14px;
font-weight: 600;
padding-left: 20px;
color: #333333;
}
.tyl_msgx {
width: 350.36px;
margin-top: 13px;
margin-left: 20px;
font-size: 14px;
color: #666666;
font-weight: 400;
letter-spacing: 0;
text-align: justify;
}
}
.cylx:hover {
border: 0.96px solid rgba(140, 105, 242, 1);
box-shadow: 7px 5px 6px 0px rgba(76, 31, 221, 0.24);
}
}
}
.imgx {
width: 835px;
margin-left: -1px;
margin-top: -1px;
position: absolute;
top: 0px;
}
}
}
.orinfo-text{
font-size: 13px;
color: #666666;
font-weight: 400;
}
.course-resources{
margin-top: 26px;
width:100%;
img{
width: 100%;
height: 100%;
border-radius: 8px;
}
}
.article-banner{
height: 240px;
background: url('../../../../public/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>