Selaa lähdekoodia

feat(ChapterTools): 新增一键应用智能分段到所有章节功能

- 在章节工具中添加“应用到所有章节”按钮,允许用户将当前智能分段设置应用于所有章节
- 增强错误处理和用户提示,确保操作的安全性和可逆性
- 更新相关逻辑以支持批量处理章节内容
YourName 1 viikko sitten
vanhempi
commit
33ee16f209
1 muutettua tiedostoa jossa 51 lisäystä ja 134 poistoa
  1. 51 134
      src/components/ChapterTools.vue

+ 51 - 134
src/components/ChapterTools.vue

@@ -282,6 +282,7 @@
                      <el-button @click="resetSmartParagraph">重置</el-button>
                      <el-button @click="previewSmartParagraphResult" :disabled="!smartParagraphResult">预览结果</el-button>
                      <el-button type="success" @click="applySmartParagraphToChapter" :disabled="!smartParagraphResult || !smartParagraphForm.selectedChapterId">应用到章节</el-button>
+                     <el-button type="warning" @click="applySmartParagraphToAllChapters" :disabled="allChapters.length === 0">应用到所有章节</el-button>
                   </el-form-item>
                 </el-form>
 
@@ -319,128 +320,6 @@
           </el-tabs>
         </div>
       </el-tab-pane>
-      <el-form :model="textProcessForm" label-width="120px">
-        <el-form-item label="处理内容">
-          <div class="content-input-section">
-            <el-upload class="file-upload" :auto-upload="false" :show-file-list="false" accept=".txt"
-              :on-change="handleTextProcessFileChange">
-              <el-button type="primary" size="small">
-                <el-icon>
-                  <Upload />
-                </el-icon>
-                选择TXT文件
-              </el-button>
-            </el-upload>
-            <div class="file-info" v-if="textProcessForm.fileName">
-              <span>已选择文件: {{ textProcessForm.fileName }}</span>
-              <el-button type="text" size="small" @click="clearTextProcessFile">清除</el-button>
-            </div>
-            <el-input v-model="textProcessForm.content" type="textarea" :rows="8"
-              placeholder="请输入要处理的文本内容,或选择TXT文件..."></el-input>
-          </div>
-        </el-form-item>
-
-        <el-form-item label="处理选项">
-          <el-checkbox v-model="textProcessForm.removeSpaces">去除所有空格和换行</el-checkbox>
-          <el-checkbox v-model="textProcessForm.removeText">去除指定文本</el-checkbox>
-          <el-checkbox v-model="textProcessForm.removeHtml">去除HTML标签</el-checkbox>
-          <el-checkbox v-model="textProcessForm.replaceText">替换指定文本</el-checkbox>
-        </el-form-item>
-
-        <el-form-item v-if="textProcessForm.removeText" label="去除的文本">
-          <el-input v-model="textProcessForm.removeTextList" type="textarea" :rows="3"
-            placeholder="请输入要去除的文本,每行一个"></el-input>
-        </el-form-item>
-
-        <el-form-item v-if="textProcessForm.replaceText" label="替换规则">
-          <el-input v-model="textProcessForm.replaceRules" type="textarea" :rows="5"
-            placeholder="格式:原文本=新文本,每行一个规则&#10;例如:&#10;第一章=第1章&#10;作者=作者名"></el-input>
-        </el-form-item>
-
-        <el-form-item>
-          <el-button type="primary" @click="processText">处理文本</el-button>
-          <el-button @click="clearTextProcess">清空</el-button>
-        </el-form-item>
-      </el-form>
-
-      <div v-if="textProcessResult" class="result-section">
-        <h4>处理结果:</h4>
-        <el-input v-model="textProcessResult" type="textarea" :rows="8" readonly></el-input>
-      </div>
-
-      <el-tab-pane label="批量章节处理" name="batch">
-        <div class="batch-process-section">
-          <h4>批量处理已导入的章节</h4>
-
-          <el-form :model="batchProcessForm" label-width="120px">
-            <el-form-item label="选择章节">
-              <el-select v-model="batchProcessForm.selectedChapters" multiple placeholder="请选择要处理的章节"
-                style="width: 100%">
-                <el-option v-for="chapter in allChapters" :key="chapter.id" :label="chapter.label"
-                  :value="chapter.id"></el-option>
-              </el-select>
-              <div style="margin-top: 10px;">
-                <el-button size="small" @click="selectAllChapters">全选</el-button>
-                <el-button size="small" @click="clearSelectedChapters">清空</el-button>
-              </div>
-            </el-form-item>
-
-            <el-form-item label="处理选项">
-              <el-checkbox v-model="batchProcessForm.removeSpaces">去除所有空格和换行</el-checkbox>
-              <el-checkbox v-model="batchProcessForm.removeText">去除指定文本</el-checkbox>
-              <el-checkbox v-model="batchProcessForm.removeHtml">去除HTML标签</el-checkbox>
-              <el-checkbox v-model="batchProcessForm.replaceText">替换指定文本</el-checkbox>
-            </el-form-item>
-
-            <el-form-item label="正则处理">
-              <el-checkbox v-model="batchProcessForm.useRegex">启用正则表达式处理</el-checkbox>
-            </el-form-item>
-            <el-form-item v-if="batchProcessForm.useRegex" label="正则表达式">
-              <el-input v-model="batchProcessForm.regexPattern" placeholder="请输入正则表达式,如:分卷阅读\d+" />
-            </el-form-item>
-            <el-form-item v-if="batchProcessForm.useRegex" label="替换内容">
-              <el-input v-model="batchProcessForm.regexReplace" placeholder="留空则为去除,填写内容则为替换" />
-              <div class="regex-examples" style="margin-top: 5px; color: #888; font-size: 12px;">
-                例如:<br />
-                <span class="example-item">分卷阅读\\d+</span> 匹配“分卷阅读1、分卷阅读2”等<br />
-                <span class="example-item">(第[0-9]+章)</span> 匹配“第12章”等
-              </div>
-            </el-form-item>
-
-            <el-form-item v-if="batchProcessForm.removeText" label="去除的文本">
-              <el-input v-model="batchProcessForm.removeTextList" type="textarea" :rows="3"
-                placeholder="请输入要去除的文本,每行一个"></el-input>
-            </el-form-item>
-
-            <el-form-item v-if="batchProcessForm.replaceText" label="替换规则">
-              <el-input v-model="batchProcessForm.replaceRules" type="textarea" :rows="5"
-                placeholder="格式:原文本=新文本,每行一个规则&#10;例如:&#10;第一章=第1章&#10;作者=作者名"></el-input>
-            </el-form-item>
-
-            <el-form-item>
-              <el-button type="primary" @click="processBatchChapters">批量处理</el-button>
-              <el-button @click="clearBatchProcess">清空</el-button>
-            </el-form-item>
-          </el-form>
-
-          <div v-if="batchProcessResult.length > 0" class="result-section">
-            <h4>处理结果:</h4>
-            <el-table :data="batchProcessResult" style="width: 100%">
-              <el-table-column prop="chapterName" label="章节名称" width="200"></el-table-column>
-              <el-table-column prop="originalLength" label="原内容长度" width="120"></el-table-column>
-              <el-table-column prop="newLength" label="处理后长度" width="120"></el-table-column>
-              <el-table-column prop="status" label="状态" width="100">
-                <template #default="scope">
-                  <el-tag :type="scope.row.status === 'success' ? 'success' : 'danger'">
-                    {{ scope.row.status === 'success' ? '成功' : '失败' }}
-                  </el-tag>
-                </template>
-              </el-table-column>
-              <el-table-column prop="message" label="消息"></el-table-column>
-            </el-table>
-          </div>
-        </div>
-      </el-tab-pane>
     </el-tabs>
   </div>
 </template>
@@ -462,6 +341,7 @@ const props = defineProps({
 const emit = defineEmits(['update-tree']);
 
 const activeTab = ref('quick-import');
+const textProcessActiveTab = ref('single');
 
 const quickImportForm = ref({
   selectedVolume: null,
@@ -486,8 +366,6 @@ const textProcessForm = ref({
 
 const textProcessResult = ref('');
 
-const textProcessActiveTab = ref('single');
-
 // 1. 扩展 batchProcessForm 数据结构
 const batchProcessForm = ref({
   selectedChapters: [],
@@ -982,17 +860,56 @@ function clearSmartParagraphChapterSelection() {
 
 // 应用智能分段结果到章节
 function applySmartParagraphToChapter() {
-  if (!smartParagraphForm.value.selectedChapterId || !smartParagraphResult.value) return;
-
-  const selectedChapter = allChapters.value.find(chapter => chapter.id === smartParagraphForm.value.selectedChapterId);
-  if (selectedChapter) {
-    selectedChapter.content = smartParagraphResult.value.paragraphs.join('\n\n');
-    ElMessage.success('章节内容已更新');
-    // 触发章节树更新
-    emit('update-tree', props.treeData);
-  } else {
-    ElMessage.error('未找到选中的章节');
+  if (!smartParagraphForm.value.selectedChapterId || !smartParagraphResult.value) {
+    ElMessage.warning('请先选择章节并完成智能分段');
+    return;
   }
+
+  try {
+    const newTreeData = JSON.parse(JSON.stringify(props.treeData));
+    const processedContent = smartParagraphResult.value.paragraphs.join('\n\n');
+    
+    if (updateChapterContent(newTreeData, smartParagraphForm.value.selectedChapterId, processedContent)) {
+      emit('update-tree', newTreeData);
+      ElMessage.success('智能分段结果已成功应用到章节');
+    } else {
+      ElMessage.error('应用失败,未找到选中的章节');
+    }
+  } catch (error) {
+    ElMessage.error('应用失败:' + error.message);
+  }
+}
+
+// 一键应用到所有章节
+function applySmartParagraphToAllChapters() {
+  if (!allChapters.value || allChapters.value.length === 0) {
+    ElMessage.warning('没有可处理的章节');
+    return;
+  }
+
+  ElMessageBox.confirm(
+    `将对所有章节应用当前智能分段设置,此操作会覆盖原有内容,是否继续?`,
+    '确认批量应用',
+    {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    }
+  ).then(() => {
+    const newTreeData = JSON.parse(JSON.stringify(props.treeData));
+    let processedCount = 0;
+
+    for (const chapter of allChapters.value) {
+      const original = chapter.content || '';
+      const result = smartParagraphSplit(original, smartParagraphForm.value);
+      const newContent = result.paragraphs.join('\n\n');
+      updateChapterContent(newTreeData, chapter.id, newContent);
+      processedCount++;
+    }
+
+    emit('update-tree', newTreeData);
+    ElMessage.success(`已对 ${processedCount} 个章节应用智能分段`);
+  }).catch(() => {});
 }
 
 function previewSmartParagraphResult() {