Files
learning-system-portal/src/views/portal/qa/Index.vue

779 lines
23 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.
<template>
<div id="qa-list-content" class="qa-list-content">
<div class="qa-banner">
<portal-header current="qa" class="qa-nav" @emitInput="emitInput"></portal-header>
</div>
<div class="portal-content">
<div class="xcontent2">
<div class="xcontent2-main" style="margin-right: 30px;background-color: #fff;padding-top: 50px;">
<div>
<div class="left-div">
<div class="order-div">
<span class="quyer-tag">
<el-button type="text" class="order-class" @click="orderFieldData('answers')" :class="{ actice: styleControl == 2 }">
最热
</el-button>
<el-button type="text" class="order-class" @click="orderFieldData('')" :class="{ actice: styleControl == 1 }">
最新
</el-button>
<el-button type="text" @click="setEssence(queryConditions.isEssence)" class="order-class" :class="{ actice: styleControl == 3 }">精华问题</el-button>
</span>
<span class="quyer-tag">
<el-button type="text" class="order-class" @click="isResolveData(null)" :class="{ actice: queryConditions.isResolve === null }">
全部
</el-button>
<el-button type="text" class="order-class" @click="isResolveData(false)" :class="{ actice: queryConditions.isResolve === false }">
待解决
</el-button>
<el-button type="text" @click="isResolveData(true)" class="order-class" :class="{ actice: queryConditions.isResolve===true }">已解决</el-button>
</span>
</div>
<div class="data-content" v-if="qaList.length > 0">
<div :span="24" v-for="(qa, qaidx) in qaList" :key="qaidx" class="qa-list">
<div class="qa-info-box">
<div class="qa-info">
<div class="qa-info-title" @click="jumpDetail(qa)">
<div class="portal-title-tow one-line-ellipsis">
<span v-if="qa.isResolve == false" @click="searchData()">待解决</span>
<span class="qa-basic qa-solve" v-if="qa.isResolve == true" @click="searchData()">已解决</span>
<span v-html="$keywordActiveShow(qa.title,queryKeyWord)"></span>
</div>
<div class="portal-time">
<i class="el-icon-time" style="margin-right:4px"></i> {{qa.sysCreateTime}}
</div>
</div>
<div style="display: flex;justify-content:space-between;">
<div class="qa-info-summary portal-summary-text two-line-ellipsis" @click="jumpDetail(qa)" v-html="$keywordActiveShow(qa.content,queryKeyWord)"></div>
<div style="cursor: pointer; text-align: right;cursor: pointer;" v-if="qa.images!==''" @click="jumpDetail(qa)">
<img style="width: 156px;height: 105px;border-radius: 4px;margin-left: 18px;" :src="fileBaseUrl + qa.images" alt="">
</div>
</div>
<div style="display: flex;justify-content:space-between;">
<div style="width: 120px;">
<author :avatar="qa.authorInfo.avatar" :name="qa.authorInfo.name" :sex="qa.authorInfo.sex"></author>
</div>
<div><interactBar nodeWidth="60px" :readonly="true" :type="4" :data="qa" @addAnswers="qaAnswer(qa)" :shares="true" :comments="false" :answers="true" :clickAnswer="true" :views="false"></interactBar></div>
</div>
</div>
</div>
</div>
</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 style="padding:0" id="qa-fixd">
<div class="portal-model-btn pointer" @click="$refs.addQuestion.askQuestionDialog = true">
<svg-icon style="margin-right: 0;font-size: 24px;" icon-class="question-mark"></svg-icon>
提问题
</div>
<div class="portal-ranking ranking-bg">
<p class="ranking-title">贡献榜</p>
<ul class="ranking-data">
<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 class="course-resources">
<!-- 资源位 -->
<img :src="fileBaseUrl + resonimg.image" alt="">
</div>
</div>
<!-- </div> -->
</div>
</div>
<addQuestion ref="addQuestion" @sure="getQaData(true)"></addQuestion>
</div>
<!-- :before-close="handleClose" -->
<el-dialog title="快速回答" :visible.sync="dialogVisible" width="600px" :close-on-click-modal="false">
<div>
<el-input type="textarea" :rows="5" maxlength="800" placeholder="写下您的答案(800字以内)" v-model="answer.inputValue"></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" v-loading="loading" @click="publishAnswer()"> </el-button>
</span>
</el-dialog>
<portal-footer></portal-footer>
<portalFloatTools @sure="getQaData(true)"></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 WxEditor from '@/components/Editor/index.vue';
import interactBar from '@/components/Portal/interactBar.vue';
import timeShow from '@/components/Portal/datetimeShow.vue';
import author from '@/components/Portal/authorInfo.vue';
import addQuestion from '@/components/Qa/addQuestion.vue';
import apiQa from '@/api/modules/qa.js';
import apiUser from '@/api/system/user.js';
import apiSearchterm from '@/api/modules/searchterm.js';
import apiPlace from "@/api/phase2/place.js"
export default {
name: 'qaindex',
components: { portalHeader, portalFooter, portalFloatTools, WxEditor, addQuestion, author, interactBar, timeShow },
computed: {
...mapGetters(['userInfo']),
},
// watch:{
// 'queryConditions.isEssence':{
// handler:function(newName,oldName){
// if(newName){
// this.queryConditions.orderField='null'
// }else{
// // this.queryConditions.isEssence=''
// this.queryConditions.orderField='id'
// }
// }
// }
// },
data() {
return {
resonimg:{},
fileBaseUrl: process.env.VUE_APP_FILE_BASE_URL,
loading: false,
answer:{
id: '',
inputValue: '',
},
dialogVisible: false,
moreState:1,// 1 加载更多 2 加载中 3无数据
searchRecords: [],
queryConditions: {
pageIndex: 1,
pageSize: 10,
keyword: '',
isResolve: null,
isEssence: '',
orderField: '',
orderAsc: false
}, //传参所需要的数据
queryKeyWord: '',
//因为不需要这个数据不是跟随input框值变化请求所以拿出来了
count: 0, //页面总条数
qaList: [], //问答详情列表
//以上是整理后的数据
anking: 2, //排行榜
ankingList: [],
styleControl:2,
isSeach:false,
};
},
mounted() {
this.queryKeyWord = this.$route.query.keyword;
this.queryConditions.keyword = this.queryKeyWord;
if(this.queryConditions.keyword != '') {
this.isSeach = true;
}
this.getQaData(true);
this.getAnkingData();
window.addEventListener("scroll", this.handleScroll);
this.searchterm();
this.couresreso();
},
beforeDestroy(){
window.removeEventListener("scroll",this.handleScroll);
},
methods: {
couresreso(){
let key = 'qa';
apiPlace.detail(key).then(res=>{
console.log(res)
let lmj = JSON.parse(res.result.content)
this.resonimg = lmj[0]
console.log(this.resonimg.image)
})
},
emitInput(val){
this.queryKeyWord = val;
this.isSeach =true;
this.search();
},
//发布回答
publishAnswer() {
if (this.answer.inputValue < 1 ) {
return this.$message.warning('请输入回答');
}
this.loading = true;
apiQa
.saveAnswer({
qid: this.answer.id,
content: this.answer.inputValue.trim()
})
.then(res => {
if (res.status == 200) {
this.loading = false;
// this.messageSave('send')
this.$message({
message: '发布回答成功',
type: 'success'
});
this.dialogVisible=false
// this.getQuestionDetail();
// this.loadAnswer();
this.getQaData(true);
this.answer.inputValue = '';
} else {
this.loading = false;
this.$message({
message: res.message,
type: 'error'
});
}
})
},
qaAnswer(qa) {
this.answer.id = qa.id;
this.dialogVisible = true;
},
handleScroll(){
let innerHeight = document.querySelector('#qa-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);
}
}
if(scrollTop > 400) {
document.querySelector('#qa-fixd').style.cssText = "position: fixed;top: 0px;width:410px;";
} else {
document.querySelector('#qa-fixd').style.cssText = "position: static";
}
},
isResolveData(num) {
this.queryConditions.isResolve=num;
this.queryConditions.pageIndex = 1
this.qaList = [];
this.getQaData(true);
},
debounce(func, wait) {// 非立即执行
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
},
setEssence(val){
this.styleControl = 3
this.queryConditions.orderField = '';
this.queryConditions.isEssence=true
this.getQaData(true);
},
orderFieldData(id) {
this.queryConditions.isEssence=''
if(id==""){
this.styleControl = 1
}
if(id=="answers"){
this.styleControl = 2
}
this.queryConditions.orderField = id;
this.queryConditions.pageIndex = 1
this.qaList = [];
this.getQaData(true);
},
searchData() {
this.queryConditions.pageIndex = 1
this.qaList = [];
this.getQaData(true);
},
useHotword(item) {
this.queryConditions.pageIndex = 1
this.queryKeyWord = item.keyword;
this.queryConditions.keyword = this.queryKeyWord;
this.qaList = [];
this.getQaData(false);
},
searchterm() {
apiSearchterm.list(5, 4).then(res => {
if (res.status === 200) {
this.searchRecords = res.result;
}
});
},
loadMore() {
this.queryConditions.pageIndex += 1;
this.getQaData(false);
},
search() {
apiSearchterm.save({ keyword: this.queryKeyWord, type: 4 });
//this.listType=2;
this.queryConditions.pageIndex = 1;
this.qaList = [];
this.queryConditions.keyword = this.queryKeyWord;
this.getQaData(false);
},
//分页查询
handleSizeChange(item) {
this.queryConditions.pageSize = item;
},
handleCurrentChange(item) {
this.queryConditions.pageIndex = item;
},
async getQaData(flag) {
if(flag){
this.qaList=[];
this.queryConditions.pageIndex=1;
}
this.queryConditions.orderField=this.styleControl==1? 'id':'answers';
this.moreState = 2;
await apiQa
.potallist(this.queryConditions)
.then(res => {
if (res.status == 200 && res.result.list.length > 0) {
this.isSeach = false;
res.result.list.forEach(item => {
item.authorInfo = { aid: '', name: '', orgInfo: '', avatar: '',sex:null, };
});
this.count = res.result.count;
let ids = [];
res.result.list.forEach(item => {
item.authorInfo = { name: '', avatar: '', orgInfo: '',sex:null, };
ids.push(item.sysCreateAid);
});
this.getQaUserData(res.result.list,ids);
this.qaList.push(...res.result.list);
this.moreState = 1;
if(res.result.count == res.result.list.length) {
this.moreState = 3;
}
} else {
this.moreState = 3;
// this.$message.error(res.message);
}
})
.catch(err => {
console.log(err);
});
},
getQaUserData(qaList,ids) {
const noReapetIds = [...new Set(ids)];
apiUser.getByIds(noReapetIds).then(res => {
if (res.status == 200) {
qaList.forEach((item, index) => {
res.result.some(author => {
if (author.aid == item.sysCreateAid) {
item.authorInfo = author;
return true;
} else {
return false;
}
});
});
//以下代码有顺序问题,而且如果返回的字段有相同的名称,也会有问题
// this.qaList=qaList.map((item,index)=>{
// item=Object.assign(item,res.result[index])
// return item
// })
} else {
// this.$message.error(res.message);
}
});
},
jumpDetail(data) {
this.$router.push({ path: '/qa/answer', query: { id: data.id } });
},
getAnkingData() {
apiQa.queryList(5).then(res => {
if (res.status == 200) {
this.ankingList = res.result;
}
});
}
}
};
</script>
<style scoped lang="scss">
::v-deep.el-input__inner {
background-color: #fff !important;
}
::v-deep .top-nav{
color: #333;
}
::v-deep .current-nav{
font-weight: 500 !important;
color: #387DF7 !important;
}
::v-deep .el-dropdown-link{
color: #333 !important;
}
::v-deep .nav-bottbor{
background: #387DF7 !important;
}
.course-resources{
width: 410px;
margin-top: 26px;
img{
border-radius: 8px;
width: 100%;
height: 100%;
}
}
.qa-banner{
height: 240px;
background: url('/images/qa-banner.png');
}
.el-card{
border: none;
}
::v-deep .bacolor:nth-child(odd){
background-color: #fff;
padding: 0 5px;
}
::v-deep .bacolor:nth-child(even){
background-color: #f6f6f6;
padding: 0 5px;
}
.qa-isresolve {
color: #08A890;
margin-left: -10px;
// left: -50px;
}
.qa-unresolve {
color: #588afc;
margin-left: -10px;
// left: -50px;
}
.qa-title-text {
font-size: 18px;
line-height: 25px;
font-weight: 600;
color: #121212;
flex: 1;
}
.checkboxbutton {
outline: none;
}
.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;
}
.two-line-ellipsis {
display: -webkit-box;
white-space:pre-wrap;
overflow: hidden;
text-overflow:ellipsis;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
box-sizing: border-box;
}
.searchbar {
background-color: #ffffff;
border: 1px solid #f3f3f3;
width: 1200px;
padding: 5px 20px;
}
.fixed {
position: fixed;
top: 0px;
background-color: #f0f0f0;
z-index: 999;
height: 50px;
}
.left-div {
.quyer-tag {
.order-class{
padding:4px 8px;
color: #6E7B84;
line-height: 20px;
border-radius: 0px;
}
.actice {
border: 0px;
background: #387DF7;
color: #fff;
font-size: 14px;
border-radius: 4px;
}
}
.more {
float: right;
display: block;
}
/* 分页div */
.pagination-div {
text-align: center;
padding: 10px 0;
}
.order-div {
margin-top: 50px;
padding: 0 40px;
background-color: #fff;
display: flex;
.quyer-tag{
&:last-of-type{
margin-left: auto;
}
}
// justify-content: space-between;
}
.data-content {
background-color: #fff;
padding: 5px 50px;
min-height: 382px;
::v-deep .interact-bar-btns{
.interact-bar-btn{
text-align: right;
min-width: 78px !important;
}
}
.qa-list:last-child {
border-bottom: none;
}
.qa-list {
// margin: 5px 0;
padding: 33px 0 ;
// padding-bottom: 10px;
// padding-left: 10px;
padding-right: 0px;
margin-right:10px;
border-bottom: 1px solid rgba(153, 153, 153,.2);
}
.qa-info-box {
.qa-info {
.qa-info-title {
cursor: pointer;
font-size: 16px;
height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
.qa-info-date {
margin-left: 30px;
height: 30px;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 200;
color: #999999;
font-size: 12px;
i {
margin-right: 5px;
}
}
}
.qa-info-re{
color: #3e7fff;
font-size: 14px;
line-height: 30px;
}
.qa-info-summary {
cursor: pointer;
line-height: 20px;
margin: 12px 0 27px 0;
// color: #121212;
// height: 45px;
// font-size: 15px;
word-break: break-all;
}
.qa-info-tools {
height: 30px;
.qa-info-tools-auth {
float: left;
font-size: 13px;
color: #999999;
img {
margin-right: 10px;
width: 30px;
border: 1px solid #eee;
border-radius: 50%;
vertical-align: middle;
}
}
.qa-info-tools-btns {
float: right;
.qa-info-tools-btn {
margin: 0 0 0 15px;
}
}
}
}
}
}
}
.search-div {
// background: #fff;
// padding: 10px 25px 0 25px;
padding: 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;
}
}
// .input-with-select {
// .tip {
// line-height: 35px;
// font-size: 14px;
// color: #666;
// }
// }
// .add-btn {
// width: 100%;
// height: 100%;
// }
}
.tag-class {
border-radius: 15px;
margin: 0 10px;
}
.add-tag {
padding: 7px 25px;
}
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload--picture-card {
width: 200px;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
text-align: center;
margin-top: 50px;
display: block;
}
.icon-text {
font-size: 14px;
display: block;
height: 30px;
line-height: 35px;
}
// .avatar {
// width: 250px;
// height: 178px;
// display: block;
//
//padding-left: 10px;
.add-btn {
width: 100%;
padding: 0px 0;
}
.ranking-title {
line-height: 34px;
.center-titlt {
font-size: 15px;
color: #333333;
}
.center {
text-align: center;
}
img{
margin-top: 5px;
}
}
.ranking-data {
margin: 10px 0;
color: #999999;
}
::v-deep .imageUrls {
.el-form-item__content {
display: flex;
justify-content: flex-start;
align-items: center;
.imageUrl {
display: flex;
justify-content: flex-start;
align-items: center;
img {
margin-right: 8px;
width: 148px;
height: 148px;
}
}
}
}
</style>