File size: 4,230 Bytes
89ce340 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
<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)
}
// 设置当前PPT ID以便自动保存
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()
})
// 应用注销时向 localStorage 中记录下本次 indexedDB 的数据库ID,用于之后清除数据库
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> |