151 lines
4.0 KiB
Vue
151 lines
4.0 KiB
Vue
<script lang="ts" setup>
|
||
import type { CommentApi } from '#/api/license/comment';
|
||
|
||
import { computed, ref } from 'vue';
|
||
|
||
import { useUserStore } from '@vben/stores';
|
||
|
||
import { message } from 'ant-design-vue';
|
||
import dayjs from 'dayjs';
|
||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||
|
||
import { deleteComment } from '#/api/license/comment';
|
||
import { $t } from '#/locales';
|
||
|
||
import CreateComment from './create-comment.vue';
|
||
|
||
const props = withDefaults(
|
||
defineProps<{
|
||
comments?: CommentApi.Comment[];
|
||
data?: CommentApi.Comment;
|
||
projectId?: number;
|
||
}>(),
|
||
{
|
||
data: () => ({
|
||
id: 0,
|
||
author: '',
|
||
avatar: '',
|
||
updateTime: dayjs(),
|
||
depth: 1,
|
||
content: '',
|
||
children: [],
|
||
}),
|
||
projectId: 0,
|
||
comments: () => [],
|
||
},
|
||
);
|
||
const emit = defineEmits(['getCommentByProjectId']);
|
||
|
||
const userStore = useUserStore();
|
||
|
||
const isShowReply = ref<boolean>();
|
||
const parentId = ref<number>();
|
||
const reply = (id: number) => {
|
||
isShowReply.value = !isShowReply.value;
|
||
parentId.value = id;
|
||
};
|
||
|
||
const showReply = (flag: boolean) => {
|
||
isShowReply.value = flag;
|
||
};
|
||
|
||
const onDelete = async (id: number) => {
|
||
try {
|
||
await deleteComment(id);
|
||
|
||
message.success($t('ui.actionMessage.operationSuccess'));
|
||
} finally {
|
||
emit('getCommentByProjectId', props.projectId);
|
||
}
|
||
};
|
||
|
||
dayjs.extend(relativeTime);
|
||
|
||
const formatContent = computed(() => {
|
||
let dataContent = props.data.content || '';
|
||
if ((props.data?.depth ?? 0) > 2 && dataContent) {
|
||
const position = dataContent.indexOf('>') + 1;
|
||
const originalString = dataContent;
|
||
const stringToInsert = `<span style="font-size: 12px; color: #32363973">回复 ${props.data?.replyUser}:</span>`;
|
||
dataContent =
|
||
originalString.slice(0, position) +
|
||
stringToInsert +
|
||
originalString.slice(position);
|
||
}
|
||
return dataContent;
|
||
});
|
||
</script>
|
||
<template>
|
||
<a-comment :author="data.author">
|
||
<template #avatar>
|
||
<a-avatar :src="data.avatar" :alt="data.author">
|
||
{{ data.author?.substring(0, 2) }}
|
||
</a-avatar>
|
||
</template>
|
||
<template #datetime>
|
||
<a-tooltip :title="dayjs(data.updateTime)">
|
||
<span>{{ dayjs(data.updateTime).format('YYYY-MM-DD HH:mm:ss') }}</span>
|
||
</a-tooltip>
|
||
</template>
|
||
<template #content>
|
||
<div>
|
||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||
<span v-html="formatContent"></span>
|
||
</div>
|
||
</template>
|
||
<template #actions>
|
||
<span key="comment-basic-reply-to">
|
||
<template v-if="!isShowReply">
|
||
<a-tooltip :title="$t('comment.reply')">
|
||
<span
|
||
class="icon-[mdi--comment-processing-outline] size-3.5"
|
||
@click="reply(data.id)"
|
||
></span>
|
||
</a-tooltip>
|
||
</template>
|
||
<template v-else>
|
||
<a-tooltip :title="$t('comment.cancelReply')">
|
||
<span
|
||
class="icon-[mdi--comment-processing] size-3.5"
|
||
@click="reply(data.id)"
|
||
></span>
|
||
</a-tooltip>
|
||
</template>
|
||
</span>
|
||
<span
|
||
v-if="userStore.userInfo?.id === data.userId"
|
||
key="comment-basic-delete"
|
||
>
|
||
<a-popconfirm
|
||
:title="$t('comment.deleteCommentTitle')"
|
||
@confirm="onDelete(data.id)"
|
||
>
|
||
<a-tooltip :title="$t('ui.actionTitle.delete')">
|
||
<span class="icon-[ri--delete-bin-line] size-3.5"></span>
|
||
</a-tooltip>
|
||
</a-popconfirm>
|
||
</span>
|
||
</template>
|
||
<div v-show="isShowReply">
|
||
<CreateComment
|
||
:project-id="projectId"
|
||
:comments="comments"
|
||
:parent-id="parentId"
|
||
@show-reply="showReply"
|
||
@get-comment-by-project-id="emit('getCommentByProjectId', projectId)"
|
||
/>
|
||
</div>
|
||
<template v-if="(data?.depth ?? 0) < 2">
|
||
<child-comment
|
||
v-for="(item, index) of data.children"
|
||
:data="item"
|
||
:key="index"
|
||
:project-id="projectId"
|
||
:comments="comments"
|
||
:parent-id="parentId"
|
||
@get-comment-by-project-id="emit('getCommentByProjectId', projectId)"
|
||
/>
|
||
</template>
|
||
</a-comment>
|
||
</template>
|