|
import api from '@/services'
|
|
import { debounce } from 'lodash'
|
|
|
|
class DataSyncService {
|
|
private currentPPTId: string | null = null
|
|
private saveTimeout: number | null = null
|
|
private isOnline = true
|
|
private autoSaveDelay = 300000
|
|
private isInitialized = false
|
|
private debouncedSave: any = null
|
|
|
|
constructor() {
|
|
this.setupNetworkMonitoring()
|
|
}
|
|
|
|
|
|
async initialize() {
|
|
if (this.isInitialized) return
|
|
await this.setupAutoSave()
|
|
this.isInitialized = true
|
|
}
|
|
|
|
|
|
setAutoSaveDelay(delay: number) {
|
|
this.autoSaveDelay = Math.max(500, delay)
|
|
if (this.isInitialized) {
|
|
this.setupAutoSave()
|
|
}
|
|
}
|
|
|
|
|
|
getAutoSaveDelay(): number {
|
|
return this.autoSaveDelay
|
|
}
|
|
|
|
|
|
setCurrentPPTId(pptId: string) {
|
|
this.currentPPTId = pptId
|
|
}
|
|
|
|
|
|
private async setupAutoSave() {
|
|
if (this.debouncedSave) {
|
|
this.debouncedSave.cancel()
|
|
}
|
|
|
|
this.debouncedSave = debounce(async () => {
|
|
await this.savePPT()
|
|
}, this.autoSaveDelay)
|
|
|
|
|
|
try {
|
|
const { useSlidesStore } = await import('@/store')
|
|
const slidesStore = useSlidesStore()
|
|
slidesStore.$subscribe(() => {
|
|
if (this.isOnline && this.currentPPTId) {
|
|
this.debouncedSave()
|
|
}
|
|
})
|
|
}
|
|
catch (error) {
|
|
|
|
}
|
|
}
|
|
|
|
|
|
private setupNetworkMonitoring() {
|
|
window.addEventListener('online', () => {
|
|
this.isOnline = true
|
|
|
|
})
|
|
|
|
window.addEventListener('offline', () => {
|
|
this.isOnline = false
|
|
|
|
})
|
|
}
|
|
|
|
|
|
async savePPT(force = false): Promise<boolean> {
|
|
|
|
const { useAuthStore, useSlidesStore } = await import('@/store')
|
|
|
|
try {
|
|
const authStore = useAuthStore()
|
|
const slidesStore = useSlidesStore()
|
|
|
|
if (!authStore.isLoggedIn) {
|
|
|
|
return false
|
|
}
|
|
|
|
|
|
if (!this.currentPPTId && force) {
|
|
try {
|
|
const response = await api.createPPT(slidesStore.title || '未命名演示文稿')
|
|
this.currentPPTId = response.pptId
|
|
|
|
|
|
if (response.ppt) {
|
|
slidesStore.setSlides(response.ppt.slides)
|
|
slidesStore.setTitle(response.ppt.title)
|
|
slidesStore.setTheme(response.ppt.theme)
|
|
}
|
|
|
|
|
|
return true
|
|
}
|
|
catch (createError) {
|
|
|
|
return false
|
|
}
|
|
}
|
|
|
|
if (!this.currentPPTId && !force) {
|
|
|
|
return false
|
|
}
|
|
|
|
const pptData = {
|
|
pptId: this.currentPPTId,
|
|
title: slidesStore.title,
|
|
slides: slidesStore.slides,
|
|
theme: slidesStore.theme
|
|
}
|
|
|
|
await api.savePPT(pptData)
|
|
|
|
return true
|
|
}
|
|
catch (error) {
|
|
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
async createNewPPT(title: string): Promise<string | null> {
|
|
const { useAuthStore } = await import('@/store')
|
|
const authStore = useAuthStore()
|
|
|
|
if (!authStore.isLoggedIn) {
|
|
throw new Error('用户未登录')
|
|
}
|
|
|
|
try {
|
|
const response = await api.createPPT(title)
|
|
this.setCurrentPPTId(response.pptId)
|
|
return response.pptId
|
|
}
|
|
catch (error) {
|
|
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
async loadPPT(pptId: string): Promise<boolean> {
|
|
const { useAuthStore, useSlidesStore } = await import('@/store')
|
|
const authStore = useAuthStore()
|
|
const slidesStore = useSlidesStore()
|
|
|
|
if (!authStore.isLoggedIn) {
|
|
throw new Error('用户未登录')
|
|
}
|
|
|
|
try {
|
|
const pptData = await api.getPPT(pptId)
|
|
|
|
slidesStore.setSlides(pptData.slides)
|
|
slidesStore.setTitle(pptData.title)
|
|
if (pptData.theme) {
|
|
slidesStore.setTheme(pptData.theme)
|
|
}
|
|
|
|
this.setCurrentPPTId(pptId)
|
|
|
|
return true
|
|
}
|
|
catch (error) {
|
|
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
async getPPTList() {
|
|
const { useAuthStore } = await import('@/store')
|
|
const authStore = useAuthStore()
|
|
|
|
if (!authStore.isLoggedIn) {
|
|
throw new Error('用户未登录')
|
|
}
|
|
|
|
return await api.getPPTList()
|
|
}
|
|
|
|
|
|
async deletePPT(pptId: string): Promise<boolean> {
|
|
const { useAuthStore } = await import('@/store')
|
|
const authStore = useAuthStore()
|
|
|
|
if (!authStore.isLoggedIn) {
|
|
throw new Error('用户未登录')
|
|
}
|
|
|
|
try {
|
|
await api.deletePPT(pptId)
|
|
|
|
|
|
if (this.currentPPTId === pptId) {
|
|
this.currentPPTId = null
|
|
}
|
|
|
|
|
|
return true
|
|
}
|
|
catch (error) {
|
|
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
async generateShareLink(slideIndex = 0) {
|
|
const { useAuthStore } = await import('@/store')
|
|
const authStore = useAuthStore()
|
|
|
|
if (!authStore.isLoggedIn || !this.currentPPTId) {
|
|
throw new Error('用户未登录或没有当前PPT')
|
|
}
|
|
|
|
try {
|
|
const response = await api.generateShareLink(
|
|
authStore.currentUser!.id,
|
|
this.currentPPTId,
|
|
slideIndex
|
|
)
|
|
return response
|
|
}
|
|
catch (error) {
|
|
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
async manualSave(): Promise<boolean> {
|
|
return await this.savePPT(true)
|
|
}
|
|
}
|
|
|
|
|
|
export const dataSyncService = new DataSyncService()
|
|
export default dataSyncService |