Skip to content

Commit 6d24402

Browse files
committed
fix: support flat comments in admin
1 parent 5de47bd commit 6d24402

4 files changed

Lines changed: 114 additions & 57 deletions

File tree

src/models/comment.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,44 @@
11
import type { Pager } from './base'
22

3+
export interface CommentParentPreview {
4+
id: string
5+
author: string
6+
text: string
7+
isDeleted?: boolean
8+
}
9+
10+
export interface CommentReplyWindow {
11+
total: number
12+
returned: number
13+
threshold: number
14+
hasHidden: boolean
15+
hiddenCount: number
16+
nextCursor?: string
17+
}
18+
319
export interface CommentModel {
420
refType: string
521
state: number
6-
children: CommentModel[]
7-
commentsIndex: number
822
id: string
923
author: string
1024
text: string
11-
mail: string
12-
url: string
13-
ip: string
14-
agent: string
15-
key: string
16-
pid: string
25+
mail?: string
26+
url?: string
27+
ip?: string
28+
agent?: string
1729
created: string
1830
modified: string
19-
avatar: string
31+
avatar?: string
2032
isWhispers?: boolean
33+
parentCommentId?: string | CommentParentPreview | null
34+
rootCommentId?: string | null
35+
replyCount?: number
36+
latestReplyAt?: string | null
37+
isDeleted?: boolean
38+
deletedAt?: string | null
39+
replies?: CommentModel[]
40+
replyWindow?: CommentReplyWindow
41+
ref?: Record<string, any>
2142
}
2243

2344
export interface CommentsResponse {

src/views/comments/components/comment-detail.tsx

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ import { useUserStore } from '~/stores/user'
3434

3535
import { CommentMarkdownRender } from '../markdown-render'
3636

37+
const getParentCommentPreview = (parent: CommentModel['parentCommentId']) => {
38+
if (!parent || typeof parent === 'string') {
39+
return null
40+
}
41+
return parent
42+
}
43+
3744
const getReferenceLink = (row: CommentModel) => {
3845
const ref = (row as any).ref
3946
switch (row.refType) {
@@ -102,8 +109,22 @@ export const CommentDetail = defineComponent({
102109
const user = computed(() => userStore.user)
103110

104111
const link = computed(() => getReferenceLink(props.comment))
105-
const isReply = computed(() => !!(props.comment as any).parent)
112+
const isReply = computed(() => !!props.comment.parentCommentId)
106113
const isTrash = computed(() => props.currentTab === 2)
114+
const commentBody = computed(() =>
115+
props.comment.isDeleted ? '该评论已删除' : props.comment.text,
116+
)
117+
const parentComment = computed(() =>
118+
getParentCommentPreview(props.comment.parentCommentId),
119+
)
120+
const parentCommentBody = computed(() => {
121+
if (!parentComment.value) {
122+
return ''
123+
}
124+
return parentComment.value.isDeleted
125+
? '该评论已删除'
126+
: parentComment.value.text
127+
})
107128

108129
const deviceInfo = computed(() => {
109130
const ua = props.comment.agent?.toLowerCase() || ''
@@ -181,6 +202,8 @@ export const CommentDetail = defineComponent({
181202
}
182203
}
183204

205+
const noop = () => void 0
206+
184207
const ActionButton = (p: {
185208
icon: any
186209
onClick: () => void
@@ -249,7 +272,7 @@ export const CommentDetail = defineComponent({
249272
<ActionButton
250273
icon={TrashIcon}
251274
label="删除"
252-
onClick={() => {}}
275+
onClick={noop}
253276
class="hover:bg-red-50 hover:text-red-600 dark:hover:bg-red-900/20 dark:hover:text-red-500"
254277
/>
255278
</div>
@@ -268,17 +291,27 @@ export const CommentDetail = defineComponent({
268291
<div class="mb-2 flex items-center gap-2 text-xs text-neutral-500">
269292
<TurnRightIcon class="h-3 w-3" />
270293
<span>
271-
回复{' '}
272-
<strong class="font-medium text-neutral-900 dark:text-neutral-100">
273-
@{(props.comment as any).parent.author}
274-
</strong>
294+
回复
295+
{parentComment.value ? (
296+
<strong class="ml-1 font-medium text-neutral-900 dark:text-neutral-100">
297+
@{parentComment.value.author}
298+
</strong>
299+
) : (
300+
<strong class="ml-1 font-medium text-neutral-900 dark:text-neutral-100">
301+
上级评论
302+
</strong>
303+
)}
275304
</span>
276305
</div>
277-
<div class="line-clamp-2 text-sm text-neutral-600 dark:text-neutral-400">
278-
<CommentMarkdownRender
279-
text={(props.comment as any).parent.text}
280-
/>
281-
</div>
306+
{parentComment.value ? (
307+
<div class="line-clamp-2 text-sm text-neutral-600 dark:text-neutral-400">
308+
<CommentMarkdownRender text={parentCommentBody.value} />
309+
</div>
310+
) : (
311+
<div class="text-sm text-neutral-600 dark:text-neutral-400">
312+
上级评论 ID: {String(props.comment.parentCommentId)}
313+
</div>
314+
)}
282315
</div>
283316
)}
284317

@@ -308,10 +341,9 @@ export const CommentDetail = defineComponent({
308341
</div>
309342

310343
<div class="prose prose-neutral dark:prose-invert max-w-none text-base leading-relaxed text-neutral-900 dark:text-neutral-100">
311-
<CommentMarkdownRender text={props.comment.text} />
344+
<CommentMarkdownRender text={commentBody.value} />
312345
</div>
313346

314-
{/* @ts-expect-error */}
315347
{props.comment.ref?.title && (
316348
<div class="flex items-center gap-2 rounded-md border border-neutral-100 bg-neutral-50 px-3 py-2 text-sm text-neutral-600 transition-colors hover:bg-neutral-100 dark:border-neutral-800 dark:bg-neutral-900 dark:text-neutral-400 dark:hover:bg-neutral-800">
317349
<span class="text-neutral-400">来源:</span>
@@ -321,7 +353,6 @@ export const CommentDetail = defineComponent({
321353
class="truncate font-medium hover:underline"
322354
rel="noreferrer"
323355
>
324-
{/* @ts-expect-error */}
325356
{props.comment.ref.title}
326357
</a>
327358
<ChevronRightIcon class="ml-auto h-4 w-4 text-neutral-400" />
@@ -336,37 +367,45 @@ export const CommentDetail = defineComponent({
336367
<span class="text-xs font-medium text-neutral-500">
337368
IP 地址
338369
</span>
339-
<div class="flex items-center gap-2">
340-
<IpInfoPopover
341-
ip={props.comment.ip}
342-
trigger="click"
343-
triggerEl={
344-
<button class="flex items-center gap-1.5 text-sm text-neutral-900 hover:underline dark:text-neutral-100">
345-
<MapPinIcon class="h-3.5 w-3.5 text-neutral-400" />
346-
<span>{props.comment.ip}</span>
347-
</button>
348-
}
349-
/>
350-
</div>
370+
{props.comment.ip ? (
371+
<div class="flex items-center gap-2">
372+
<IpInfoPopover
373+
ip={props.comment.ip}
374+
trigger="click"
375+
triggerEl={
376+
<button class="flex items-center gap-1.5 text-sm text-neutral-900 hover:underline dark:text-neutral-100">
377+
<MapPinIcon class="h-3.5 w-3.5 text-neutral-400" />
378+
<span>{props.comment.ip}</span>
379+
</button>
380+
}
381+
/>
382+
</div>
383+
) : (
384+
<span class="text-sm text-neutral-400">未知</span>
385+
)}
351386
</div>
352387

353388
<div class="flex flex-col gap-1">
354389
<span class="text-xs font-medium text-neutral-500">
355390
访问设备
356391
</span>
357-
<NTooltip trigger="hover">
358-
{{
359-
trigger: () => (
360-
<div class="flex items-center gap-1.5 text-sm text-neutral-900 dark:text-neutral-100">
361-
<span class="text-neutral-400">
362-
{deviceInfo.value.icon}
363-
</span>
364-
<span class="truncate">{deviceInfo.value.label}</span>
365-
</div>
366-
),
367-
default: () => deviceInfo.value.full,
368-
}}
369-
</NTooltip>
392+
{props.comment.agent ? (
393+
<NTooltip trigger="hover">
394+
{{
395+
trigger: () => (
396+
<div class="flex items-center gap-1.5 text-sm text-neutral-900 dark:text-neutral-100">
397+
<span class="text-neutral-400">
398+
{deviceInfo.value.icon}
399+
</span>
400+
<span class="truncate">{deviceInfo.value.label}</span>
401+
</div>
402+
),
403+
default: () => deviceInfo.value.full,
404+
}}
405+
</NTooltip>
406+
) : (
407+
<span class="text-sm text-neutral-400">未知</span>
408+
)}
370409
</div>
371410

372411
{props.comment.mail && (

src/views/comments/components/comment-list-item.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ export const CommentListItem = defineComponent({
3131
},
3232
setup(props) {
3333
const comment = computed(() => props.data)
34-
const isReply = computed(() => !!(comment.value as any).parent)
34+
const isReply = computed(() => !!comment.value.parentCommentId)
35+
const previewText = computed(() =>
36+
comment.value.isDeleted ? '该评论已删除' : comment.value.text,
37+
)
3538

3639
const handleClick = (e: MouseEvent) => {
3740
const target = e.target as HTMLElement
@@ -85,7 +88,7 @@ export const CommentListItem = defineComponent({
8588
</span>
8689
</div>
8790
<p class="mt-0.5 line-clamp-2 text-sm text-neutral-600 dark:text-neutral-400">
88-
{comment.value.text}
91+
{previewText.value}
8992
</p>
9093
{comment.value.isWhispers && (
9194
<span class="mt-1 inline-flex items-center rounded-full bg-yellow-100 px-1.5 py-0.5 text-xs font-medium text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-500">

src/views/comments/index.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,7 @@ const ManageComment = defineComponent(() => {
6868
size: params.size,
6969
state: params.filters?.state ?? 0,
7070
})
71-
return {
72-
data: response.data.map((data) => {
73-
Reflect.deleteProperty(data, 'children')
74-
return data
75-
}),
76-
pagination: response.pagination,
77-
}
71+
return response
7872
},
7973
pageSize: 20,
8074
filters: () => ({ state: tabValue.value }),

0 commit comments

Comments
 (0)