Files
tonePage/tonecn/src/views/BlogContent.vue

183 lines
5.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang='ts'>
import { request, type BaseResponseData } from '@/lib/request';
import { onMounted, onUnmounted, ref, type Ref } from 'vue';
import { timestampToString } from '../lib/timestampToString'
import { useRoute } from 'vue-router'
import { Marked } from 'marked';
import { markedHighlight } from "marked-highlight";
import hljs from 'highlight.js';
import "highlight.js/styles/xcode.css";
import BlogContentToolBar from '@/components/Blog/BlogContentToolBar.vue';
import BlogComment from '@/components/Blog/BlogComment.vue';
type BlogInfo = {
visit_count: number,
title: string,
publish_time: string,
like_count: number,
description: string
}
const loadStatus = ref(0);// 0加载中 -1加载失败 1加载成功
const loadStatusDescription = ref('出错啦,返回到上一个界面重试吧');
const route = useRoute();
const blogContent = ref('');
const blogInfo: Ref<BlogInfo> = ref({
visit_count: 0,
title: '',
publish_time: '',
like_count: 0,
description: ''
});
const blogCommentReload = ref(false);
const marked = new Marked(
markedHighlight({
langPrefix: 'hljs language-',
highlight(code, lang, info) {
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
return hljs.highlight(code, { language }).value;
}
})
);
onMounted(async () => {
const bloguuid = route.params.uuid;
if (bloguuid.length != 32) {
return loadStatus.value = -1;
}
try {
let blogContentRes: BaseResponseData = await request.get(`/blogContent?bloguuid=${bloguuid}` + (window.location.href.indexOf('?') != -1 ? "&" + window.location.href.split('?')[1] : ""));
console.log(blogContent.value)
if (blogContentRes.code == 0) {
try {
blogContent.value = await marked.parse(decodeURIComponent(escape(atob(blogContentRes.data.data))))
blogInfo.value = blogContentRes.data.info;
loadStatus.value = 1;
// 标题
document.title = blogContentRes.data.info.title + ' —— 特恩(TONE)';
} catch (error) {
throw error
}
} else if (blogContentRes.code == -4001) {
// 不可见或不存在
loadStatus.value = -1;
loadStatusDescription.value = '文章不可见或不存在'
} else if (blogContentRes.code == -4002) {
// 文章加密
loadStatus.value = -1;
loadStatusDescription.value = '文章被加密啦,请联系发布者'
} else if (blogContentRes.code == -4003) {
loadStatus.value = -2;
loadStatusDescription.value = '密钥好像有点问题,请联系发布者'
} else {
throw new Error(blogContentRes.message);
}
} catch (error) {
console.error('请求博客内容发生错误 ', error);
loadStatusDescription.value = '加载失败,刷新后重试';
loadStatus.value = -1;
}
})
onUnmounted(() => {
document.title = '特恩(TONE)';
})
</script>
<template>
<div class="bg-default-bg dark:bg-[#222] fixed inset-0 w-full h-full -z-10"></div>
<div class="flex flex-col max-w-[600px] my-[50px] mx-auto px-[20px]">
<div class="mx-auto dark:text-white" v-if="loadStatus == 0">加载中请稍后...</div>
<el-empty v-if="loadStatus < 0" :description="loadStatusDescription" />
<div v-if="loadStatus == 1">
<div>
<h1 class="text-center text-[28px] font-semibold dark:text-white text-[#222]">{{ blogInfo.title }}</h1>
<p class="my-[15px] mx-auto text-[14px] text-[#888] dark:text-[#ccc] text-center">发布于 {{
timestampToString(blogInfo.publish_time) }} {{ blogInfo.like_count }} 点赞</p>
<!-- TODO <p class="mt-[-10px] mx-auto text-[14px] text-[#888] dark:text-[#ccc] text-center whitespace-pre">
{{ blogInfo.visit_count }} 访问
{{ blogInfo.like_count }} 点赞
</p> -->
</div>
<div v-html="blogContent" id="blogContentContainer"></div>
</div>
<BlogComment v-if="loadStatus == 1" v-model="blogCommentReload" />
</div>
<BlogContentToolBar v-if="loadStatus == 1" @comment-success="blogCommentReload = true;" />
</template>
<style>
/* markdown CSS */
#blogContentContainer img {
@apply w-full my-[5px];
}
#blogContentContainer p {
@apply text-[#555] dark:text-[#ddd] my-[10px];
}
#blogContentContainer p code {
@apply bg-[#dedede] dark:bg-[#ffffff44] py-[1px] px-[3px] rounded-[3px];
}
#blogContentContainer blockquote {
@apply my-[16px] pl-[25px] border-[4px_solid_#ddd];
}
#blogContentContainer blockquote p {
@apply text-[#888];
}
#blogContentContainer pre {
@apply rounded-[5px] overflow-hidden;
}
#blogContentContainer pre code {
@apply overflow-x-scroll;
}
#blogContentContainer h1,
#blogContentContainer h2,
#blogContentContainer h3,
#blogContentContainer h4,
#blogContentContainer h5,
#blogContentContainer h6 {
@apply font-[800] text-[#333] dark:text-[#fff] mt-[20px];
}
#blogContentContainer h1 {
@apply text-[28px] border-b-[#ddd] dark:border-b-[#999] border-b;
}
#blogContentContainer h2 {
@apply text-[24px] border-b-[#ddd] dark:border-b-[#999] border-b;
}
#blogContentContainer h3 {
@apply text-[22px];
}
#blogContentContainer h4 {
@apply text-[20px];
}
#blogContentContainer h5 {
@apply text-[18px];
}
#blogContentContainer h6 {
@apply text-[16px];
}
#blogContentContainer pre {
@apply text-[12px] rounded-[8px] shadow;
}
#blogContentContainer table thead th {
@apply border-[2px] ;
}
#blogContentContainer table td {
@apply border-[1px] p-[5px];
}
</style>