web_ppt / frontend /src /services /dataSyncService.ts
CatPtain's picture
Upload 339 files
89ce340 verified
raw
history blame
6.8 kB
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 // 默认5分钟,可配置
private isInitialized = false
private debouncedSave: any = null
constructor() {
this.setupNetworkMonitoring()
}
// 延迟初始化,在 Pinia 可用后调用
async initialize() {
if (this.isInitialized) return
await this.setupAutoSave()
this.isInitialized = true
}
// 设置自动保存延迟时间(毫秒)
setAutoSaveDelay(delay: number) {
this.autoSaveDelay = Math.max(500, delay) // 最小500ms
if (this.isInitialized) {
this.setupAutoSave() // 重新设置自动保存
}
}
// 获取当前自动保存延迟时间
getAutoSaveDelay(): number {
return this.autoSaveDelay
}
// 设置当前PPT ID
setCurrentPPTId(pptId: string) {
this.currentPPTId = pptId
}
// 自动保存功能
private async setupAutoSave() {
if (this.debouncedSave) {
this.debouncedSave.cancel()
}
this.debouncedSave = debounce(async () => {
await this.savePPT()
}, this.autoSaveDelay) // 使用可配置的延迟时间
// 监听slides变化
try {
const { useSlidesStore } = await import('@/store')
const slidesStore = useSlidesStore()
slidesStore.$subscribe(() => {
if (this.isOnline && this.currentPPTId) {
this.debouncedSave()
}
})
}
catch (error) {
// console.warn('无法设置自动保存,store 未就绪:', error)
}
}
// 网络状态监控
private setupNetworkMonitoring() {
window.addEventListener('online', () => {
this.isOnline = true
// console.log('网络已连接,恢复自动保存')
})
window.addEventListener('offline', () => {
this.isOnline = false
// console.log('网络已断开,暂停自动保存')
})
}
// 保存PPT到后端
async savePPT(force = false): Promise<boolean> {
// 动态导入 store,避免初始化时的依赖问题
const { useAuthStore, useSlidesStore } = await import('@/store')
try {
const authStore = useAuthStore()
const slidesStore = useSlidesStore()
if (!authStore.isLoggedIn) {
// console.warn('用户未登录,无法保存')
return false
}
// 如果没有当前PPT ID且是强制保存,创建新PPT
if (!this.currentPPTId && force) {
try {
const response = await api.createPPT(slidesStore.title || '未命名演示文稿')
this.currentPPTId = response.pptId
// 更新slides store中的数据以匹配新创建的PPT
if (response.ppt) {
slidesStore.setSlides(response.ppt.slides)
slidesStore.setTitle(response.ppt.title)
slidesStore.setTheme(response.ppt.theme)
}
// console.log('创建新PPT并保存成功')
return true
}
catch (createError) {
// console.error('创建新PPT失败:', createError)
return false
}
}
if (!this.currentPPTId && !force) {
// console.warn('没有当前PPT ID')
return false
}
const pptData = {
pptId: this.currentPPTId,
title: slidesStore.title,
slides: slidesStore.slides,
theme: slidesStore.theme
}
await api.savePPT(pptData)
// console.log('PPT保存成功')
return true
}
catch (error) {
// console.error('PPT保存失败:', error)
return false
}
}
// 创建新PPT
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) {
// console.error('创建PPT失败:', error)
throw error
}
}
// 加载PPT
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)
// console.log('PPT加载成功')
return true
}
catch (error) {
// console.error('PPT加载失败:', error)
throw error
}
}
// 获取PPT列表
async getPPTList() {
const { useAuthStore } = await import('@/store')
const authStore = useAuthStore()
if (!authStore.isLoggedIn) {
throw new Error('用户未登录')
}
return await api.getPPTList()
}
// 删除PPT
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)
// 如果删除的是当前PPT,清除当前PPT ID
if (this.currentPPTId === pptId) {
this.currentPPTId = null
}
// console.log('PPT删除成功')
return true
}
catch (error) {
// console.error('PPT删除失败:', 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) {
// console.error('生成分享链接失败:', error)
throw error
}
}
// 手动保存
async manualSave(): Promise<boolean> {
return await this.savePPT(true)
}
}
// 创建单例实例
export const dataSyncService = new DataSyncService()
export default dataSyncService