feature: 新增支持拆书自选保留章节数,或者整本拆书功能

This commit is contained in:
xiamuceer
2026-04-02 11:03:58 +08:00
parent 099d12a1c9
commit 5968a3d29e
6 changed files with 158 additions and 23 deletions
+43 -1
View File
@@ -28,6 +28,7 @@ import { InboxOutlined, PlayCircleOutlined, ReloadOutlined, StopOutlined, Warnin
import { bookImportApi } from '../services/api';
import type {
BookImportApplyPayload,
BookImportExtractMode,
BookImportPreview,
BookImportStepFailure,
BookImportTask,
@@ -111,6 +112,8 @@ export default function BookImport() {
const { token } = theme.useToken();
const isMobile = window.innerWidth <= 768;
const [file, setFile] = useState<File | null>(null);
const [extractMode, setExtractMode] = useState<BookImportExtractMode>('tail');
const [tailChapterCount, setTailChapterCount] = useState(10);
const [taskId, setTaskId] = useState<string | null>(null);
const [taskStatus, setTaskStatus] = useState<BookImportTask | null>(null);
@@ -322,8 +325,13 @@ export default function BookImport() {
setPreview(null);
setTaskStatus(null);
const normalizedTailChapterCount = Math.max(5, Math.ceil(tailChapterCount / 5) * 5);
const normalizedExtractMode = normalizedTailChapterCount > 50 ? 'full' : extractMode;
const response = await bookImportApi.createTask({
file,
extract_mode: normalizedExtractMode,
tail_chapter_count: normalizedTailChapterCount,
});
setTaskId(response.task_id);
@@ -546,6 +554,8 @@ export default function BookImport() {
setRetrying(false);
setRetryProgress(0);
setRetryMessage('');
setExtractMode('tail');
setTailChapterCount(10);
message.success('已重新开始,请重新上传 TXT 并解析');
}, []);
@@ -688,6 +698,38 @@ export default function BookImport() {
<p className="ant-upload-hint"> .txt 50MB</p>
</Dragger>
<Card size="small" title="解析范围设置">
<Space direction="vertical" style={{ width: '100%' }} size={12}>
<Select
value={extractMode}
onChange={(value) => setExtractMode(value)}
options={[
{ label: '截取末 x 章反向生成', value: 'tail' },
{ label: '整本反向生成', value: 'full' },
]}
style={{ width: '100%' }}
/>
<InputNumber
min={5}
max={55}
step={5}
precision={0}
value={tailChapterCount}
disabled={extractMode !== 'tail'}
onChange={(value) => setTailChapterCount(typeof value === 'number' ? value : 10)}
addonBefore="末尾章节数"
style={{ width: '100%' }}
/>
<Text type="secondary">
{extractMode === 'tail'
? tailChapterCount > 50
? '当前输入已超过 50 章,将自动按整本拆处理。'
: `当前将截取末 ${Math.max(5, Math.ceil(tailChapterCount / 5) * 5)} 章进行反向生成;章节数必须为 5 的倍数,最多 50 章。`
: '当前将基于整本内容进行反向生成,适合完整拆书但耗时可能更长。'}
</Text>
</Space>
</Card>
<Alert
type="info"
showIcon
@@ -713,7 +755,7 @@ export default function BookImport() {
}
/>
<Space>
<Space wrap>
<Button
type="primary"
icon={<PlayCircleOutlined />}
+5 -3
View File
@@ -53,6 +53,7 @@ import type {
BookImportTask,
BookImportPreview,
BookImportApplyPayload,
BookImportCreateTaskPayload,
BookImportResult,
BookImportRetryResult,
BatchAnalysisStatusResponse,
@@ -455,11 +456,12 @@ export const projectApi = {
};
export const bookImportApi = {
createTask: (params: {
file: File;
}) => {
createTask: (params: BookImportCreateTaskPayload) => {
const formData = new FormData();
formData.append('file', params.file);
const tailChapterCount = params.tail_chapter_count ?? 10;
formData.append('extract_mode', params.extract_mode ?? 'tail');
formData.append('tail_chapter_count', String(tailChapterCount));
return api.post<unknown, { task_id: string; status: BookImportTask['status'] }>(
'/book-import/tasks',
+7
View File
@@ -985,6 +985,7 @@ export interface ForeshadowContextResponse {
export type BookImportTaskStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
export type BookImportWarningLevel = 'info' | 'warning' | 'error';
export type BookImportExtractMode = 'tail' | 'full';
export interface BookImportWarning {
code: string;
@@ -1041,6 +1042,12 @@ export interface BookImportApplyPayload {
import_mode?: 'append' | 'overwrite';
}
export interface BookImportCreateTaskPayload {
file: File;
extract_mode?: BookImportExtractMode;
tail_chapter_count?: number;
}
export interface BookImportResult {
success: boolean;
project_id: string;