|
<template> |
|
<div id="app"> |
|
|
|
<Login v-if="!authStore.isLoggedIn" /> |
|
|
|
|
|
<FullscreenSpin v-else-if="!dataLoaded" tip="数据加载中,请稍等..." loading :mask="false" /> |
|
|
|
|
|
<template v-else> |
|
<Screen v-if="screening" /> |
|
<Editor v-else-if="_isPC" /> |
|
<Mobile v-else /> |
|
</template> |
|
</div> |
|
</template> |
|
|
|
<script lang="ts" setup> |
|
import { onMounted, ref } from 'vue' |
|
import { storeToRefs } from 'pinia' |
|
import { useScreenStore, useMainStore, useSnapshotStore, useSlidesStore, useAuthStore } from '@/store' |
|
import { LOCALSTORAGE_KEY_DISCARDED_DB } from '@/configs/storage' |
|
import { deleteDiscardedDB } from '@/utils/database' |
|
import { isPC } from '@/utils/common' |
|
import api from '@/services' |
|
import dataSyncService from '@/services/dataSyncService' |
|
|
|
import Editor from './views/Editor/index.vue' |
|
import Screen from './views/Screen/index.vue' |
|
import Mobile from './views/Mobile/index.vue' |
|
import Login from './views/Login.vue' |
|
import FullscreenSpin from '@/components/FullscreenSpin.vue' |
|
|
|
const _isPC = isPC() |
|
const dataLoaded = ref(false) |
|
|
|
const mainStore = useMainStore() |
|
const slidesStore = useSlidesStore() |
|
const snapshotStore = useSnapshotStore() |
|
const authStore = useAuthStore() |
|
const { databaseId } = storeToRefs(mainStore) |
|
const { screening } = storeToRefs(useScreenStore()) |
|
|
|
if (import.meta.env.MODE !== 'development') { |
|
window.onbeforeunload = () => false |
|
} |
|
|
|
|
|
const initializeApp = async () => { |
|
try { |
|
// 初始化 DataSyncService(在 Pinia 可用后) |
|
await dataSyncService.initialize() |
|
|
|
// 如果用户已登录,加载用户的PPT数据 |
|
if (authStore.isLoggedIn) { |
|
const pptList = await api.getPPTList() |
|
|
|
// 如果用户有PPT,加载第一个PPT;否则创建默认PPT |
|
if (pptList.length > 0) { |
|
const firstPPT = await api.getPPT(pptList[0].name) |
|
slidesStore.setSlides(firstPPT.slides) |
|
slidesStore.setTitle(firstPPT.title) |
|
if (firstPPT.theme) { |
|
slidesStore.setTheme(firstPPT.theme) |
|
} |
|
|
|
dataSyncService.setCurrentPPTId(pptList[0].name) |
|
} |
|
else { |
|
// 创建默认演示文稿 |
|
const defaultPPT = await api.createPPT('我的第一个演示文稿') |
|
slidesStore.setSlides(defaultPPT.ppt.slides) |
|
slidesStore.setTitle(defaultPPT.ppt.title) |
|
slidesStore.setTheme(defaultPPT.ppt.theme) |
|
dataSyncService.setCurrentPPTId(defaultPPT.pptId) |
|
} |
|
} |
|
else { |
|
// 未登录状态,加载默认示例数据 |
|
const slides = await api.getFileData('slides') |
|
slidesStore.setSlides(slides) |
|
} |
|
|
|
await deleteDiscardedDB() |
|
snapshotStore.initSnapshotDatabase() |
|
dataLoaded.value = true |
|
} |
|
catch (error) { |
|
// 如果是认证错误,清除登录状态 |
|
if (error === 'Authentication failed') { |
|
authStore.logout() |
|
} |
|
else { |
|
// 其他错误,加载默认数据 |
|
try { |
|
const slides = await api.getFileData('slides') |
|
slidesStore.setSlides(slides) |
|
dataLoaded.value = true |
|
} |
|
catch (fallbackError) { |
|
// 创建一个空的默认幻灯片 |
|
slidesStore.setSlides([{ |
|
id: 'default-slide', |
|
elements: [], |
|
background: { type: 'solid', color: '#ffffff' } |
|
}]) |
|
dataLoaded.value = true |
|
} |
|
} |
|
} |
|
} |
|
|
|
onMounted(async () => { |
|
// 初始化认证状态 |
|
await authStore.initAuth() |
|
|
|
// 初始化应用数据 |
|
await initializeApp() |
|
}) |
|
|
|
|
|
window.addEventListener('unload', () => { |
|
const discardedDB = localStorage.getItem(LOCALSTORAGE_KEY_DISCARDED_DB) |
|
const discardedDBList: string[] = discardedDB ? JSON.parse(discardedDB) : [] |
|
|
|
discardedDBList.push(databaseId.value) |
|
|
|
const newDiscardedDB = JSON.stringify(discardedDBList) |
|
localStorage.setItem(LOCALSTORAGE_KEY_DISCARDED_DB, newDiscardedDB) |
|
}) |
|
</script> |
|
|
|
<style lang="scss"> |
|
#app { |
|
height: 100%; |
|
} |
|
</style> |