mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-mobile.git
synced 2025-12-06 17:36:45 +08:00
600 lines
17 KiB
Vue
600 lines
17 KiB
Vue
<template>
|
||
<view class="my-qa-page">
|
||
<u-toast ref="articleToast"></u-toast>
|
||
<page-title :showBack="true" goPgae="/pages/plus/addQuestion">我的问答
|
||
<template #right>
|
||
<p style="width: 100upx;margin-top: 18upx;">去提问</p>
|
||
</template>
|
||
</page-title>
|
||
<view class="top-content">
|
||
<view>
|
||
<u-search
|
||
:clearabled="true"
|
||
@search="search()"
|
||
@clear="search()"
|
||
placeholder="搜索"
|
||
:height="36"
|
||
v-model="keyword"
|
||
:showAction="false">
|
||
</u-search>
|
||
</view>
|
||
</view>
|
||
<view class="my-qa-tabs">
|
||
<view class="tabs-text" @click="tabsClick(1)" :class="{'active':active ==1}"><text style="z-index: 999;">提问</text><text v-show="active ==1" class="active-line"></text></view>
|
||
<view class="tabs-text" @click="tabsClick(2)" :class="{'active':active ==2}">回答<text v-show="active ==2" class="active-line"></text></view>
|
||
</view>
|
||
<view class="my-qa-list" v-show="active ==1">
|
||
<view class="my-qa-index" v-for="(put, index) in putList.list" :key="put.id">
|
||
<view class="artical-box-top">
|
||
<view style="" class="artical-tit" @click="toDetail(put)">
|
||
<text class="qa-basic qa-solve" v-if="put.isResolve">【已解决】</text>
|
||
<text class="qa-basic qa-unSolve" v-else >【待解决】</text>
|
||
<text v-html="$keywordActiveShow(put.title,keyword)"></text>
|
||
</view>
|
||
</view>
|
||
<view class="qa-author-time">
|
||
<view class="author-info">
|
||
<author-info :avatar="put.avatar" :name="put.name" :sex="put.sex"></author-info>
|
||
</view>
|
||
<view class="qa-time">
|
||
{{put.sysCreateTime}}
|
||
</view>
|
||
</view>
|
||
<view class="qa-text" @click="toDetail(put)">
|
||
<view v-html="highlightedFilter(put.content)"></view>
|
||
</view>
|
||
<view style="display: flex;justify-content: space-between;margin-top: 20upx;">
|
||
<view style="display: flex;">
|
||
<view class="rowbtn" @click.stop="toEdit(put)">
|
||
<image class="btn-img" src="../../static/images/icon/edit.png" size="24"></image><text class="btn-text">编辑</text>
|
||
</view>
|
||
<view class="rowbtn" style="margin-left: 12upx;" @click.stop="del(put,index)">
|
||
<image class="btn-img" src="../../static/images/icon/del.png" size="24"></image><text class="btn-text">删除</text>
|
||
</view>
|
||
</view>
|
||
<view class="">
|
||
<interact-bar :comments="false" :answers="true" :views="false" :data="put"></interact-bar>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
<view class="my-answer-list" v-show="active ==2">
|
||
<view class="uni-list">
|
||
<view class="article-one" style="border-bottom: 20upx solid #F9F9F9;" v-for="(item, qidx) of answerList.list" :key="qidx" >
|
||
<view class="artical-box">
|
||
<view>
|
||
<view class="artical-box-top" @click="toanDetail(item)">
|
||
<view style="
|
||
word-break:break-all;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
-webkit-box-orient: vertical;
|
||
display: -webkit-box;-webkit-line-clamp: 1;
|
||
font-size: 36upx;
|
||
font-weight: 600;
|
||
">
|
||
<text class="qa-basic qa-solve" v-if="item.isResolve">【已解决】</text>
|
||
<text class="qa-basic qa-unSolve" v-else >【待解决】</text>
|
||
<text v-html="$keywordActiveShow(item.title,keyword)"></text>
|
||
</view>
|
||
<view class="articl-box-cont">
|
||
<view>
|
||
<text style="color: #333333;font-weight: 600;font-size: 28upx;">我的回答:</text>
|
||
<text style="color: #818181;font-size: 28upx;">{{displayAll(item)}}</text>
|
||
<text style="color: #387DF7;" v-if="item.answercontent.length>60" @click.stop="changeIsAll(item)">
|
||
{{item.isAll?'收起':'展开'}}
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<view class="articl-box-time">
|
||
<view style="padding-top: 10upx;">{{ item.sysCreateTimeA }}</view>
|
||
<view class="rowbtn-right" style="display: flex;">
|
||
<view class="rowbtn rowbtn-primary" @click.stop="editItem(item)">
|
||
<image class="btn-img" src="../../static/images/icon/edit.png" size="24"></image><text class="btn-text">编辑</text>
|
||
</view>
|
||
<view class="rowbtn rowbtn-info" style="margin-left: 20upx;" @click.stop="delItem(item)">
|
||
<image class="btn-img" src="../../static/images/icon/del.png" size="24"></image><text class="btn-text">删除</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<u-popup :show="inputShow" @close="closeInput" @open="openInput" :round="16">
|
||
<view>
|
||
<view style="padding: 60upx 30upx;">
|
||
<view>
|
||
<u--textarea style="border: none;background: #F4F4F4;" :height="50" v-model="inputValue" :plaholder="'回复'" count></u--textarea>
|
||
</view>
|
||
<view style="width:160upx;padding-top: 10px;float: right;height: 120upx;">
|
||
<view>
|
||
<u-button type="primary" @click="publishReply" text="发布" style="padding: 2upx 30upx;height: 52upx;background: #87B3FF;border-color: #87B3FF;"></u-button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view>
|
||
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
<!-- <u-modal :show="modalShow" @confirm="confirm" @cancel="cancel" :showCancelButton="true" confirmText="删除" ref="uModal" :content='content'></u-modal> -->
|
||
<uni-load-more :status="loadStatus"></uni-load-more>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { mapGetters } from 'vuex'
|
||
import apiStat from '@/api/phase2/stat.js';
|
||
import apiQa from '@/api/modules/qa.js';
|
||
import apiUser from '@/api/system/user.js';
|
||
export default {
|
||
computed: {
|
||
...mapGetters(['userInfo']),
|
||
},
|
||
data() {
|
||
return {
|
||
modalShow:false,
|
||
inputShow:false,
|
||
loadStatus:'more',
|
||
active:1,
|
||
keyword:'',
|
||
inputValue: '',
|
||
uCoinRecord:[],
|
||
uinfo: {
|
||
uCurrency: 0 ,// 用户累计U币
|
||
timestamp:'',
|
||
},
|
||
putList:{
|
||
pageIndex:1,
|
||
pageSize:10,
|
||
list:[],
|
||
count:0,
|
||
},
|
||
reply: {},
|
||
answerList:{
|
||
pageIndex:1,
|
||
pageSize:10,
|
||
list:[],
|
||
count:0,
|
||
}
|
||
}
|
||
},
|
||
onPullDownRefresh() {
|
||
this.onReachBottom();
|
||
},
|
||
async onReachBottom() {
|
||
if(this.active == 1) {
|
||
if (this.putList.list.length < this.putList.count) {
|
||
this.loadStatus = 'loading'; //more,loading,noMore
|
||
this.putList.pageIndex++;
|
||
await this.findData(false);
|
||
this.loadStatus = 'more';
|
||
} else {
|
||
this.loadStatus = 'noMore';
|
||
}
|
||
} else {
|
||
if (this.answerList.list.length < this.answerList.count) {
|
||
this.loadStatus = 'loading'; //more,loading,noMore
|
||
this.answerList.pageIndex++;
|
||
await this.findAnData(false);
|
||
this.loadStatus = 'more';
|
||
} else {
|
||
this.loadStatus = 'noMore';
|
||
}
|
||
}
|
||
|
||
},
|
||
mounted() {
|
||
this.findData(true);
|
||
this.findAnData(true);
|
||
},
|
||
|
||
// 实例被激活时使用,用于重复激活一个实例的时候
|
||
// activated () {
|
||
// this.findData(true);
|
||
// },
|
||
|
||
|
||
methods:{
|
||
search() {
|
||
if(this.active == 1) {
|
||
this.putList.pageIndex = 1;
|
||
this.findData(true);
|
||
} else {
|
||
this.answerList.pageIndex=1;
|
||
this.findAnData(true);
|
||
}
|
||
},
|
||
//展示全部
|
||
displayAll(item) {
|
||
// let content = '';
|
||
// content = item.content.replace(/(\n){2,}/,'<br>');
|
||
// item.content = content;
|
||
if(!item.isAll && item.answercontent && item.answercontent.length > 60) {
|
||
return item.answercontent.slice(0, 60) + "...";
|
||
}
|
||
return item.answercontent;
|
||
},
|
||
changeIsAll(item) {
|
||
item.isAll=!item.isAll;
|
||
},
|
||
publishReply() {
|
||
const $this=this;
|
||
let {answerid,content,sysCreateAid,favorites,praises,shares}=this.reply;
|
||
apiQa
|
||
.updateAnswer({id:answerid,sysCreateAid,content:$this.inputValue})
|
||
.then(res => {
|
||
if (res.status == 200) {
|
||
$this.$refs.articleToast.show({message:'修改成功',type:'success'});
|
||
$this.closeInput();
|
||
$this.findAnData(true);
|
||
} else {
|
||
$this.$refs.articleToast.show({message:'修改失败',type:'error'});
|
||
}
|
||
})
|
||
|
||
},
|
||
openInput() {
|
||
this.inputShow = true;
|
||
},
|
||
closeInput() {
|
||
this.inputShow = false;
|
||
},
|
||
delItem(item) {
|
||
const $this=this
|
||
uni.showModal({
|
||
// title: '提示',
|
||
content: '您确定要删除此回答吗?',
|
||
confirmText:"删除",
|
||
success: function (res) {
|
||
if (res.confirm) {
|
||
apiQa
|
||
.delAnswer(item.answerid)
|
||
.then(res => {
|
||
if (res.status == 200) {
|
||
uni.showToast({
|
||
title:'删除成功',
|
||
// duration:500000
|
||
image:'../../static/images/icon/ok-icon.png'
|
||
})
|
||
// $this.$refs.articleToast.show({message:'删除成功',type:'success'});
|
||
$this.findAnData(true);
|
||
} else {
|
||
$this.$refs.articleToast.show({message:'删除失败,请稍后再试',type:'error'});
|
||
}
|
||
})
|
||
}
|
||
}
|
||
});
|
||
},
|
||
editItem(item){
|
||
// this.reply = item;
|
||
// this.inputValue = item.answercontent;
|
||
// this.inputShow=true
|
||
|
||
uni.navigateTo({
|
||
url:'/pages/plus/editAnser?value='+JSON.stringify(item)
|
||
})
|
||
},
|
||
toanDetail(item) {
|
||
uni.navigateTo({
|
||
url: '/pages/resource/qaDetail?id=' + item.answerqid
|
||
|
||
});
|
||
},
|
||
toDetail(item) {
|
||
uni.navigateTo({
|
||
url: '/pages/resource/qaDetail?id=' + item.id
|
||
});
|
||
},
|
||
toEdit(item){
|
||
uni.navigateTo({
|
||
url:'/pages/plus/editQuestion?value='+JSON.stringify(item)
|
||
})
|
||
},
|
||
del(item,index){
|
||
const $this=this
|
||
uni.showModal({
|
||
// title: '提示',
|
||
content: '确认删除这条提问吗?',
|
||
confirmText:"删除",
|
||
success: function (res) {
|
||
if (res.confirm) {
|
||
apiQa.del(item.id).then(res=>{
|
||
if(res.status=200){
|
||
uni.showToast({
|
||
title:'删除成功',
|
||
image:'../../static/images/icon/ok-icon.png'
|
||
})
|
||
// $this.$refs.articleToast.show({message:'删除成功',type:'success'});
|
||
let event = {
|
||
key: "DeleteQuestion",//
|
||
title: "删除提问",//事件的标题
|
||
parameters:"author:"+item.sysCreateAid,//作者参数
|
||
content: "删除提问【"+item.title+"】",//事件的内容
|
||
source:'page',
|
||
objId: item.id,//关联的id
|
||
objType: "2",//关联的类型
|
||
objInfo: item.title,
|
||
aid: $this.userInfo.aid, //当前登录人的id
|
||
aname: $this.userInfo.name,//当前人的姓名
|
||
status: 1 ,//状态,直接写1
|
||
source:2,
|
||
}
|
||
apiStat.sendEvent(event);
|
||
setTimeout(()=>{
|
||
// $this.findData(true)
|
||
$this.putList.list.splice(index, 1);
|
||
},1000)
|
||
}else{
|
||
$this.$refs.articleToast.show({message:'删除失败,请稍后再试',type:'error'});
|
||
}
|
||
})
|
||
} else if (res.cancel) {
|
||
}
|
||
}
|
||
});
|
||
},
|
||
findAnData(flag) {// 回答
|
||
uni.showLoading({ title: '加载中...' });
|
||
if (flag) {
|
||
this.answerList.list = [];
|
||
}
|
||
// const { pageIndex, pageSize, keyWord,isResolve } = this.qaList;
|
||
let params = {
|
||
pageIndex:this.answerList.pageIndex,
|
||
pageSize:this.answerList.pageSize,
|
||
isResolve:this.answerList.isResolve,
|
||
};
|
||
if (this.keyWord) {
|
||
params.keyWord = this.keyWord;
|
||
}
|
||
let $this=this;
|
||
apiQa.queryAnswer(params).then(async res => {
|
||
if (res.status == 200) {
|
||
this.answerList.count = res.result.count;
|
||
let userIds = [];
|
||
res.result.list.forEach(item => {
|
||
item.isAll=false;
|
||
item.avatar='';
|
||
item.name='',
|
||
item.orgInfo='';
|
||
item.sex = null;
|
||
userIds.push(item.sysCreateAid);
|
||
$this.answerList.list.push(item);
|
||
});
|
||
this.loadUserInfos(res.result.list, userIds);
|
||
}else{
|
||
//加载数据列表错误
|
||
this.$refs.messager.show({message:'加载数据失败:'+res.message,type:'error'});
|
||
}
|
||
setTimeout(function(){uni.hideLoading();},100);
|
||
});
|
||
},
|
||
findData(flag) {// 提问
|
||
//是否重置列表
|
||
if (flag) {
|
||
this.putList.list = [];
|
||
}
|
||
uni.showLoading({ title: '加载中...' });
|
||
//查询条件
|
||
let params = {
|
||
pageIndex: this.putList.pageIndex,
|
||
pageSize: this.putList.pageSize,
|
||
keyWord:'',
|
||
isResolve: this.putList.isResolve
|
||
};
|
||
if (this.keyWord != '') {
|
||
params.keyWord = this.keyword;
|
||
}
|
||
apiQa.queryQuestion(params).then(async rs => {
|
||
if (rs.status == 200) {
|
||
if (rs.result.list.length != 0) {
|
||
this.putList.count = rs.result.count;
|
||
let userIds = [];
|
||
rs.result.list.forEach(item => {
|
||
item.avatar='';
|
||
item.name='',
|
||
item.orgInfo='';
|
||
item.sex = null;
|
||
this.putList.list.push(item);
|
||
userIds.push(item.sysCreateAid);
|
||
});
|
||
await this.loadUserInfos(rs.result.list, userIds);
|
||
}
|
||
}
|
||
uni.hideLoading();
|
||
}).catch((err)=>{
|
||
uni.hideLoading();
|
||
});
|
||
},
|
||
loadUserInfos(list, userIds) {
|
||
const noReapetIds = [...new Set(userIds)];
|
||
apiUser.getByIds(noReapetIds).then(res => {
|
||
if (res.status == 200) {
|
||
list.forEach(item => {
|
||
res.result.some(author => {
|
||
if (author.aid == item.sysCreateAid) {
|
||
let { aid, avatar, name, orgInfo, code,sex } = author;
|
||
// if (!avatar) {
|
||
// avatar = this.$config.fileUrl + avatar;
|
||
// }
|
||
item.name = name;
|
||
item.aid = aid;
|
||
item.orgInfo = orgInfo;
|
||
item.code = code;
|
||
item.avatar = avatar;
|
||
item.sex = sex;
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
});
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: '获取数据失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
//原本想用async await等数据请求完成后使用hideLoading,但是页面渲染需要时间,关闭太早了,有考虑用nexeTick()
|
||
setTimeout(function() {
|
||
uni.hideLoading();
|
||
}, 1000);
|
||
});
|
||
},
|
||
findList(){
|
||
|
||
},
|
||
tabsClick(tab) {
|
||
this.keyword = '';
|
||
this.active=tab
|
||
},
|
||
highlightedFilter(value) {
|
||
if (value.indexOf(this.copyKeyWord) !== -1 && this.copyKeyWord !== '') {
|
||
return value.replace(this.copyKeyWord,`<span class='highlighted'>${this.copyKeyWord}</span>`);
|
||
}else{
|
||
return value
|
||
}
|
||
},
|
||
|
||
}
|
||
|
||
}
|
||
</script>
|
||
<style scoped lang="scss">
|
||
.qa-solve{
|
||
color: #333333;
|
||
margin-left:-7px;
|
||
}
|
||
.qa-unSolve{
|
||
margin-left:-7px;
|
||
color:#387DF7;
|
||
}
|
||
|
||
.my-qa-page{
|
||
padding: 36upx;
|
||
background-color: #fff;
|
||
.rowbtn{
|
||
padding: 5px 8px 0px 0;
|
||
height: 20px;
|
||
border-radius: 10upx;
|
||
.btn-img{
|
||
width: 16px;
|
||
height: 18px;
|
||
vertical-align: middle;
|
||
}
|
||
.btn-text{
|
||
margin-left: 12upx;
|
||
font-size: 24upx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
.my-qa-tabs{
|
||
display: flex;
|
||
margin-top: 40upx;
|
||
.tabs-text{
|
||
margin: 0 44upx 0 4upx;
|
||
font-size: 32upx;
|
||
color: #666666;
|
||
}
|
||
.active{
|
||
font-size: 32upx;
|
||
font-weight: 600;
|
||
color: #333333;
|
||
position: relative;
|
||
.active-line{
|
||
z-index: 1;
|
||
position: absolute;
|
||
display: inline-block;
|
||
bottom: -4upx;
|
||
left: -4upx;
|
||
width: 70upx;
|
||
height: 10upx;
|
||
background: linear-gradient(270deg, #46ACFF 0%, #1E68F9 100%);
|
||
border-radius: 6upx;
|
||
}
|
||
}
|
||
}
|
||
.my-qa-list{
|
||
margin-top: 12upx;
|
||
.my-qa-index{
|
||
padding-bottom: 36upx;
|
||
border-bottom: 20upx solid #F9F9F9;
|
||
}
|
||
.artical-box-top {
|
||
padding: 36upx 0;
|
||
font-weight: 600;
|
||
line-height: 50upx;
|
||
.artical-tit{
|
||
word-break:break-all;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
-webkit-box-orient: vertical;
|
||
display: -webkit-box;-webkit-line-clamp: 2;
|
||
font-size: 36upx;
|
||
color: #333333;
|
||
}
|
||
|
||
}
|
||
.qa-author-time{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 34upx;
|
||
.qa-time{
|
||
margin-top: 14upx;
|
||
}
|
||
}
|
||
.qa-text{
|
||
font-size: 28upx;
|
||
color: #666666;
|
||
word-break:break-all;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
-webkit-box-orient: vertical;
|
||
display: -webkit-box;-webkit-line-clamp: 2;
|
||
}
|
||
.qa-time{
|
||
font-size: 24upx;
|
||
color: #999999;
|
||
}
|
||
}
|
||
.artical-box {
|
||
// margin-top: 20upx;
|
||
color: #151515;
|
||
padding: 36rpx 0 26rpx 0;
|
||
background-color: #ffffff;
|
||
.artical-box-top {
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
// line-height: 60rpx;
|
||
// margin-top: 10rpx;
|
||
}
|
||
.articl-box-cont {
|
||
font-size: 28rpx;
|
||
// line-height: 50rpx;
|
||
color: #454545;
|
||
margin-top: 30upx;
|
||
// margin: 0upx 10upx;
|
||
// overflow: hidden;
|
||
// text-overflow: ellipsis;
|
||
// -webkit-box-orient: vertical;
|
||
// display: -webkit-box;-webkit-line-clamp: 2;
|
||
word-break:break-all;
|
||
}
|
||
.articl-box-time {
|
||
margin-top: 10upx;
|
||
font-size: 26rpx;
|
||
color: #999999;
|
||
// padding: 20rpx 0;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
}
|
||
}
|
||
}
|
||
</style>
|