|
@@ -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="格式:原文本=新文本,每行一个规则 例如: 第一章=第1章 作者=作者名"></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="格式:原文本=新文本,每行一个规则 例如: 第一章=第1章 作者=作者名"></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() {
|