Files
learning-system-mobile/components/comments/comments.vue
2022-11-15 17:09:30 +08:00

665 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.
<template>
<view>
<u-toast ref="interactToast"></u-toast>
<view class="comments">
<view v-if="showTop" class="comments-top">
<view>
<text style="font-size: 32upx;font-weight: 500;">评论 </text>
<text style="font-size: 28upx;padding-left: 20upx;color: #333;font-weight: 400;"> ({{total}})</text></view>
<view>
<!-- <view v-if="showShare" class="share-btn" @click="addShare">
<view class="share-btn-icon"><img src="/static/images/icon/share.png" alt=""></view>
<view class="share-btn-name">分享</view>
</view> -->
</view>
</view>
<view class="comments-items">
<!--内容确定了这部分样式要移到class中-->
<view v-for="(comm,commidx) in list" :key="commidx" class="comment">
<view class="comment-top">
<author-img :avatar="comm.avatar" :sex="comm.sex" width="30px" height="30px" :size="30"></author-img>
<text style="font-size: 28upx;ont-weight: 500;color: #333333;margin-left: 22upx;">{{comm.sysCreateBy}}</text>
</view>
<view class="comment-body">
<view class="comment-content" v-html="comm.content"></view>
<view class="comment-btns">
<view class="comment-time">
<time-show :time="comm.sysCreateTime"></time-show>
</view>
<view class="" style="display: flex;">
<view style="font-size: 12px;color: #999999;line-height: 60upx;" @click="openInput(commidx)">
<image style="width: 36upx;height: 36upx;vertical-align: middle;margin-right: 10upx;" src="../../static/images/icon/bar-comment.png" size="24"></image>回复
<!-- <u-icon @click="openInput(commidx)" name="chat" color="#979797" size="18" label="回复"></u-icon> -->
</view>
<interact-bar :type="praisesType" :data="comm" :comments="false" :favorites="false"></interact-bar>
</view>
<!-- <view>
<u-icon @click="openInput(commidx)" name="chat" color="#979797" size="18" label="回复"></u-icon>
</view> -->
<!-- <view>
<u-icon @click="openBtns(commidx,-1,comm)" name="more-dot-fill" size="20"></u-icon>
</view> -->
</view>
<view v-if="comm.replyList && comm.replyList.length>0" class="comment-replys">
<view v-for="(reply,replyIdx) in comm.replyList" :key="replyIdx" class="comment">
<view class="comment-top">
<view style="display: flex;">
<author v-if="reply" :showInfo="true" :data="reply"></author>
<!-- <author-info :avatar="reply.avatar" :name="reply.sysCreateBy"></author-info> -->
<!-- <u-avatar shape="square" icon="account" :size="26" :src="reply.avatar"></u-avatar>
<text style="margin-left: 10upx;"> {{reply.sysCreateBy}}</text> -->
<text style="padding-left: 16upx;padding-top: 6upx;color: #979797;font-size: 20upx;"> 回复 </text>
<text style="padding-left: 16upx;padding-top: 6upx;font-size: 26upx;">{{reply.replyName}}</text>
</view>
</view>
<view class="comment-body" style="margin-left: 0;padding-left: 50upx;">
<view class="comment-content" v-html="reply.content"></view>
<view class="" style="display: flex;justify-content: space-between;">
<view class="comment-time">
<time-show :time="reply.sysCreateTime"></time-show>
</view>
<view class="comment-btns" style="line-height: 60upx;">
<view style="font-size: 12px;color: #999999;" @click="openInput(commidx,replyIdx)">
<image style="width: 36upx;height: 36upx;vertical-align: middle;margin-right: 10upx;" src="../../static/images/icon/bar-comment.png" size="24"></image>回复
<!-- <u-icon @click="openInput(commidx)" name="chat" color="#979797" size="18" label="回复"></u-icon> -->
</view>
<interact-bar :data="reply" :type="praisesType" :comments="false" :favorites="false"></interact-bar>
<!-- <view>
<u-icon @click="openInput(commidx,replyIdx)" name="chat" color="#979797" size="18" label="回复"></u-icon>
</view>
<view>
<u-icon @click="openBtns(commidx,replyIdx,reply)" name="more-dot-fill" size="20"></u-icon>
</view> -->
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="total==0 && loadStatus=='noMore'">
<!--提示-->
<view style="text-align: center;padding: 20px;color: #aaaaaa;min-height: 400upx; " >暂无评论</view>
</view>
</view>
<view style="height: 10px;"></view>
</view>
<view v-if="total>pageSize">
<uni-load-more :status="loadStatus"></uni-load-more>
</view>
<u-popup :show="inputShow" @close="closeInput" :round="16">
<view>
<view style="padding: 60upx 30upx;">
<view><u--textarea confirmType="done" style="border: none;background: #F4F4F4;" :height="50" v-model="inputValue" placeholder="请输入内容" count ></u--textarea></view>
<view style="width:160upx;padding-top: 10px;line-height: 80upx;float: right;">
<view style="padding: 20upx;margin-top: 20upx;"><u-button style="padding: 2upx 30upx;height: 52upx;background: #87B3FF;border-color: #87B3FF;" @click="submitReply()" type="primary" text="发布"></u-button></view>
</view>
</view>
<view>
</view>
</view>
</u-popup>
<u-popup :show="btnsShow" @close="closeBtns">
<view>
<view @click="delShow()" class="big-button" v-if="userInfo.aid==commData.sysCreateAid" style="color: #db0000;">删除</view>
<view @click="copy()" class="big-button">复制</view>
<view @click="closeBtns()" class="big-button">取消</view>
</view>
</u-popup>
<u-popup :show="shareInfo.show" @close="closeShare" @open="addShare" mode="right">
<view style="padding: 10px 20px;line-height: 60upx;">
<view style="padding: 10upx;">请输入要分享给人的姓名</view>
<view style="padding: 10upx;">
<u--input placeholder="请输入人员姓名" border="surround" v-model="shareInfo.name"></u--input>
</view>
<view style="padding-top:20upx;">
<u-button @click="findUsers()" type="primary" text="查询"></u-button>
</view>
<view style="padding-top: 50upx;">
<!--查询内容列表-->
<view style="line-height: 60upx;" v-for="(su,suidx) in shareInfo.users" :key="suidx" @click="confirmShare(su)">{{suidx+1}}, {{su.name}} {{su.code}}</view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import apiComment from '@/api/modules/comments.js'
import apiUser from '@/api/system/user.js'
import apiShares from '@/api/modules/shares.js'
import apiStat from '@/api/phase2/stat.js'
import { mapGetters } from 'vuex';
export default {
props:{
showTop:{
type:Boolean,
default:true
},
showShare:{
type:Boolean,
default:true
},
objId:{
type:String,
required:true
},
objType:{
type:Number,
required:true
}
},
computed: {
...mapGetters(['userInfo'])
},
data(){
return {
loadStatus:'more',//more,loading,noMore
pageSize:20,
pageIndex:1,
total:0,
inputShow:false,
inputValue:'',
curCommentIndex:-1,
curReplyIndex:-1,
shareInfo:{
show:false,
name:'',
users:[],
},
btnsShow:false,
list:[],
replyParent:{},
// replyShow:false,
btnsShowRowId:'',
replyInfo:{
clevel:2,
parentId:'',
replyAid:'',
commentId:'',
replyName:'',
objType:'',
objId:'',
content:'',
sex:'',
},
replyDiaglog:{
show:false,
pageIndex:1,
pageSize:30,
count:0,
commentId:'',
list:[]
},
toUserDig:{
show:false,
name:'',
chooseUserId:'',
chooseUserName:'',
list:[]
},
commData:{},
praisesType:0,
}
},
mounted() {
this.loadData(false);
if(this.objType == 1) {
this.praisesType = 10;
}
if(this.objType == 2) {
this.praisesType = 20;
}
if(this.objType == 3) {
this.praisesType = 30;
}
},
methods: {
loadData(append){ //加载数据
let params={
pageIndex:this.pageIndex,
pageSize:this.pageSize,
type:this.objType,
id:this.objId
}
let $this=this;
uni.showLoading({
title:'加载评论...'
})
apiComment.pageQuery(params).then(res=>{
setTimeout(function(){uni.hideLoading()},500);
if(res.status==200){
this.total=res.result.count;
let ids=[];
let allList=[];
res.result.list.forEach(item=>{
item.avatar='';
item.orgInfo='';
item.sex = null;
item.content = item.content.replace(/(\n){2,}/,'<br>');
allList.push(item);
ids.push(item.sysCreateAid);
if(item.replyList && item.replyList!=''){
item.replyList.forEach(reply=>{
reply.avatar='';
reply.orgInfo='';
reply.sex = null;
reply.content = reply.content.replace(/(\n){2,}/,'<br>');
allList.push(reply);
ids.push(reply.sysCreateAid);
})
}
});
this.loadAuthorInfo(allList,ids);
if(append){
res.result.list.forEach(item=>{
$this.list.push(item);
});
}else{
$this.list=res.result.list;
}
if(this.total==0){
this.loadStatus='noMore';
}else if(this.pageIndex>=res.result.totalPages){
this.loadStatus='noMore';
}else{
this.loadStatus='more';
}
}else{
this.$refs.interactToast.show({message:'加载评论失败',type:'error'});
}
});
},
loadAuthorInfo(list,ids){ //加载作者信息,头像,机构信息
if(ids.length==0){
return;
}
const noReapetIds=[...new Set(ids)]
apiUser.getByIds(ids).then(res=>{
if(res.status==200){
list.forEach((item,index)=>{
res.result.some(author=>{
if(author.aid==item.sysCreateAid){
if(item.parentId == "-1" ) {
item.avatar= author.avatar;
} else if(author.avatar != ''){
item.avatar=this.$config.fileUrl + author.avatar;
}
// item.avatar= author.avatar;
item.sex=author.sex;
item.orgInfo=author.orgInfo;
return true;
}else{
return false;
}
})
});
}else{
//console.log('加载用户头像信息:'+res.error);
//this.$message.error(res.message);
}
});
},
submit(){
if(this.inputValue==''){
return;
}
this.inputValue=this.inputValue.replace(/^\s*|\s*$/g,"");
if(this.inputValue==''){
return;
}
if(this.inputValue!=''){
let cdata={
objType:this.objType,
objId:this.objId,
parentId:'-1',
content:this.inputValue,
clevel:1,
toAid:'',
toAname:'',
}
if(this.toUserDig.chooseUserId!=='' && this.toUserDig.chooseUserName!=''){
cdata.toAid=this.toUserDig.chooseUserId;
cdata.toAname=this.toUserDig.chooseUserName;
}
apiComment.add(cdata).then(res=>{
if(res.status==200){
this.list.push(res.result);
//this.$message.success('发布成功');
this.inputValue='';
this.toUserDig.chooseUserId='';
this.toUserDig.chooseUserName='';
}else{
//this.$message.error(res.message);
}
});
}
},
// showReply(item){
// this.replyInfo.objType=this.objType;
// this.replyInfo.objId=this.objId;
// this.replyInfo.parentId=item.id;
// this.replyInfo.replyAid=item.sysCreateAid;
// this.replyInfo.replyName=item.sysCreateBy;
// this.replyShow=true;
// //注意在这里并没有设置commentId,需要在下一步计算
// },
// cancelReply(){
// this.replyInfo.parentId='';
// },
submitReply(){
if(this.inputValue==''){
return;
}
this.inputValue=this.inputValue.replace(/^\s*|\s*$/g,"");
if(this.inputValue==''){
return;
}
this.replyInfo.content=this.inputValue;
let $this=this;
//console.log(this.curCommentIndex,'this.curCommentIndex')
apiComment.reply(this.replyInfo).then(res=>{
if(res.status==200){
this.replyInfo.parentId='';
this.replyInfo.content='';
// this.replyInfo.sex = null;
this.inputValue='';
this.loadData()
// this.loadAuthorInfo([this.result],[res.result.sysCreateAid])
res.result.content = res.result.content.replace(/(\n){2,}/,'<br>');
this.list[this.curCommentIndex].replyList.push(res.result);
this.$refs.interactToast.show({message:'发布成功',type:'success'});
this.inputShow=false;
let event = {
key: "ReplyComment",//后台的事件key 发布文章且审核通过
title: "回复评论",//事件的标题
parameters:"",//用户自定义参数 name:value,name:value
content: "每回一个评论",//事件的内容
objId: this.replyInfo.commentId,//关联的id
objType: "81",//关联的类型
objInfo: "回复评论",
aid: this.userInfo.aid, //当前登录人的id
aname: this.userInfo.name,//当前人的姓名
status: 1 ,//状态直接写1
source:2,
}
apiStat.sendEvent(event);
}else{
this.$refs.interactToast.show({message:'发布失败',type:'error'});
}
});
},
showMoreReply(comment){
this.replyDiaglog.show=true;
this.replyDiaglog.commnetId=comment.id;
this.loadReplyData(false);
},
loadReplyData(append){
let params={
pageIndex:this.replyDiaglog.pageIndex,
pageSize:this.replyDiaglog.pageSize,
type:this.objType,
commentId:this.replyDiaglog.commnetId
}
let $this=this;
apiComment.replyList(params).then(rs=>{
if(rs.status==200){
if(append){
rs.result.list.forEach(item=>{
$this.replyDiaglog.list.push(item);
})
}else{
$this.replyDiaglog.list=rs.result.list;
}
}else{
this.$refs.interactToast.show({message:'加载失败',type:'error'});
}
})
},
addShare(){
//分享
this.shareInfo.show=true;
//默认显示当前内容的作者最好
},
findUsers(){
this.shareInfo.users=[];
//模拟数据
var name=this.shareInfo.name;
if(name==''){
return;
}
apiUser.findByName(name).then(rs=>{
if(rs.status==200){
this.shareInfo.users=rs.result;
}else{
this.$refs.interactToast.show({message:'查询用户失败',type:'error'});
console.log(rs.message);
console.log(rs.error)
}
})
},
confirmShare(u){
let postData={
objType:this.objType,
objId:this.objId,
content:'',
isRead:false,
toAid:u.aid,
toAname:u.name
}
//console.log(postData,'选中的列表');
apiShares.save(postData).then(rs=>{
if(rs.status==200){
this.$refs.interactToast.show({message:'分享成功',type:'success'});
this.shareInfo.show=false;
}else{
console.log(rs.message);
this.$refs.interactToast.show({message:'分享处理失败',type:'error'});
}
});
},
closeShare(){
this.shareInfo.show=false;
},
//回复的事件
openInput(commIdx,replyIdx){
this.curCommentIndex=commIdx;
let comm=this.list[commIdx];
this.replyInfo.commentId=comm.id;
if(replyIdx){
this.curReplyIndex=replyIdx;
let re=comm.replyList[replyIdx];
this.replyInfo.parentId=re.id;
this.replyInfo.replyAid=re.sysCreateAid;
this.replyInfo.replyName=re.sysCreateBy;
this.replyInfo.sex = re.sex;
}else{
this.curReplyIndex=-1;
this.replyInfo.parentId=comm.id;
this.replyInfo.replyAid=comm.sysCreateAid;
this.replyInfo.replyName=comm.sysCreateBy;
this.replyInfo.sex = comm.sex;
}
this.replyInfo.objType=this.objType;
this.replyInfo.objId=this.objId;
this.inputShow=true;
// this.loadAuthorInfo();
// this.loadData()
},
closeInput(){
this.inputShow=false;
},
openBtns(comIdx,itemIdx,com){
this.curCommentIndex=comIdx;
this.curReplyIndex=itemIdx;
this.commData = com;
this.btnsShow=true;
},
closeBtns(){
this.btnsShow=false;
},
delShow(){
this.btnsShow=false;
let $this=this;
uni.showModal({
title: '提示',
content: '您确定要删除所选评论吗?',
success: function (res) {
if (res.confirm) {
$this.del();
} else if (res.cancel) {
}
}
});
},
del(){
//删除
//console.log(this.userInfo);
let comm=this.list[this.curCommentIndex];
if(this.curReplyIndex==-1){
if(comm.replyList.length>0){
this.$refs.interactToast.show({message:'有回复不能删除',type:'error'});
return;
}
//删除评论
let $this=this;
apiComment.del(comm.id,this.userInfo.aid).then(res=>{
if(res.status==200){
this.list.splice(this.curCommentIndex,1);
this.$refs.interactToast.show({message:'删除成功',type:'success'});
this.btnsShow=false;
this.$emit('delSuccess');
}else{
console.log(res.error);
this.$refs.interactToast.show({message:'删除失败',type:'error'});
}
});
}else{
let re=comm.replyList[this.curReplyIndex];
let params={
id:re.id,
user:this.userInfo.aid,
pid:re.parentId
}
apiComment.delReply(params).then(res=>{
if(res.status==200){
comm.replyList.splice(this.curReplyIndex,1);
this.$refs.interactToast.show({message:'删除回复成功',type:'success'});
this.btnsShow=false;
}else{
this.$refs.interactToast.show({message:'删除回复失败',type:'error'});
}
});
}
},
copy(){
let comm=this.list[this.curCommentIndex];
let text=comm.content;
if(this.curReplyIndex>-1){
text=comm.replyList[this.curReplyIndex].content;
}
//复制到剪切版中
uni.setClipboardData({
data:text
});
this.btnsShow=false;
this.$refs.interactToast.show({message:'已复制',type:'success'});
}
}
}
</script>
<style lang="scss" scoped>
.comment{
padding-top: 20upx;
.comment-top{
display: flex;
// justify-content: space-between;
line-height: 50upx;
.comment-avatar{
height: 50upx;
width: 50upx;
border-radius: 10%;
border: 1px solid #f3f3f3;
}
.comment-time{
color: #696969;font-size: 0.9em;
}
}
.comment-body{
margin-left: 22upx;
padding: 0 0upx 0upx 60upx;
color: #373737;
.comment-content{
word-break:break-all;
padding: 0upx 10upx 10upx 0upx;
font-size: 28upx;
color: #666666;
}
.comment-btns{
display: flex;
justify-content: space-between;
padding-top: 10upx;
}
}
}
.comments{
margin-top: 10px;
background-color: #FFFFFF;
padding: 20upx 30upx;
.comments-top{
display: flex;
justify-content: space-between;
padding-bottom:20upx;
border-bottom: 1px solid #f4f4f4;
font-weight: 500;
font-size: 1.1em;
}
.comments-items{
padding-top: 10upx;
}
}
.share-btn{
display: flex;
justify-content: flex-end;
padding-top: 10upx;
line-height: 28upx;
.share-btn-icon{
img{
width: 28upx;
height: 28upx;
}
}
.share-btn-name{
font-size: 28upx;
margin-left: 8upx;
}
}
.big-button{
text-align: center;
line-height: 80upx;
border-top: 1px solid #ebebeb;
}
.txtbtn{
background-color: #e9e9e9;
border: 1px solid #e0e0e0;
padding: 3px 10px;
border-radius: 6px;
font-size: 0.8em;
}
</style>