Просмотр исходного кода

fix: show ISSUE warning on continuity check, show skipped Step 5 in progress bar

nonvioce 6 месяцев назад
Родитель
Сommit
0f096b1591

+ 21 - 8
src/app/features/novel-writer/components/ChapterDraftPipeline.tsx

@@ -92,6 +92,7 @@ export default function ChapterDraftPipeline({
 
   const [currentStep, setCurrentStep] = useState<PipelineStep>(0);
   const [showCancelConfirm, setShowCancelConfirm] = useState(false);
+  const [stepSkipped, setStepSkipped] = useState(false); // true when Step 5 is skipped (non-trigger chapter)
   const [pipelineState, setPipelineState] = useState<PipelineState>(getInitialState);
   const [chapterEvents, setChapterEvents] = useState<EventNode[]>([]);
   const [ironRulesContent, setIronRulesContent] = useState('');
@@ -191,11 +192,16 @@ export default function ChapterDraftPipeline({
   // Step 4 完成(连续性检查)→ 条件性进入 Step 5(每5章一次)或直接完成
   const handleStep4Complete = useCallback(() => {
     if (chapterIndex % 5 === 0) {
+      setStepSkipped(false);
       setCurrentStep(5);
     } else {
-      sessionStorage.removeItem(storageKey);
-      const title = pipelineState.controlCard?.workingTitle || `第${chapterIndex}章`;
-      onComplete(title, pipelineState.chapterContent);
+      setStepSkipped(true);
+      // Delay completion slightly so user can see the skipped step indicator
+      setTimeout(() => {
+        sessionStorage.removeItem(storageKey);
+        const title = pipelineState.controlCard?.workingTitle || `第${chapterIndex}章`;
+        onComplete(title, pipelineState.chapterContent);
+      }, 800);
     }
   }, [onComplete, pipelineState.chapterContent, pipelineState.controlCard, chapterIndex, storageKey]);
 
@@ -240,9 +246,10 @@ export default function ChapterDraftPipeline({
           {/* 步骤进度条 */}
           <div className="flex items-center">
             {STEPS.map((step, index) => {
-              const isCompleted = currentStep > step.id;
+              const isSkipped = step.id === 5 && stepSkipped;
+              const isCompleted = currentStep > step.id || isSkipped;
               const isCurrent = currentStep === step.id;
-              const isUpcoming = currentStep < step.id;
+              const isUpcoming = currentStep < step.id && !isSkipped;
 
               return (
                 <div key={step.id} className="flex items-center flex-1">
@@ -250,14 +257,18 @@ export default function ChapterDraftPipeline({
                   <div className="flex flex-col items-center">
                     <div
                       className={`w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium transition-all ${
-                        isCompleted
+                        isSkipped
+                          ? 'bg-gray-200 text-gray-400 line-through'
+                          : isCompleted
                           ? 'bg-indigo-600 text-white'
                           : isCurrent
                           ? 'bg-indigo-600 text-white ring-4 ring-indigo-100'
                           : 'bg-gray-100 text-gray-400'
                       }`}
                     >
-                      {isCompleted ? (
+                      {isSkipped ? (
+                        <span className="text-xs">-</span>
+                      ) : isCompleted ? (
                         <Check className="h-4 w-4" />
                       ) : (
                         <span>{step.id}</span>
@@ -265,7 +276,9 @@ export default function ChapterDraftPipeline({
                     </div>
                     <span
                       className={`mt-1 text-xs whitespace-nowrap ${
-                        isCurrent
+                        isSkipped
+                          ? 'text-gray-300 line-through'
+                          : isCurrent
                           ? 'text-indigo-600 font-medium'
                           : isCompleted
                           ? 'text-indigo-400'

+ 18 - 5
src/app/features/novel-writer/components/pipeline/Step6ContinuityCheck.tsx

@@ -1,7 +1,7 @@
 'use client';
 
 import { useState } from 'react';
-import { Shield, ArrowLeft, Check } from 'lucide-react';
+import { Shield, ArrowLeft, Check, AlertTriangle } from 'lucide-react';
 import { CONTINUITY_CHECK_ITEMS, buildContinuityCheckPrompt } from '@/app/lib/chapter-prompts';
 import type { EventNode } from '@/app/lib/novel-types';
 
@@ -41,6 +41,9 @@ export default function Step6ContinuityCheck({
   const [results, setResults] = useState<CheckResult[] | null>(null);
   const [error, setError] = useState<string | null>(null);
 
+  const issueCount = results ? results.filter(r => r.status === 'issue').length : 0;
+  const hasIssues = issueCount > 0;
+
   const toggle = (id: string) => {
     const next = new Set(selected);
     if (next.has(id)) next.delete(id);
@@ -218,10 +221,20 @@ export default function Step6ContinuityCheck({
             className="flex items-center gap-1 px-4 py-2 text-sm text-gray-600 border border-gray-300 rounded-lg hover:bg-gray-50">
             <ArrowLeft className="h-4 w-4" /> 返回
           </button>
-          <button onClick={onComplete}
-            className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700">
-            <Check className="h-4 w-4" /> 完成创作
-          </button>
+          {hasIssues ? (
+            <div className="flex flex-col items-end gap-1">
+              <button onClick={onComplete}
+                className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-amber-600 rounded-lg hover:bg-amber-700">
+                <AlertTriangle className="h-4 w-4" /> 忽略并继续
+              </button>
+              <span className="text-xs text-red-500">有 {issueCount} 项未通过,建议返回修改后再提交</span>
+            </div>
+          ) : (
+            <button onClick={onComplete}
+              className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-green-600 rounded-lg hover:bg-green-700">
+              <Check className="h-4 w-4" /> 完成创作
+            </button>
+          )}
         </div>
       </div>
     </div>