128 lines
3.4 KiB
Vue
128 lines
3.4 KiB
Vue
<template>
|
|
<div class="blog-comment-card">
|
|
<el-avatar :src="`https://api.dicebear.com/6.x/adventurer/svg?seed=${props.comment.name}`"
|
|
:size="50" alt="未加载"/>
|
|
|
|
<div class="blog-comment-content">
|
|
<div class="basic-info">
|
|
<span>{{ props.comment.name }}</span>
|
|
<span class="content">{{ getBrowser(props.comment.userAgent) }}</span>
|
|
<span class="content">{{ getOsInfo(props.comment.userAgent) }}</span>
|
|
</div>
|
|
|
|
<div class="sub-info">
|
|
<span class="content">{{ props.comment.createTime }}</span>
|
|
<el-button v-if="!blogComment.isShowEdit"
|
|
type="primary" text @click="replyClick">回复</el-button>
|
|
<el-button v-else type="primary"
|
|
text @click="cancelClick">取消</el-button>
|
|
</div>
|
|
|
|
<p>{{ props.comment.content }}</p>
|
|
|
|
<blog-comment-edit v-if="blogComment.isShowEdit"
|
|
:parent-id="props.comment.id"/>
|
|
|
|
<div class="reply-list">
|
|
<div class="blog-comment-card" v-for="(item, index) in props.replyList" :key="index">
|
|
<el-avatar :src="`https://api.dicebear.com/6.x/adventurer/svg?seed=${item.name}`"
|
|
:size="50" alt="未加载"/>
|
|
|
|
<div class="blog-comment-content">
|
|
<div class="basic-info">
|
|
<span>{{ item.name }}</span>
|
|
<span class="content">{{ getBrowser(props.comment.userAgent) }}</span>
|
|
<span class="content">{{ getOsInfo(props.comment.userAgent) }}</span>
|
|
</div>
|
|
|
|
<div class="sub-info">
|
|
<span class="content">{{ item.createTime }}</span>
|
|
</div>
|
|
<p>{{ item.content }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import BlogCommentEdit from '@/components/Comment/BlogCommentEdit.vue'
|
|
import 'vue3-emoji-picker/css'
|
|
import { defineProps, PropType, reactive } from 'vue'
|
|
import { IBlogComment } from '@/types/blog'
|
|
import { useBlogStore } from '@/store/blog.ts'
|
|
import { UAParser } from 'ua-parser-js'
|
|
|
|
const blogStore = useBlogStore()
|
|
|
|
const props = defineProps({
|
|
comment: {
|
|
required: true,
|
|
type: Object as PropType<IBlogComment>
|
|
},
|
|
replyList: {
|
|
required: true,
|
|
type: Object as PropType<IBlogComment[]>
|
|
}
|
|
})
|
|
|
|
const blogComment = reactive({
|
|
isShowEdit: false
|
|
})
|
|
|
|
const replyClick = () => {
|
|
blogStore.currentBlogComment = blogStore.getEmptyBlogComment()
|
|
blogComment.isShowEdit = true
|
|
}
|
|
|
|
const cancelClick = () => {
|
|
blogComment.isShowEdit = false
|
|
}
|
|
|
|
const getOsInfo = (userAgent: string) => {
|
|
const uaParse = new UAParser(userAgent)
|
|
return `${uaParse.getOS().name} ${uaParse.getOS().version}`
|
|
}
|
|
|
|
const getBrowser = (userAgent: string) => {
|
|
const uaParse = new UAParser(userAgent)
|
|
return `${uaParse.getBrowser().name} ${uaParse.getBrowser().version}`
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.blog-comment-card {
|
|
width: 100%;
|
|
padding: 10px;
|
|
|
|
display: grid;
|
|
grid-template-columns: 60px 1fr;
|
|
gap: 5px;
|
|
|
|
.blog-comment-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
|
|
.basic-info {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
font-size: small;
|
|
}
|
|
|
|
.sub-info {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.content {
|
|
font-size: small;
|
|
color: #666666;
|
|
}
|
|
}
|
|
}
|
|
</style>
|