mirror of https://github.com/halo-dev/halo-admin
feat: perfect post comment drawer component.
parent
90a563b074
commit
6ff6c89050
|
@ -605,6 +605,13 @@ body {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-comment-avatar {
|
||||||
|
img {
|
||||||
|
width: 40px !important;
|
||||||
|
height: 40px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.bottom-control {
|
.bottom-control {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
|
|
|
@ -40,13 +40,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="table-operator" style="margin-bottom: 0;">
|
<div class="table-operator" style="margin-bottom: 0;">
|
||||||
<a-button type="primary" icon="cloud-upload" @click="() => (uploadVisible = true)">上传</a-button>
|
<a-button type="primary" icon="cloud-upload" @click="() => (uploadVisible = true)">上传</a-button>
|
||||||
<a-button type="primary" v-show="!supportMultipleSelection" @click="handleMultipleSelection">
|
<a-button type="primary" icon="select" v-show="!supportMultipleSelection" @click="handleMultipleSelection">
|
||||||
批量操作
|
批量操作
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="primary" v-show="supportMultipleSelection" @click="handleDeleteAttachmentInBatch">
|
<a-button type="danger" icon="delete" v-show="supportMultipleSelection" @click="handleDeleteAttachmentInBatch">
|
||||||
删除
|
删除
|
||||||
</a-button>
|
</a-button>
|
||||||
<a-button type="primary" v-show="supportMultipleSelection" @click="handleCancelMultipleSelection">
|
<a-button icon="close" v-show="supportMultipleSelection" @click="handleCancelMultipleSelection">
|
||||||
取消
|
取消
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -272,7 +272,7 @@ export default {
|
||||||
handleDeleteAttachmentInBatch() {
|
handleDeleteAttachmentInBatch() {
|
||||||
var that = this
|
var that = this
|
||||||
if (this.batchSelectedAttachments.length <= 0) {
|
if (this.batchSelectedAttachments.length <= 0) {
|
||||||
this.$message.success('你还未选择任何附件,先选择一个吧')
|
this.$message.success('你还未选择任何附件,请至少选择一个!')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.$confirm({
|
this.$confirm({
|
||||||
|
|
|
@ -394,8 +394,8 @@
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<a-modal
|
<a-modal
|
||||||
v-if="selectComment"
|
v-if="selectedComment"
|
||||||
:title="'回复给:'+selectComment.author"
|
:title="'回复给:'+selectedComment.author"
|
||||||
v-model="replyCommentVisible"
|
v-model="replyCommentVisible"
|
||||||
@close="onReplyClose"
|
@close="onReplyClose"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
|
@ -421,8 +421,8 @@
|
||||||
</a-modal>
|
</a-modal>
|
||||||
<!-- <CommentDetail
|
<!-- <CommentDetail
|
||||||
v-model="commentDetailVisible"
|
v-model="commentDetailVisible"
|
||||||
v-if="selectComment"
|
v-if="selectedComment"
|
||||||
:comment="selectComment"
|
:comment="selectedComment"
|
||||||
:type="this.type"
|
:type="this.type"
|
||||||
/> -->
|
/> -->
|
||||||
</div>
|
</div>
|
||||||
|
@ -542,7 +542,7 @@ export default {
|
||||||
selectedRowKeys: [],
|
selectedRowKeys: [],
|
||||||
selectedRows: [],
|
selectedRows: [],
|
||||||
comments: [],
|
comments: [],
|
||||||
selectComment: {},
|
selectedComment: {},
|
||||||
replyComment: {},
|
replyComment: {},
|
||||||
loading: false,
|
loading: false,
|
||||||
commentStatus: commentApi.commentStatus,
|
commentStatus: commentApi.commentStatus,
|
||||||
|
@ -595,7 +595,7 @@ export default {
|
||||||
this.handleEditStatusClick(comment.id, 'PUBLISHED')
|
this.handleEditStatusClick(comment.id, 'PUBLISHED')
|
||||||
},
|
},
|
||||||
handleReplyClick(comment) {
|
handleReplyClick(comment) {
|
||||||
this.selectComment = comment
|
this.selectedComment = comment
|
||||||
this.replyCommentVisible = true
|
this.replyCommentVisible = true
|
||||||
this.replyComment.parentId = comment.id
|
this.replyComment.parentId = comment.id
|
||||||
if (this.type === 'posts') {
|
if (this.type === 'posts') {
|
||||||
|
@ -615,7 +615,7 @@ export default {
|
||||||
commentApi.create(this.type, this.replyComment).then(response => {
|
commentApi.create(this.type, this.replyComment).then(response => {
|
||||||
this.$message.success('回复成功!')
|
this.$message.success('回复成功!')
|
||||||
this.replyComment = {}
|
this.replyComment = {}
|
||||||
this.selectComment = {}
|
this.selectedComment = {}
|
||||||
this.replyCommentVisible = false
|
this.replyCommentVisible = false
|
||||||
this.loadComments()
|
this.loadComments()
|
||||||
})
|
})
|
||||||
|
@ -659,7 +659,7 @@ export default {
|
||||||
},
|
},
|
||||||
onReplyClose() {
|
onReplyClose() {
|
||||||
this.replyComment = {}
|
this.replyComment = {}
|
||||||
this.selectComment = {}
|
this.selectedComment = {}
|
||||||
this.replyCommentVisible = false
|
this.replyCommentVisible = false
|
||||||
},
|
},
|
||||||
onSelectionChange(selectedRowKeys) {
|
onSelectionChange(selectedRowKeys) {
|
||||||
|
@ -675,7 +675,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleShowDetailDrawer(comment) {
|
handleShowDetailDrawer(comment) {
|
||||||
this.selectComment = comment
|
this.selectedComment = comment
|
||||||
this.commentDetailVisible = true
|
this.commentDetailVisible = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,12 @@
|
||||||
<a-empty v-if="comments.length==0" />
|
<a-empty v-if="comments.length==0" />
|
||||||
<TargetCommentTree
|
<TargetCommentTree
|
||||||
v-else
|
v-else
|
||||||
v-for="(comment, index) in formattedComments"
|
v-for="(comment, index) in comments"
|
||||||
:key="index"
|
:key="index"
|
||||||
:comment="comment"
|
:comment="comment"
|
||||||
@reply="handleCommentReply"
|
@reply="handleCommentReply"
|
||||||
@delete="handleCommentDelete"
|
@delete="handleCommentDelete"
|
||||||
|
@editStatus="handleEditStatusClick"
|
||||||
/>
|
/>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
|
@ -42,13 +43,38 @@
|
||||||
@change="handlePaginationChange"
|
@change="handlePaginationChange"
|
||||||
></a-pagination>
|
></a-pagination>
|
||||||
</div>
|
</div>
|
||||||
|
<a-modal
|
||||||
|
v-if="selectedComment"
|
||||||
|
:title="'回复给:'+selectedComment.author"
|
||||||
|
v-model="replyCommentVisible"
|
||||||
|
@close="onReplyClose"
|
||||||
|
destroyOnClose
|
||||||
|
>
|
||||||
|
<template slot="footer">
|
||||||
|
<a-button
|
||||||
|
key="submit"
|
||||||
|
type="primary"
|
||||||
|
@click="handleCreateClick"
|
||||||
|
>
|
||||||
|
回复
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
<a-form layout="vertical">
|
||||||
|
<a-form-item>
|
||||||
|
<a-input
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 8 }"
|
||||||
|
v-model="replyComment.content"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
</a-drawer>
|
</a-drawer>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { mixin, mixinDevice } from '@/utils/mixin.js'
|
import { mixin, mixinDevice } from '@/utils/mixin.js'
|
||||||
import TargetCommentTree from './TargetCommentTree'
|
import TargetCommentTree from './TargetCommentTree'
|
||||||
import commentApi from '@/api/comment'
|
import commentApi from '@/api/comment'
|
||||||
import marked from 'marked'
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TargetCommentDrawer',
|
name: 'TargetCommentDrawer',
|
||||||
mixins: [mixin, mixinDevice],
|
mixins: [mixin, mixinDevice],
|
||||||
|
@ -56,6 +82,9 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
comments: [],
|
comments: [],
|
||||||
|
selectedComment: {},
|
||||||
|
replyComment: {},
|
||||||
|
replyCommentVisible: false,
|
||||||
pagination: {
|
pagination: {
|
||||||
page: 1,
|
page: 1,
|
||||||
size: 10,
|
size: 10,
|
||||||
|
@ -105,14 +134,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
|
||||||
formattedComments() {
|
|
||||||
return this.comments.map(comment => {
|
|
||||||
comment.content = marked(comment.content, { sanitize: true })
|
|
||||||
return comment
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
loadComments() {
|
loadComments() {
|
||||||
this.queryParam.page = this.pagination.page - 1
|
this.queryParam.page = this.pagination.page - 1
|
||||||
|
@ -128,9 +149,51 @@ export default {
|
||||||
this.pagination.size = pageSize
|
this.pagination.size = pageSize
|
||||||
this.loadComments()
|
this.loadComments()
|
||||||
},
|
},
|
||||||
handleCommentReply() {},
|
handleCommentReply(comment) {
|
||||||
handleCommentDelete() {},
|
this.selectedComment = comment
|
||||||
|
this.replyCommentVisible = true
|
||||||
|
this.replyComment.parentId = comment.id
|
||||||
|
if (this.type === 'posts') {
|
||||||
|
this.replyComment.postId = comment.post.id
|
||||||
|
} else if (this.type === 'sheets') {
|
||||||
|
this.replyComment.postId = comment.sheet.id
|
||||||
|
} else {
|
||||||
|
this.replyComment.postId = comment.journal.id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleCreateClick() {
|
||||||
|
if (!this.replyComment.content) {
|
||||||
|
this.$notification['error']({
|
||||||
|
message: '提示',
|
||||||
|
description: '评论内容不能为空!'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
commentApi.create(this.target, this.replyComment).then(response => {
|
||||||
|
this.$message.success('回复成功!')
|
||||||
|
this.replyComment = {}
|
||||||
|
this.selectedComment = {}
|
||||||
|
this.replyCommentVisible = false
|
||||||
|
this.loadComments()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleEditStatusClick(comment, status) {
|
||||||
|
commentApi.updateStatus(this.target, comment.id, status).then(response => {
|
||||||
|
this.$message.success('操作成功!')
|
||||||
|
this.loadComments()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleCommentDelete(comment) {
|
||||||
|
commentApi.delete(this.target, comment.id).then(response => {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.loadComments()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onReplyClose() {
|
||||||
|
this.replyComment = {}
|
||||||
|
this.selectedComment = {}
|
||||||
|
this.replyCommentVisible = false
|
||||||
|
},
|
||||||
onClose() {
|
onClose() {
|
||||||
this.comments = []
|
this.comments = []
|
||||||
this.pagination = {
|
this.pagination = {
|
||||||
|
|
|
@ -2,36 +2,100 @@
|
||||||
<div>
|
<div>
|
||||||
<a-comment>
|
<a-comment>
|
||||||
<template slot="actions">
|
<template slot="actions">
|
||||||
<span @click="handleReplyClick">回复</span>
|
<a-dropdown
|
||||||
|
:trigger="['click']"
|
||||||
|
v-if="comment.status === 'AUDITING'"
|
||||||
|
>
|
||||||
|
<span href="javascript:void(0);">通过</span>
|
||||||
|
<a-menu slot="overlay">
|
||||||
|
<a-menu-item key="1">
|
||||||
|
<span
|
||||||
|
href="javascript:void(0);"
|
||||||
|
@click="handleEditStatusClick(comment,'PUBLISHED')"
|
||||||
|
>通过</span>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-item key="2">
|
||||||
|
<span href="javascript:void(0);">通过并回复</span>
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</a-dropdown>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-else-if="comment.status === 'PUBLISHED'"
|
||||||
|
@click="handleReplyClick"
|
||||||
|
>回复</span>
|
||||||
|
|
||||||
|
<a-popconfirm
|
||||||
|
v-else-if="comment.status === 'RECYCLE'"
|
||||||
|
:title="'你确定要还原该评论?'"
|
||||||
|
@confirm="handleEditStatusClick(comment,'PUBLISHED')"
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<span>还原</span>
|
||||||
|
</a-popconfirm>
|
||||||
|
|
||||||
|
<a-popconfirm
|
||||||
|
v-if="comment.status === 'PUBLISHED' || comment.status === 'AUDITING'"
|
||||||
|
:title="'你确定要将该评论移到回收站?'"
|
||||||
|
@confirm="handleEditStatusClick(comment,'RECYCLE')"
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<span>回收站</span>
|
||||||
|
</a-popconfirm>
|
||||||
|
|
||||||
<a-popconfirm
|
<a-popconfirm
|
||||||
:title="'你确定要永久删除该评论?'"
|
:title="'你确定要永久删除该评论?'"
|
||||||
@confirm="handleDeleteClick"
|
@confirm="handleDeleteClick(comment)"
|
||||||
okText="确定"
|
okText="确定"
|
||||||
cancelText="取消"
|
cancelText="取消"
|
||||||
>
|
>
|
||||||
<span>删除</span>
|
<span>删除</span>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
<a slot="author">{{ comment.author }}</a>
|
<a
|
||||||
|
slot="author"
|
||||||
|
:href="comment.authorUrl"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<a-icon
|
||||||
|
type="user"
|
||||||
|
v-if="comment.isAdmin"
|
||||||
|
style="margin-right: 3px;"
|
||||||
|
/>
|
||||||
|
{{ comment.author }}
|
||||||
|
</a>
|
||||||
<a-avatar
|
<a-avatar
|
||||||
|
size="large"
|
||||||
slot="avatar"
|
slot="avatar"
|
||||||
:src="avatar"
|
:src="avatar"
|
||||||
:alt="comment.author"
|
:alt="comment.author"
|
||||||
/>
|
/>
|
||||||
<p slot="content" v-html="comment.content"></p>
|
<p
|
||||||
|
slot="content"
|
||||||
|
v-html="content"
|
||||||
|
></p>
|
||||||
|
<a-tooltip slot="datetime">
|
||||||
|
<span slot="title">{{ comment.createTime | moment }}</span>
|
||||||
|
<span>{{ comment.createTime | timeAgo }}</span>
|
||||||
|
</a-tooltip>
|
||||||
<template v-if="comment.children">
|
<template v-if="comment.children">
|
||||||
<TargetCommentTree
|
<TargetCommentTree
|
||||||
v-for="(child, index) in comment.children"
|
v-for="(child, index) in comment.children"
|
||||||
:key="index"
|
:key="index"
|
||||||
:comment="child"
|
:comment="child"
|
||||||
@reply="handleSubReply"
|
@reply="handleReplyClick"
|
||||||
@delete="handleSubDelete"
|
@delete="handleDeleteClick"
|
||||||
|
@editStatus="handleEditStatusClick"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</a-comment>
|
</a-comment>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import marked from 'marked'
|
||||||
export default {
|
export default {
|
||||||
name: 'TargetCommentTree',
|
name: 'TargetCommentTree',
|
||||||
props: {
|
props: {
|
||||||
|
@ -44,19 +108,19 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
avatar() {
|
avatar() {
|
||||||
return `//cn.gravatar.com/avatar/${this.comment.gravatarMd5}/?s=256&d=mp`
|
return `//cn.gravatar.com/avatar/${this.comment.gravatarMd5}/?s=256&d=mp`
|
||||||
|
},
|
||||||
|
content() {
|
||||||
|
return marked(this.comment.content, { sanitize: true })
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleReplyClick() {
|
handleReplyClick() {
|
||||||
this.$emit('reply', this.comment)
|
this.$emit('reply', this.comment)
|
||||||
},
|
},
|
||||||
handleSubReply(comment) {
|
handleEditStatusClick(comment, status) {
|
||||||
this.$emit('reply', comment)
|
this.$emit('editStatus', comment, status)
|
||||||
},
|
},
|
||||||
handleDeleteClick() {
|
handleDeleteClick(comment) {
|
||||||
this.$emit('delete', this.comment)
|
|
||||||
},
|
|
||||||
handleSubDelete(comment) {
|
|
||||||
this.$emit('delete', comment)
|
this.$emit('delete', comment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -491,7 +491,7 @@
|
||||||
<a-tabs>
|
<a-tabs>
|
||||||
<a-tab-pane
|
<a-tab-pane
|
||||||
tab="发信设置"
|
tab="发信设置"
|
||||||
key="1"
|
key="smtpoptions"
|
||||||
>
|
>
|
||||||
<a-form
|
<a-form
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
|
@ -531,7 +531,7 @@
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
<a-tab-pane
|
<a-tab-pane
|
||||||
tab="发送测试"
|
tab="发送测试"
|
||||||
key="2"
|
key="smtptest"
|
||||||
>
|
>
|
||||||
<a-form
|
<a-form
|
||||||
layout="vertical"
|
layout="vertical"
|
||||||
|
|
Loading…
Reference in New Issue