Browse Source

feat: auditing comments modal support click into the comment management (#517)

Signed-off-by: Ryan Wang <i@ryanc.cc>
pull/518/head
Ryan Wang 3 years ago committed by GitHub
parent
commit
cb26198d65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      src/components/Comment/CommentListView.vue
  2. 6
      src/components/Comment/TargetCommentListModal.vue
  3. 142
      src/components/Comment/TargetCommentTreeNode.vue
  4. 23
      src/components/Tools/HeaderComment.vue
  5. 7
      src/components/Tools/HeaderCommentTab.vue
  6. 0
      src/components/Tools/index.js
  7. 8
      src/styles/global.less
  8. 43
      src/views/comment/CommentList.vue
  9. 25
      src/views/comment/components/CommentTab.vue

16
src/components/Comment/CommentListView.vue

@ -1,7 +1,12 @@
<template>
<a-list :dataSource="comments" :loading="loading" item-layout="vertical">
<template #renderItem="item, index">
<a-list-item :key="index" class="!p-0">
<a-list-item
:key="index"
class="!p-0"
:class="{ 'hover:bg-gray-100 hover:!px-1 hover:rounded transition-all cursor-pointer': clickable }"
@click="handleClick(item)"
>
<a-comment :avatar="item.avatar">
<template #author>
<a v-if="item.authorUrl" :href="item.authorUrl" class="!text-gray-800 hover:!text-blue-500" target="_blank">
@ -40,6 +45,10 @@ export default {
loading: {
type: Boolean,
default: false
},
clickable: {
type: Boolean,
default: false
}
},
computed: {
@ -73,6 +82,11 @@ export default {
window.open(link, '_blank')
}
}
},
handleClick(item) {
if (this.clickable) {
this.$emit('click', item)
}
}
}
}

6
src/components/Comment/TargetCommentListModal.vue

@ -1,6 +1,6 @@
<template>
<a-modal v-model="modalVisible" :afterClose="onClose" :title="title" :width="1024" destroyOnClose>
<a-spin :spinning="list.loading">
<a-list :loading="list.loading" item-layout="vertical">
<TargetCommentTreeNode
v-for="(comment, index) in list.data"
:key="index"
@ -9,9 +9,7 @@
:target-id="targetId"
@reload="handleGetComments"
/>
</a-spin>
<a-empty v-if="!list.loading && !list.data.length" />
</a-list>
<div class="page-wrapper">
<a-pagination

142
src/components/Comment/TargetCommentTreeNode.vue

@ -1,87 +1,89 @@
<template>
<a-comment>
<template #author>
<a :href="comment.authorUrl" target="_blank">
<a-icon v-if="comment.isAdmin" style="margin-right: 3px" type="user" />
{{ comment.author }}
</a>
</template>
<a-list-item class="!p-0">
<a-comment>
<template #author>
<a :href="comment.authorUrl" target="_blank">
<a-icon v-if="comment.isAdmin" style="margin-right: 3px" type="user" />
{{ comment.author }}
</a>
</template>
<template #avatar>
<a-avatar :alt="comment.author" :src="comment.avatar" size="large" />
</template>
<template #avatar>
<a-avatar :alt="comment.author" :src="comment.avatar" size="large" />
</template>
<template #content>
<div class="comment-modal-content" v-html="$options.filters.markdownRender(comment.content)"></div>
</template>
<template #content>
<div class="comment-modal-content" v-html="$options.filters.markdownRender(comment.content)"></div>
</template>
<template #datetime>
<a-tooltip>
<template #title>
<span>{{ comment.createTime | moment }}</span>
</template>
<span>{{ comment.createTime | timeAgo }}</span>
</a-tooltip>
</template>
<template #datetime>
<a-tooltip>
<template #title>
<span>{{ comment.createTime | moment }}</span>
</template>
<span>{{ comment.createTime | timeAgo }}</span>
</a-tooltip>
</template>
<template #actions>
<a-dropdown v-if="comment.status === 'AUDITING'" :trigger="['click']">
<span>通过</span>
<template #actions>
<a-dropdown v-if="comment.status === 'AUDITING'" :trigger="['click']">
<span>通过</span>
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="handleChangeStatus('PUBLISHED')"> 通过</a-menu-item>
<a-menu-item key="2" @click="handlePublishAndReply"> 通过并回复</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<template #overlay>
<a-menu>
<a-menu-item key="1" @click="handleChangeStatus('PUBLISHED')"> 通过</a-menu-item>
<a-menu-item key="2" @click="handlePublishAndReply"> 通过并回复</a-menu-item>
</a-menu>
</template>
</a-dropdown>
<span v-else-if="comment.status === 'PUBLISHED'" @click="replyModalVisible = true">回复</span>
<span v-else-if="comment.status === 'PUBLISHED'" @click="replyModalVisible = true">回复</span>
<a-popconfirm
v-else-if="comment.status === 'RECYCLE'"
:title="'你确定要还原该评论?'"
cancelText="取消"
okText="确定"
@confirm="handleChangeStatus('PUBLISHED')"
>
还原
</a-popconfirm>
<a-popconfirm
v-else-if="comment.status === 'RECYCLE'"
:title="'你确定要还原该评论?'"
cancelText="取消"
okText="确定"
@confirm="handleChangeStatus('PUBLISHED')"
>
还原
</a-popconfirm>
<a-popconfirm
v-if="comment.status === 'PUBLISHED' || comment.status === 'AUDITING'"
:title="'你确定要将该评论移到回收站?'"
cancelText="取消"
okText="确定"
@confirm="handleChangeStatus('RECYCLE')"
>
回收站
</a-popconfirm>
<a-popconfirm
v-if="comment.status === 'PUBLISHED' || comment.status === 'AUDITING'"
:title="'你确定要将该评论移到回收站?'"
cancelText="取消"
okText="确定"
@confirm="handleChangeStatus('RECYCLE')"
>
回收站
</a-popconfirm>
<a-popconfirm :title="'你确定要永久删除该评论?'" cancelText="取消" okText="确定" @confirm="handleDelete">
删除
</a-popconfirm>
</template>
<a-popconfirm :title="'你确定要永久删除该评论?'" cancelText="取消" okText="确定" @confirm="handleDelete">
删除
</a-popconfirm>
</template>
<template v-if="comment.children">
<TargetCommentTreeNode
v-for="(child, index) in comment.children"
:key="index"
:comment="child"
<template v-if="comment.children">
<TargetCommentTreeNode
v-for="(child, index) in comment.children"
:key="index"
:comment="child"
:target="target"
:target-id="targetId"
@reload="$emit('reload')"
/>
</template>
<CommentReplyModal
:comment="comment"
:target="target"
:target-id="targetId"
@reload="$emit('reload')"
:visible.sync="replyModalVisible"
@succeed="$emit('reload')"
/>
</template>
<CommentReplyModal
:comment="comment"
:target="target"
:target-id="targetId"
:visible.sync="replyModalVisible"
@succeed="$emit('reload')"
/>
</a-comment>
</a-comment>
</a-list-item>
</template>
<script>
import apiClient from '@/utils/api-client'

23
src/components/Tools/HeaderComment.vue

@ -12,7 +12,12 @@
<div class="custom-tab-wrapper">
<a-tabs v-model="activeKey" :animated="{ inkBar: true, tabPane: false }" @change="handleListAuditingComments">
<a-tab-pane v-for="target in targets" :key="target.key" :tab="target.label">
<CommentListView :comments="comments[target.dataKey]" :loading="comments.loading" />
<CommentListView
:comments="comments[target.dataKey]"
:loading="comments.loading"
clickable
@click="handleRouteToCommentList(arguments[0], target)"
/>
</a-tab-pane>
</a-tabs>
</div>
@ -30,6 +35,7 @@
<script>
import apiClient from '@/utils/api-client'
import { commentStatuses } from '@/core/constant'
const targets = [
{
@ -87,6 +93,21 @@ export default {
} finally {
this.comments.loading = false
}
},
handleRouteToCommentList(comment, target) {
this.$log.debug('Handle click auditing comment', comment, target)
const { name } = this.$router.currentRoute
this.$router.push({
name: 'Comments',
query: { activeKey: target.dataKey, defaultStatus: commentStatuses.AUDITING.value }
})
if (name === 'Comments') {
this.$router.go(0)
}
}
}
}

7
src/components/Tools/HeaderCommentTab.vue

@ -1,7 +0,0 @@
<template>
<div></div>
</template>
<script>
export default {}
</script>
<style lang="less" scoped></style>

0
src/components/Tools/index.js

8
src/styles/global.less

@ -518,14 +518,6 @@ body {
}
}
.ant-comment {
.ant-comment-actions {
margin-bottom: 0 !important;
margin-top: 0 !important;
padding-bottom: 0 !important;
}
}
.ant-comment-inner {
.ant-comment-content {
.ant-comment-content-detail {

43
src/views/comment/CommentList.vue

@ -1,15 +1,9 @@
<template>
<page-view>
<div class="card-container">
<a-tabs type="card">
<a-tab-pane key="post" tab="文章">
<comment-tab target="post"></comment-tab>
</a-tab-pane>
<a-tab-pane key="sheet" tab="页面">
<comment-tab target="sheet"></comment-tab>
</a-tab-pane>
<a-tab-pane key="journal" tab="日志">
<comment-tab target="journal"></comment-tab>
<a-tabs v-model="activeKey" type="card">
<a-tab-pane v-for="pane in panes" :key="pane.key" :tab="pane.title">
<comment-tab :target="pane.key" :defaultStatus="defaultStatus"></comment-tab>
</a-tab-pane>
</a-tabs>
</div>
@ -24,6 +18,37 @@ export default {
components: {
PageView,
CommentTab
},
data() {
const panes = [
{ title: '文章', key: 'post' },
{ title: '页面', key: 'sheet' },
{ title: '日志', key: 'journal' }
]
return {
panes,
activeKey: panes[0].key,
defaultStatus: undefined
}
},
beforeRouteEnter(to, from, next) {
// Get post id from query
const activeKey = to.query.activeKey
const defaultStatus = to.query.defaultStatus
next(vm => {
if (activeKey) {
vm.activeKey = activeKey
}
if (defaultStatus) {
vm.defaultStatus = defaultStatus
}
})
},
watch: {
activeKey(newVal) {
const path = this.$router.history.current.path
this.$router.push({ path, query: { activeKey: newVal } }).catch(err => err)
}
}
}
</script>

25
src/views/comment/components/CommentTab.vue

@ -450,6 +450,10 @@ export default {
validator: function (value) {
return ['post', 'sheet', 'journal'].indexOf(value) !== -1
}
},
defaultStatus: {
type: String,
default: undefined
}
},
data() {
@ -466,7 +470,7 @@ export default {
page: 0,
size: 10,
keyword: null,
status: null
status: undefined
}
},
@ -476,9 +480,6 @@ export default {
replyModalVisible: false
}
},
created() {
this.handleListComments()
},
computed: {
pagination() {
return {
@ -512,6 +513,20 @@ export default {
return 0
}
},
watch: {
defaultStatus(status) {
this.list.params.status = status
this.$nextTick(() => {
this.handleListComments()
})
}
},
mounted() {
this.list.params.status = this.defaultStatus
this.$nextTick(() => {
this.handleListComments()
})
},
methods: {
async handleListComments() {
try {
@ -621,7 +636,7 @@ export default {
handleResetParam() {
this.list.params.keyword = null
this.list.params.status = null
this.list.params.status = undefined
this.handleClearRowKeys()
this.handlePageChange(1)
},

Loading…
Cancel
Save