|
|
@ -1,6 +1,11 @@ |
|
|
<script setup lang="ts"> |
|
|
<script setup lang="ts"> |
|
|
import { unwrapApiBody, type ApiResponse } from '../../../utils/http/factory' |
|
|
import { unwrapApiBody, type ApiResponse } from '../../../utils/http/factory' |
|
|
import { extractFrontMatterDesc } from '../../../utils/markdown-front-matter' |
|
|
import { extractFrontMatterDesc } from '../../../utils/markdown-front-matter' |
|
|
|
|
|
import { |
|
|
|
|
|
buildMarkdownExportFileName, |
|
|
|
|
|
downloadMarkdownFile, |
|
|
|
|
|
normalizeMarkdownImageUrls, |
|
|
|
|
|
} from '../../../utils/markdown-export' |
|
|
import { renderSafeMarkdown } from '../../../utils/render-markdown' |
|
|
import { renderSafeMarkdown } from '../../../utils/render-markdown' |
|
|
import { formatOccurredOnDisplay, occurredOnToIsoAttr } from '../../../utils/timeline-datetime' |
|
|
import { formatOccurredOnDisplay, occurredOnToIsoAttr } from '../../../utils/timeline-datetime' |
|
|
import { useAuthSession } from '../../../composables/useAuthSession' |
|
|
import { useAuthSession } from '../../../composables/useAuthSession' |
|
|
@ -13,6 +18,7 @@ const route = useRoute() |
|
|
const publicSlug = computed(() => route.params.publicSlug as string) |
|
|
const publicSlug = computed(() => route.params.publicSlug as string) |
|
|
const postSlug = computed(() => route.params.postSlug as string) |
|
|
const postSlug = computed(() => route.params.postSlug as string) |
|
|
const { user, loggedIn } = useAuthSession() |
|
|
const { user, loggedIn } = useAuthSession() |
|
|
|
|
|
const toast = useToast() |
|
|
|
|
|
|
|
|
type Post = { |
|
|
type Post = { |
|
|
id: number |
|
|
id: number |
|
|
@ -75,6 +81,26 @@ const canEditPost = computed(() => { |
|
|
const editPostHref = computed(() => |
|
|
const editPostHref = computed(() => |
|
|
data.value && canEditPost.value ? `/me/posts/${data.value.id}` : '', |
|
|
data.value && canEditPost.value ? `/me/posts/${data.value.id}` : '', |
|
|
) |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
function exportMarkdown(): void { |
|
|
|
|
|
if (!data.value) { |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
const origin = window.location.origin |
|
|
|
|
|
const bodyMarkdown = data.value.bodyMarkdown || '' |
|
|
|
|
|
const normalizedMarkdown = normalizeMarkdownImageUrls(bodyMarkdown, origin) |
|
|
|
|
|
const filename = buildMarkdownExportFileName({ |
|
|
|
|
|
slug: data.value.slug, |
|
|
|
|
|
id: data.value.id, |
|
|
|
|
|
}) |
|
|
|
|
|
downloadMarkdownFile(filename, normalizedMarkdown) |
|
|
|
|
|
toast.add({ title: '已导出 Markdown', color: 'success' }) |
|
|
|
|
|
} catch { |
|
|
|
|
|
toast.add({ title: '导出失败,请稍后重试', color: 'error' }) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<template> |
|
|
<template> |
|
|
@ -97,6 +123,16 @@ const editPostHref = computed(() => |
|
|
> |
|
|
> |
|
|
编辑 |
|
|
编辑 |
|
|
</UButton> |
|
|
</UButton> |
|
|
|
|
|
<UButton |
|
|
|
|
|
v-if="data" |
|
|
|
|
|
color="neutral" |
|
|
|
|
|
variant="soft" |
|
|
|
|
|
size="sm" |
|
|
|
|
|
:disabled="pending" |
|
|
|
|
|
@click="exportMarkdown" |
|
|
|
|
|
> |
|
|
|
|
|
导出 .md |
|
|
|
|
|
</UButton> |
|
|
</div> |
|
|
</div> |
|
|
<div v-if="data.coverUrl" class="flex justify-center"> |
|
|
<div v-if="data.coverUrl" class="flex justify-center"> |
|
|
<img |
|
|
<img |
|
|
|