Commit 3a7882f6 by lijiabin

【需求 21402】 feat: 文章评论区加入发布者本人删除评论功能

parent 7e251560
......@@ -135,6 +135,7 @@
<span class="font-semibold text-gray-800">{{
isReal ? item.replyUser : item.hiddenName
}}</span>
<span
v-if="item.isTop === BooleanFlag.YES"
class="inline-flex items-center gap-1 px-2 py-0.5 text-13px leading-4 font-medium text-amber-700 bg-amber-50/80 border border-amber-200/70 rounded-full"
......@@ -150,6 +151,13 @@
>
{{ item.floorNumber || '顶' }}楼
</span>
<button
v-if="isSelfComment(item)"
class="cursor-pointer text-red-500 text-xs leading-none"
@click="handleDeleteComment(item)"
>
删除
</button>
</div>
<!-- 作者有权利置顶 并且不是问吧(问吧是获取的二级评论列表) -->
<button
......@@ -249,10 +257,17 @@
child.replyUser
}}</span>
<!-- v-if="item.replyName && item.replyName !== parentComment?.replyUser" -->
<span class="text-gray-500 text-sm flex items-center gap-1">
<span class="text-gray-500 text-sm flex items-center gap-1 px-1">
<el-icon class="mx-1"><IEpCaretRight /></el-icon>
{{ child.replyName }}
</span>
<button
v-if="isSelfComment(child)"
class="cursor-pointer text-red-500 text-xs leading-none"
@click="handleDeleteComment(child)"
>
删除
</button>
</div>
<p
class="text-gray-800 my-2 break-all whitespace-pre-wrap text-[16px]"
......@@ -430,8 +445,9 @@ import {
getCommentChildren,
getSecondCommentList,
topOrCancelTopComment,
deleteComment,
} from '@/api'
import { usePageSearch, useScrollTop } from '@/hooks'
import { useMessageBox, usePageSearch, useScrollTop } from '@/hooks'
import { ArticleTypeEnum, BooleanFlag } from '@/constants'
import type { CommentItemDto } from '@/api'
import { useUserStore } from '@/stores'
......@@ -445,6 +461,7 @@ import { push } from 'notivue'
import { IS_REAL_KEY_COMMENT, CommentSortTypeEnum } from '@/constants'
const { jumpToUserHomePage } = useNavigation()
const { confirm } = useMessageBox()
const {
authorId = '',
id,
......@@ -556,6 +573,8 @@ const myCommentImgStr = ref('')
const commentToOtherImgStr = ref('')
const currentCommentId = ref(-1)
const myCommentBoxRef = useTemplateRef<InstanceType<typeof CommentBox>>('myCommentBoxRef')
const isSelfComment = (item: CommentItemDto) =>
String(item.userId || '') === String(userInfo.value.userId || '')
const handleLickComment = async (item: CommentItemDto) => {
await addOrCancelCommentLike(item.id)
......@@ -570,6 +589,18 @@ const handleLickComment = async (item: CommentItemDto) => {
}
}
const handleDeleteComment = async (item: CommentItemDto) => {
await confirm({
title: '提示',
message: '确定删除该评论吗?',
type: 'danger',
})
await deleteComment(item.id)
push.success('删除成功')
await search()
emit('commentSuccess')
}
const highlightCommentId = ref<number | null>(null)
const topCommentPendingId = ref<number | null>(null)
const handleTopComment = async (item: CommentItemDto) => {
......
......@@ -36,16 +36,27 @@
/>
<div class="flex-1">
<div class="flex items-center justify-between mb-2">
<span class="font-bold text-gray-900 text-base">{{ parentComment.replyUser }}</span>
<!-- 点赞按钮 -->
<div
class="flex items-center gap-1.5 cursor-pointer text-gray-500 hover:text-blue-500 transition-colors px-3 py-1.5 rounded-full hover:bg-blue-50"
@click="handleLike(parentComment)"
>
<el-icon :size="18">
<svg-icon :name="parentComment.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span class="text-sm font-medium">{{ parentComment.postPriseCount || 0 }}</span>
<div class="flex items-center gap-1.5">
<span class="font-bold text-gray-900 text-base">{{ parentComment.replyUser }}</span>
<button
v-if="isSelfComment(parentComment)"
class="cursor-pointer text-red-500 text-13px leading-none"
@click="handleDeleteComment(parentComment, true)"
>
删除
</button>
</div>
<div class="flex items-center gap-3">
<!-- 点赞按钮 -->
<div
class="flex items-center gap-1.5 cursor-pointer text-gray-500 hover:text-blue-500 transition-colors px-3 py-1.5 rounded-full hover:bg-blue-50"
@click="handleLike(parentComment)"
>
<el-icon :size="18">
<svg-icon :name="parentComment.hasPraise ? 'praise_fill' : 'praise'"></svg-icon>
</el-icon>
<span class="text-sm font-medium">{{ parentComment.postPriseCount || 0 }}</span>
</div>
</div>
</div>
......@@ -101,6 +112,13 @@
<el-icon class="mx-1"><IEpCaretRight /></el-icon>
{{ item.replyName }}
</span>
<button
v-if="isSelfComment(item)"
class="cursor-pointer text-red-500 text-13px leading-none"
@click="handleDeleteComment(item)"
>
删除
</button>
</div>
<!-- 列表项点赞 -->
......@@ -234,6 +252,7 @@ import {
addComment,
addOrCancelCommentLike,
getCommentDetail,
deleteComment,
} from '@/api'
import type { CommentItemDto } from '@/api'
import { BooleanFlag } from '@/constants'
......@@ -243,6 +262,7 @@ import CommentBox from '../CommentBox/index.vue'
import dayjs from 'dayjs'
import { push } from 'notivue'
import { IS_REAL_KEY_COMMENT } from '@/constants/symbolKey'
import { useMessageBox } from '@/hooks'
const { articleId, pid } = defineProps<{
articleId: number
......@@ -259,6 +279,7 @@ provide(IS_REAL_KEY_COMMENT, BooleanFlag.YES)
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const currentUserAvatar = computed(() => userInfo.value.hiddenAvatar)
const { confirm } = useMessageBox()
// State
const visible = ref(false)
......@@ -278,6 +299,8 @@ const commentStr = ref('')
const imgUrl = ref('')
const loadingBtn = ref(false)
const isDisabled = computed(() => !commentStr.value.trim() || loadingBtn.value)
const isSelfComment = (item: CommentItemDto) =>
String(item.userId || '') === String(userInfo.value.userId || '')
// --- Actions ---
const { list, total, search, searchParams, goToPage, changePageSize, refresh, loading } =
......@@ -408,6 +431,23 @@ const handleLike = async (item: CommentItemDto) => {
}
}
const handleDeleteComment = async (item: CommentItemDto, isParent = false) => {
await confirm({
title: '提示',
message: '确定删除该评论吗?',
type: 'danger',
})
await deleteComment(item.id)
push.success('删除成功')
if (isParent) {
visible.value = false
emit('refresh')
return
}
await refresh()
emit('refresh')
}
const closeDialog = () => {
visible.value = false
}
......
......@@ -300,10 +300,17 @@
置顶回答
</span>
<span
class="inline-flex items-center rounded-full border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-11px leading-none text-gray-500"
class="inline-flex items-center rounded-full border border-gray-200 bg-gray-50 px-1.5 py-0.5 text-xs leading-none text-gray-500"
>
{{ answer.floorNumber || '顶' }}楼
</span>
<button
v-if="isSelfAnswer(answer)"
class="cursor-pointer text-red-500 text-xs leading-none"
@click="handleDeleteAnswer(answer)"
>
删除
</button>
</div>
</div>
</div>
......@@ -437,6 +444,7 @@ import {
addOrCanceArticlelCollect,
addOrCancelCommentLike,
topOrCancelTopComment,
deleteComment,
} from '@/api'
import type { ArticleItemDto, CommentItemDto } from '@/api'
import { usePageSearch } from '@/hooks'
......@@ -448,6 +456,7 @@ import dayjs from 'dayjs'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
import { useNavigation, useScrollTop } from '@/hooks'
import { useMessageBox } from '@/hooks'
import { parseEmoji } from '@/utils/emoji'
import { ArticleTypeEnum, BooleanFlag } from '@/constants'
import { push } from 'notivue'
......@@ -456,6 +465,7 @@ import { CommentSortTypeEnum } from '@/constants'
const userStore = useUserStore()
const { userInfo } = storeToRefs(userStore)
const { jumpToUserHomePage } = useNavigation()
const { confirm } = useMessageBox()
const route = useRoute()
const router = useRouter()
......@@ -471,6 +481,8 @@ const sendMessageDialogRef = useTemplateRef<InstanceType<typeof SendMessageDialo
// 回滚到子评论框
const { handleBackTop: handleBackTopChildren } = useScrollTop(answerRefList)
const loading = computed(() => !questionDetail.value.title)
const isSelfAnswer = (answer: CommentItemDto) =>
String(answer.userId || '') === String(userInfo.value.userId || '')
const isAuthor = computed(() => {
return questionDetail.value.createUserId === userInfo.value.userId
......@@ -543,6 +555,17 @@ const handleLikeAnswer = async (answer: CommentItemDto) => {
push.success(`${answer.hasPraise ? '点赞该回答' : '取消点赞该回答'}`)
}
const handleDeleteAnswer = async (answer: CommentItemDto) => {
await confirm({
title: '提示',
message: '确定删除该评论吗?',
type: 'danger',
})
await deleteComment(answer.id)
push.success('删除成功')
await refresh()
}
const topCommentPendingId = ref<number | null>(null)
const highlightCommentId = ref<number | null>(null)
const handleTopAnswer = async (answer: CommentItemDto) => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment