新增: 首页 + 资料导入 + PDF导出 + AI文档生成

This commit is contained in:
lxy
2026-08-17 09:34:12 +08:00
parent a5ebfd8b74
commit 352496c00a
13 changed files with 1698 additions and 12 deletions
+60 -8
View File
@@ -2,7 +2,7 @@
App.vue 根组件编辑/演示模式切换工具栏三栏布局弹窗
===================================================================== -->
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
import { store } from './core/store'
import Toolbar from './components/editor/Toolbar.vue'
import ThumbBar from './components/editor/ThumbBar.vue'
@@ -12,10 +12,13 @@ import AiPanel from './components/ai/AiPanel.vue'
import SettingsModal from './components/modals/SettingsModal.vue'
import LibraryModal from './components/modals/LibraryModal.vue'
import TemplateModal from './components/modals/TemplateModal.vue'
import ImportModal from './components/modals/ImportModal.vue'
import PrintModal from './components/modals/PrintModal.vue'
import PresentMode from './components/present/PresentMode.vue'
import HomePage from './components/HomePage.vue'
/* ---------- 模式 ---------- */
const mode = ref<'editor' | 'present'>('editor')
const mode = ref<'home' | 'editor' | 'present'>('home')
const presentVisible = ref(false)
const presentStartIndex = ref(0)
@@ -29,6 +32,9 @@ function switchTab(name: 'props' | 'ai') {
const settingsVisible = ref(false)
const libraryVisible = ref(false)
const templateVisible = ref(false)
const importVisible = ref(false)
const printVisible = ref(false)
const deckLoaded = ref(false) // 文库/导入是否加载了新 deck,防止误切
/* ---------- toast ---------- */
const toastText = ref('')
@@ -96,6 +102,7 @@ function onImportJson() {
try {
store.importJSON(reader.result as string)
toast('已导入')
if (mode.value === 'home') mode.value = 'editor'
} catch (e: any) {
toast('导入失败:' + (e?.message || String(e)))
}
@@ -105,13 +112,27 @@ function onImportJson() {
input.click()
}
function onNewBlank() {
store.newBlankDeck()
deckLoaded.value = true
mode.value = 'editor'
}
function onImportMaterials() { importVisible.value = true }
function onImportClose() {
importVisible.value = false
if (mode.value === 'home') {
const slides = store.getSlides()
// 不是仅有 1 页空白页时视为已导入内容
if (slides.length > 1 || slides[0]?.elements?.length > 0) {
mode.value = 'editor'
}
}
}
function onExportPdf() {
// 用浏览器打印 + @media print CSS 实现 PDF 导出
// 演示模式的 slide-layer 已有 print 样式
document.body.classList.add('printing')
window.print()
setTimeout(() => document.body.classList.remove('printing'), 500)
toast('在打印对话框中选择「另存为 PDF」')
printVisible.value = true
}
/* ---------- 全局快捷键(编辑模式) ---------- */
@@ -146,12 +167,32 @@ function onKey(e: KeyboardEvent) {
onMounted(() => {
document.addEventListener('keydown', onKey)
})
/* 文库关闭时若在首页且从文库加载了 deck 则切入编辑 */
watch(libraryVisible, (now, prev) => {
if (prev && !now && deckLoaded.value) {
deckLoaded.value = false
if (mode.value === 'home') mode.value = 'editor'
}
})
onUnmounted(() => {
document.removeEventListener('keydown', onKey)
})
</script>
<template>
<!-- ===================== 首页 ===================== -->
<HomePage
v-show="mode === 'home'"
@new-blank="onNewBlank"
@open-library="libraryVisible = true"
@import-materials="importVisible = true"
@open-deck="deckLoaded = true; mode = 'editor'"
@ai-create="onNewBlank(); switchTab('ai')"
@toast="toast"
@open-settings="settingsVisible = true"
/>
<!-- ===================== 编辑模式 ===================== -->
<div v-show="mode === 'editor'" class="app-editor">
<Toolbar
@@ -163,6 +204,7 @@ onUnmounted(() => {
@save="onSave"
@open-templates="templateVisible = true"
@export-json="onExportJson"
@import-materials="onImportMaterials"
@import-json="onImportJson"
@export-pdf="onExportPdf"
/>
@@ -218,6 +260,16 @@ onUnmounted(() => {
@close="templateVisible = false"
@toast="toast"
/>
<ImportModal
:visible="importVisible"
@close="onImportClose"
@toast="toast"
@open-settings="settingsVisible = true"
/>
<PrintModal
v-if="printVisible"
@close="printVisible = false"
/>
<!-- 轻提示 -->
<div class="toast" :class="{ show: toastShow }">{{ toastText }}</div>