Selaa lähdekoodia

feat(ExportDialog, ImportDialog, ChapterPanel): 改进封面处理和章节内容管理

- 在ExportDialog中根据封面图片类型动态设置扩展名和媒体类型
- 更新章节内容添加逻辑,移除默认内容占位符
- 在ImportDialog中支持GIF格式封面图片的处理
- 优化章节内容中base64图片的扩展名处理逻辑
YourName 1 viikko sitten
vanhempi
commit
9d84bb653b

+ 1 - 1
src/components/ChapterPanel.vue

@@ -263,7 +263,7 @@ function addChapterToParent(nodes, parentId) {
         id: Date.now(),
         label: newNodeName.value.trim(),
         type: 'chapter',
-        content: '<p>请输入章节内容...</p>',
+        content: '',
         children: []
       });
       return true;

+ 51 - 5
src/components/ExportDialog.vue

@@ -199,6 +199,15 @@ async function generateEPUB() {
     await addCoverFile(zip);
     // 添加封面HTML文件
     const bookTitle = props.bookInfo.title || exportForm.value.title;
+    
+    // 根据封面图片类型确定扩展名
+    let coverExtension = '.jpg'; // 默认扩展名
+    if (props.bookInfo.cover && props.bookInfo.cover.includes('image/png')) {
+      coverExtension = '.png';
+    } else if (props.bookInfo.cover && props.bookInfo.cover.includes('image/gif')) {
+      coverExtension = '.gif';
+    }
+    
     const coverHtml = `<?xml version="1.0" encoding="utf-8"?>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
   "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
@@ -211,7 +220,7 @@ async function generateEPUB() {
   <div class="cover">
     <h1 class="title">${bookTitle}</h1>
     <p class="author">作者:${exportForm.value.author}</p>
-    <img alt="cover" class="coverborder" src="../Images/cover.jpg" />
+    <img alt="cover" class="coverborder" src="../Images/cover${coverExtension}" />
   </div>
 </body>
 </html>`;
@@ -243,7 +252,18 @@ function generateContentOpf() {
   
   // 添加封面
   if (hasCover.value) {
-    manifest.push(`    <item id="cover" href="../Images/cover.jpg" media-type="image/jpeg" properties="cover-image"/>`);
+    // 根据封面图片类型确定扩展名和媒体类型
+    let coverExtension = '.jpg';
+    let mediaType = 'image/jpeg';
+    if (props.bookInfo.cover && props.bookInfo.cover.includes('image/png')) {
+      coverExtension = '.png';
+      mediaType = 'image/png';
+    } else if (props.bookInfo.cover && props.bookInfo.cover.includes('image/gif')) {
+      coverExtension = '.gif';
+      mediaType = 'image/gif';
+    }
+    
+    manifest.push(`    <item id="cover" href="../Images/cover${coverExtension}" media-type="${mediaType}" properties="cover-image"/>`);
     manifest.push(`    <item id="cover-html" href="Text/cover.xhtml" media-type="application/xhtml+xml"/>`);
     // 将封面HTML添加到书脊开头
     spine.unshift(`    <itemref idref="cover-html"/>`);
@@ -278,7 +298,17 @@ function generateContentOpf() {
     <meta property="dcterms:modified">${new Date().toISOString()}</meta>`;
   
   // 如果有封面,添加封面元数据
-  const coverMetadata = hasCover.value ? '\n    <meta name="cover" content="Images/cover.jpg"/>' : '';
+  let coverMetadata = '';
+  if (hasCover.value) {
+    // 根据封面图片类型确定扩展名
+    let coverExtension = '.jpg';
+    if (props.bookInfo.cover && props.bookInfo.cover.includes('image/png')) {
+      coverExtension = '.png';
+    } else if (props.bookInfo.cover && props.bookInfo.cover.includes('image/gif')) {
+      coverExtension = '.gif';
+    }
+    coverMetadata = `\n    <meta name="cover" content="Images/cover${coverExtension}"/>`;
+  }
   
   return `<?xml version="1.0" encoding="UTF-8"?>
 <package version="3.0" xmlns="http://www.idpf.org/2007/opf">
@@ -402,7 +432,15 @@ function generateChapterContent(chapter, chapterId) {
   
   // 查找并处理base64图片
   processedContent = processedContent.replace(/<img[^>]*src="(data:image\/[^;]+;base64,[^"]+)"[^>]*>/g, (match, src) => {
-    const imageName = `image-${chapterId}-${imageMap.size + 1}.jpg`;
+    // 根据图片类型确定扩展名
+    let extension = '.jpg'; // 默认扩展名
+    if (src.includes('image/png')) {
+      extension = '.png';
+    } else if (src.includes('image/gif')) {
+      extension = '.gif';
+    }
+    
+    const imageName = `image-${chapterId}-${imageMap.size + 1}${extension}`;
     imageMap.set(imageName, src);
     // 输出章节中发现的base64图片数据
     console.log(`章节${chapterId}中发现的base64图片数据:`, src);
@@ -497,7 +535,15 @@ async function addCoverFile(zip) {
         console.log('添加封面文件到EPUB');
         console.log('最终用于EPUB的base64数据长度:', base64Data.length);
         console.log('最终用于EPUB的base64数据预览:', base64Data.substring(0, Math.min(100, base64Data.length)) + '...');
-        zip.file('OEBPS/Images/cover.jpg', base64Data, { base64: true });
+        // 根据封面图片类型确定扩展名
+        let coverExtension = '.jpg'; // 默认扩展名
+        if (imageData.includes('image/png')) {
+          coverExtension = '.png';
+        } else if (imageData.includes('image/gif')) {
+          coverExtension = '.gif';
+        }
+        
+        zip.file(`OEBPS/Images/cover${coverExtension}`, base64Data, { base64: true });
       } else {
         console.log('base64数据为空');
       }

+ 12 - 7
src/components/ImportDialog.vue

@@ -517,9 +517,14 @@ async function loadChapterContent(src, zipData) {
                const imageFile = zipData.file(imagePath);
                if (imageFile) {
                  console.log('找到图片文件:', imagePath);
-                 const imageData = await imageFile.async('base64');
-                 const imageType = imagePath.endsWith('.png') ? 'image/png' : 'image/jpeg';
-                 const base64Src = `data:${imageType};base64,${imageData}`;
+                                   const imageData = await imageFile.async('base64');
+                  let imageType = 'image/jpeg'; // 默认类型
+                  if (imagePath.endsWith('.png')) {
+                    imageType = 'image/png';
+                  } else if (imagePath.endsWith('.gif')) {
+                    imageType = 'image/gif';
+                  }
+                  const base64Src = `data:${imageType};base64,${imageData}`;
                  
                  console.log('图片转换为base64成功');
                  
@@ -554,10 +559,10 @@ async function loadChapterContent(src, zipData) {
 // 处理封面
 async function processCover(metadata, zipData) {
   try {
-    // 查找封面图片
-    const coverFiles = Object.keys(zipData.files).filter(file =>
-      file.includes('cover') && (file.endsWith('.jpg') || file.endsWith('.png'))
-    );
+         // 查找封面图片
+     const coverFiles = Object.keys(zipData.files).filter(file =>
+       file.includes('cover') && (file.endsWith('.jpg') || file.endsWith('.png') || file.endsWith('.gif'))
+     );
 
     if (coverFiles.length > 0) {
       const coverFile = coverFiles[0];