|
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, |
|
|
|
viewportSize: slidesStore.viewportSize, |
|
viewportRatio: slidesStore.viewportRatio |
|
} |
|
|
|
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 |