提交 4e7a87ff authored 作者: 王鹏飞's avatar 王鹏飞

feat: 优化课程讨论模块

上级 b3dad309
......@@ -14,7 +14,8 @@
"send": "Send",
"noAnswer": "No answer",
"deleteSuccess": "Delete success",
"answering": "Answer"
"answering": "Answer",
"sendAnswer": "Send"
}
}
}
......@@ -8,13 +8,14 @@
"DiscussDetail": {
"title": "问题详情",
"like": "点赞",
"discuss": "论",
"discuss": "论",
"reply": "回复",
"delete": "删除",
"send": "发",
"send": "发",
"noAnswer": "暂无回答",
"deleteSuccess": "删除成功",
"answering": "回答问题"
"answering": "回答问题",
"sendAnswer": "发布回答"
}
}
}
<template>
<div>
<div class="ask">
<div class="user-1">
<img class="img-1" :src="avatar" />
<div class="right-1">
<div class="name-1">{{ data.replier.nickname }}</div>
<div class="time-1">{{ data.created_time }}</div>
<div class="answer-item">
<div class="user">
<img class="user-avatar" :src="avatar" />
<div class="user-content">
<div class="user-name">{{ data.replier.nickname }}</div>
<div class="user-publishtime">{{ data.created_time }}</div>
</div>
</div>
<div class="text" v-html="contentHtml"></div>
<div class="user">
<template v-if="data.mine">
<div class="right-txt" @click="deleteAnswer(data.id)">{{ $t('pages.learn.discussDetail.delete') }}</div>
</template>
<div class="right-txt" @click="$emit('reply', { answer_id: data.id })">
{{ $t('pages.learn.discussDetail.reply') }}
<div class="answer-content" v-html="contentHtml"></div>
<div class="tools">
<div class="right-txt" @click="toggleLike">
<i class="el-icon-thumb"></i>
{{ $t('DiscussModule.DiscussDetail.like') }}({{ data.tag_count }})
</div>
<div class="right-txt" @click="commentVisible = !commentVisible">
{{ $t('pages.learn.discussDetail.discuss') }}({{ data.comments.length }})
<div class="right-txt" @click="toggleComment">
<i class="el-icon-chat-round"></i>
{{ $t('DiscussModule.DiscussDetail.discuss') }}({{ data.comments.length }})
</div>
<div class="right-txt" @click="$emit('btnlike', { tagId: data.tag ? data.tag.id : null, ansId: data.id })">
{{ $t('pages.learn.discussDetail.like') }}({{ data.tag_count }})
<div class="right-txt" @click="handleDelete(data.id)" v-if="data.mine">
<i class="el-icon-delete"></i>
{{ $t('DiscussModule.DiscussDetail.delete') }}
</div>
</div>
<template v-if="commentVisible">
<!-- 评论列表 -->
<template v-for="item in data.comments">
<reply-item v-on="$listeners" :data="item" :dataId="data.id" :key="item.id"></reply-item>
</template>
</template>
</div>
<comment-list
:detail="detail"
:list="data.comments"
:data="data"
v-on="$listeners"
v-if="commentVisible"
></comment-list>
</div>
</template>
<script>
import * as api from '../api/index.js'
import replyItem from './replyItem.vue'
import commentList from './commentList.vue'
import defaultAvatar from '../assets/images/person-default.jpg'
export default {
components: { replyItem },
components: { commentList },
props: {
data: { type: Object, default: () => {} }
data: { type: Object, default: () => {} },
detail: { type: Object, default: () => {} }
},
data() {
return {
commentVisible: false
commentVisible: false,
publishText: ''
}
},
computed: {
......@@ -56,21 +58,45 @@ export default {
}
},
methods: {
deleteAnswer(id) {
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
api
.deleteAnswer(id)
.then(json => {
this.$emit('updateList')
this.$message({ type: 'success', message: this.$t('pages.learn.discussDetail.deleteSuccess') })
// 点赞
toggleLike() {
const params = {
answer_id: this.data.id,
question_id: this.detail.id,
semester_id: this.detail.semester_id
}
if (this.data.tag) {
// 取消点赞
api.unlike(this.data.tag.id).then(json => {
this.$emit('update')
})
} else {
// 点赞
api.like(params).then(res => {
this.$emit('update')
})
.finally(() => {
loading.close()
}
},
// 评论
toggleComment() {
this.commentVisible = !this.commentVisible
},
// 删除回答
handleDelete(id) {
api.deleteAnswer(id).then(json => {
this.$message({ type: 'success', message: this.$t('DiscussModule.DiscussDetail.deleteSuccess') })
this.$emit('update')
})
}
}
}
</script>
<style lang="sass" scoped>
<style lang="scss" scoped>
.answer-item + .answer-item {
border-top: 1px solid #f6f6f6;
}
.answer-item {
padding-bottom: 20px;
}
</style>
<template>
<div class="comment-list">
<reply-item
v-for="item in list"
:isAnswer="isAnswer"
:detail="detail"
:data="item"
:key="item.id"
v-on="$listeners"
></reply-item>
<!-- 评论框 -->
<div class="comments-publish">
<div class="discuss-publish">
<el-input
class="discuss-publish-textarea"
resize="none"
placeholder="写下你的评论……"
v-model="publishText"
></el-input>
<el-button type="primary" @click="handlePublish">{{ $t('DiscussModule.DiscussDetail.send') }}</el-button>
</div>
</div>
</div>
</template>
<script>
import * as api from '../api/index.js'
import replyItem from './replyItem.vue'
export default {
components: { replyItem },
props: {
list: { type: Array, default: () => [] }, // 评论列表
data: { type: Object, default: () => ({}) }, // 回答数据
detail: { type: Object, default: () => ({}) } // 详情数据
},
data() {
return {
publishText: ''
}
},
computed: {
isAnswer() {
return !!this.data.id
}
},
methods: {
// 发布评论
handlePublish() {
if (!this.publishText) {
return this.$message.error('请输入内容')
}
const params = {
answer_id: this.data.id,
semester_id: this.detail.semester_id,
comments: this.publishText
}
if (this.isAnswer) {
params.questionId = this.detail.id
} else {
params.question_id = this.detail.id
}
api.callbackComment(params).then(res => {
this.publishText = ''
this.$emit('update')
})
}
}
}
</script>
<style lang="scss" scoped>
.comment-list {
margin-top: 20px;
border-radius: 4px;
border: 1px solid #ebebeb;
box-shadow: 0 1px 3px rgb(18 18 18 / 10%);
}
.comments-publish {
border-top: 1px solid #f6f6f6;
padding: 20px;
}
</style>
<template>
<div class="item-list">
<div class="user">
<div class="name">{{data.observer.nickname}}</div>
<div class="time">{{data.created_time}}</div>
<template v-if="data.mine">
<div
class="right-txt"
@click="deleteComment(data.id)"
>{{ $t('pages.learn.discussDetail.delete') }}</div>
</template>
<div class="right-txt" @click="$emit('reply', {to: data.observer.nickname, question_id: dataId})">{{ $t('pages.learn.discussDetail.reply') }}</div>
</div>
<div class="text" v-html="contentHtml"></div>
</div>
</template>
<script>
import * as api from '../api/index.js'
export default {
props: {
data: { type: Object, default: () => {} },
dataId: { type: String, default: () => {} }
},
data() {
return {}
},
computed: {
contentHtml() {
return this.data.comments.replace(/\n/g, '<br />')
}
},
methods: {
deleteComment (id) {
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
api.deleteComment(id).then(json => {
this.$emit('updateList')
this.$message({ type: 'success', message: this.$t('pages.learn.discussDetail.deleteSuccess') })
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
}
}
}
</script>
<template>
<div class="item-list">
<div class="reply-item">
<div class="user">
<div class="name">{{data.observer.nickname}}</div>
<div class="time">{{data.created_time}}</div>
<template v-if="data.mine">
<div
class="right-txt"
@click="deleteComment(data.id)"
>{{ $t('pages.learn.discussDetail.delete') }}</div>
</template>
<div class="right-txt" @click="$emit('reply', {answer_id: dataId, to: data.observer.nickname})">{{ $t('pages.learn.discussDetail.reply') }}</div>
<img class="user-avatar" :src="avatar" />
<div class="user-content">
<div class="user-name">{{ data.observer.nickname }}</div>
<div class="user-publishtime">{{ data.created_time }}</div>
</div>
</div>
<div class="reply-content" v-html="contentHtml"></div>
<div class="tools">
<div class="right-txt" @click="toggleReply">
<i class="el-icon-edit"></i> {{ $t('DiscussModule.DiscussDetail.reply') }}
</div>
<div class="right-txt" v-if="data.mine" @click="handleDelete(data.id)">
<i class="el-icon-delete"></i> {{ $t('DiscussModule.DiscussDetail.delete') }}
</div>
</div>
<div class="discuss-publish" v-if="visible">
<el-input
class="discuss-publish-textarea"
resize="none"
:placeholder="publishPholder"
v-model="publishText"
ref="input"
></el-input>
<el-button type="primary" @click="handlePublish">{{ $t('DiscussModule.DiscussDetail.send') }}</el-button>
</div>
<div class="text" v-html="contentHtml"></div>
</div>
</template>
<script>
import * as api from '../api/index.js'
import defaultAvatar from '../assets/images/person-default.jpg'
export default {
props: {
isAnswer: { type: Boolean, default: false },
data: { type: Object, default: () => {} },
dataId: { type: String, default: () => {} }
detail: { type: Object, default: () => {} }
},
data() {
return {}
return {
visible: false,
publishText: ''
}
},
computed: {
avatar() {
return this.data.observer.avatar || defaultAvatar
},
contentHtml() {
return this.data.comments.replace(/\n/g, '<br />')
},
publishPholder() {
return this.data.mine ? '回复' + this.data.observer.nickname + ':' : '评论'
}
},
methods: {
deleteComment (id) {
const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
// 删除评论
handleDelete(id) {
api.deleteComment(id).then(json => {
this.$emit('updateList')
this.$message({ type: 'success', message: this.$t('pages.learn.discussDetail.deleteSuccess') })
}).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
this.$emit('update')
this.$message({ type: 'success', message: this.$t('DiscussModule.DiscussDetail.deleteSuccess') })
})
},
// 回复
toggleReply() {
this.visible = !this.visible
this.$nextTick(() => {
this.visible && this.$refs.input.focus()
})
},
// 发布
handlePublish() {
if (!this.publishText) {
return this.$message.error('请输入内容')
}
const comments = `回复${this.data.observer.nickname}${this.publishText}`
const params = {
semester_id: this.detail.semester_id,
comments,
to: this.data.observer.nickname
}
if (this.isAnswer) {
params.answer_id = this.data.relate_id
params.questionId = this.detail.id
} else {
params.question_id = this.detail.id
}
api.callbackComment(params).then(res => {
this.visible = false
this.publishText = ''
this.$emit('update')
})
}
}
}
</script>
<style lang="scss" scoped>
.reply-item + .reply-item {
border-top: 1px solid #f6f6f6;
}
.reply-item {
margin: 20px;
}
.discuss-publish {
margin-top: 10px;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论