feat: 初始化慧遇书院官网一期
This commit is contained in:
32
app/composables/useSiteDocument.ts
Normal file
32
app/composables/useSiteDocument.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import type { SiteDocument } from '../../server/utils/site-schema'
|
||||
|
||||
export async function useSiteDocument() {
|
||||
const route = useRoute()
|
||||
const isPreview = computed(() => route.query.preview === 'draft')
|
||||
const endpoint = computed(() => isPreview.value ? '/api/admin/site' : '/api/public/site')
|
||||
const headers = import.meta.server && isPreview.value ? useRequestHeaders(['cookie']) : undefined
|
||||
useHead(() => isPreview.value ? { meta: [{ name: 'robots', content: 'noindex, nofollow' }] } : {})
|
||||
const { data: response, error } = await useFetch<{ data: SiteDocument }>(endpoint, { headers })
|
||||
|
||||
if (error.value) {
|
||||
if (isPreview.value && error.value.statusCode === 401) {
|
||||
throw createError({ statusCode: 401, statusMessage: '预览草稿前请先登录后台' })
|
||||
}
|
||||
throw error.value
|
||||
}
|
||||
|
||||
return {
|
||||
site: computed(() => response.value!.data),
|
||||
isPreview,
|
||||
}
|
||||
}
|
||||
|
||||
export function useAbsoluteUrl() {
|
||||
const config = useRuntimeConfig()
|
||||
const base = String(config.public.siteUrl).replace(/\/$/, '')
|
||||
return (path?: string | null) => {
|
||||
if (!path) return base
|
||||
if (/^https?:\/\//i.test(path)) return path
|
||||
return `${base}${path.startsWith('/') ? path : `/${path}`}`
|
||||
}
|
||||
}
|
||||
35
app/composables/useUnsavedChanges.ts
Normal file
35
app/composables/useUnsavedChanges.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
export function useUnsavedChanges<T>(source: Ref<T | undefined>) {
|
||||
const dirty = ref(false)
|
||||
let baseline = ''
|
||||
|
||||
function snapshot() {
|
||||
baseline = JSON.stringify(source.value ?? null)
|
||||
dirty.value = false
|
||||
}
|
||||
|
||||
watch(source, (value) => {
|
||||
if (!baseline) return
|
||||
dirty.value = JSON.stringify(value ?? null) !== baseline
|
||||
}, { deep: true })
|
||||
|
||||
function beforeUnload(event: BeforeUnloadEvent) {
|
||||
if (!dirty.value) return
|
||||
event.preventDefault()
|
||||
event.returnValue = ''
|
||||
}
|
||||
|
||||
onMounted(() => window.addEventListener('beforeunload', beforeUnload))
|
||||
onBeforeUnmount(() => window.removeEventListener('beforeunload', beforeUnload))
|
||||
onBeforeRouteLeave(() => !dirty.value || window.confirm('当前修改尚未保存,确定离开吗?'))
|
||||
|
||||
return { dirty, markClean: snapshot }
|
||||
}
|
||||
|
||||
export function apiErrorMessage(error: any, fallback: string) {
|
||||
const issue = error?.data?.data?.issues?.[0]
|
||||
if (!issue) return error?.data?.statusMessage || fallback
|
||||
const path = Array.isArray(issue.path) && issue.path.length ? `${issue.path.join('.')}:` : ''
|
||||
return `${path}${issue.message || fallback}`
|
||||
}
|
||||
Reference in New Issue
Block a user