"use client"; import { useState } from "react"; import { Play } from "lucide-react"; import { Button } from "@/components/ui/Button"; import { Field } from "@/components/ui/Field"; import { Radio } from "@/components/ui/Radio"; import { SectionHeader } from "@/components/ui/SectionHeader"; import { TextInput } from "@/components/ui/TextInput"; import { CHAIN_KINDS, type ChainKind } from "@/lib/chain/chain"; interface ChainStarterProps { // 发起一条链(链类型 + 起始章 + 章数);父层负责 POST run + 轮询。 onStart: (chainKey: ChainKind, startChapterNo: number, count: number) => void; // 链正在运行/等待裁决时禁用(避免重复发起)。 disabled: boolean; } const DEFAULT_START = 1; const DEFAULT_COUNT = 3; const MAX_COUNT = 50; const DEFAULT_CHAIN: ChainKind = "draft_volume"; // 链发起表单(净新):选起始章号 + 连续写几章 → 调 onStart。 // count 1..50(对齐后端 ChainRunRequest Field 约束;前端先拦一道,越界后端 422 兜底)。 export function ChainStarter({ onStart, disabled }: ChainStarterProps) { const [chainKey, setChainKey] = useState(DEFAULT_CHAIN); const [start, setStart] = useState(String(DEFAULT_START)); const [count, setCount] = useState(String(DEFAULT_COUNT)); const startNo = Number.parseInt(start, 10); const countNo = Number.parseInt(count, 10); const valid = Number.isInteger(startNo) && startNo >= 1 && Number.isInteger(countNo) && countNo >= 1 && countNo <= MAX_COUNT; return (
{ e.preventDefault(); if (valid && !disabled) onStart(chainKey, startNo, countNo); }} >
链类型
{CHAIN_KINDS.map((kind) => ( ))}
setStart(e.target.value)} aria-label="起始章号" /> setCount(e.target.value)} aria-label="连续章数" />
); }