155 lines
5.9 KiB
TypeScript
155 lines
5.9 KiB
TypeScript
import type { Dispatch, SetStateAction } from "react";
|
||
import type { AIRoutingConfig } from "@/api/sstc";
|
||
import { Button } from "@/components/ui/button";
|
||
import {
|
||
Dialog,
|
||
DialogContent,
|
||
DialogDescription,
|
||
DialogFooter,
|
||
DialogHeader,
|
||
DialogTitle,
|
||
} from "@/components/ui/dialog";
|
||
import { Input } from "@/components/ui/input";
|
||
|
||
interface ProjectSettingsDialogProps {
|
||
open: boolean;
|
||
onOpenChange: (open: boolean) => void;
|
||
routingDraft: AIRoutingConfig | null;
|
||
setRoutingDraft: Dispatch<SetStateAction<AIRoutingConfig | null>>;
|
||
routingConfigLoading: boolean;
|
||
isSaving: boolean;
|
||
onCancel: () => void;
|
||
onSave: (payload: {
|
||
cold_start_enabled: boolean;
|
||
signal_auto_enter_threshold: number;
|
||
project_auto_create_threshold: number;
|
||
project_uncertain_threshold: number;
|
||
}) => void;
|
||
}
|
||
|
||
export default function ProjectSettingsDialog({
|
||
open,
|
||
onOpenChange,
|
||
routingDraft,
|
||
setRoutingDraft,
|
||
routingConfigLoading,
|
||
isSaving,
|
||
onCancel,
|
||
onSave,
|
||
}: ProjectSettingsDialogProps) {
|
||
return (
|
||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||
<DialogContent className="w-[min(640px,calc(100vw-1rem))] max-w-[calc(100vw-1rem)] sm:max-w-[640px]">
|
||
<DialogHeader>
|
||
<DialogTitle>项目设置</DialogTitle>
|
||
<DialogDescription>
|
||
管理冷启动与自动路由阈值。示例:`0.80` 表示模型置信度达到 80% 即自动入库。
|
||
</DialogDescription>
|
||
</DialogHeader>
|
||
{!routingDraft ? (
|
||
<p className="text-sm text-muted-foreground">{routingConfigLoading ? "正在加载项目设置…" : "暂未加载到路由配置"}</p>
|
||
) : (
|
||
<div className="space-y-4">
|
||
<div className="rounded-md border bg-muted/20 p-3">
|
||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||
<div className="space-y-1">
|
||
<p className="text-sm font-semibold">冷启动开关</p>
|
||
<p className="text-xs text-muted-foreground">{routingDraft.tips.cold_start_enabled}</p>
|
||
</div>
|
||
<Button
|
||
size="sm"
|
||
variant={routingDraft.cold_start_enabled ? "default" : "outline"}
|
||
disabled={isSaving}
|
||
onClick={() =>
|
||
setRoutingDraft((prev) => (prev ? { ...prev, cold_start_enabled: !prev.cold_start_enabled } : prev))
|
||
}
|
||
>
|
||
冷启动:{routingDraft.cold_start_enabled ? "开启" : "关闭"}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid gap-3 md:grid-cols-3">
|
||
<label className="space-y-1 text-xs">
|
||
<span className="font-medium">自动入库阈值(confidence)</span>
|
||
<Input
|
||
type="number"
|
||
step="0.01"
|
||
min="0"
|
||
max="1"
|
||
value={routingDraft.signal_auto_enter_threshold}
|
||
disabled={isSaving}
|
||
onChange={(e) => {
|
||
const val = Number(e.target.value);
|
||
setRoutingDraft((prev) =>
|
||
prev && Number.isFinite(val) ? { ...prev, signal_auto_enter_threshold: val } : prev
|
||
);
|
||
}}
|
||
/>
|
||
<p className="text-muted-foreground">{routingDraft.tips.signal_auto_enter_threshold}</p>
|
||
</label>
|
||
|
||
<label className="space-y-1 text-xs">
|
||
<span className="font-medium">自动建项阈值(project_score)</span>
|
||
<Input
|
||
type="number"
|
||
step="0.01"
|
||
min="0"
|
||
max="1"
|
||
value={routingDraft.project_auto_create_threshold}
|
||
disabled={isSaving}
|
||
onChange={(e) => {
|
||
const val = Number(e.target.value);
|
||
setRoutingDraft((prev) =>
|
||
prev && Number.isFinite(val) ? { ...prev, project_auto_create_threshold: val } : prev
|
||
);
|
||
}}
|
||
/>
|
||
<p className="text-muted-foreground">{routingDraft.tips.project_auto_create_threshold}</p>
|
||
</label>
|
||
|
||
<label className="space-y-1 text-xs">
|
||
<span className="font-medium">项目待确认阈值(project_uncertain)</span>
|
||
<Input
|
||
type="number"
|
||
step="0.01"
|
||
min="0"
|
||
max="1"
|
||
value={routingDraft.project_uncertain_threshold}
|
||
disabled={isSaving}
|
||
onChange={(e) => {
|
||
const val = Number(e.target.value);
|
||
setRoutingDraft((prev) =>
|
||
prev && Number.isFinite(val) ? { ...prev, project_uncertain_threshold: val } : prev
|
||
);
|
||
}}
|
||
/>
|
||
<p className="text-muted-foreground">{routingDraft.tips.project_uncertain_threshold}</p>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
)}
|
||
<DialogFooter>
|
||
<Button variant="outline" onClick={onCancel}>
|
||
取消
|
||
</Button>
|
||
<Button
|
||
disabled={!routingDraft || isSaving}
|
||
onClick={() => {
|
||
if (!routingDraft) return;
|
||
onSave({
|
||
cold_start_enabled: routingDraft.cold_start_enabled,
|
||
signal_auto_enter_threshold: Number(routingDraft.signal_auto_enter_threshold.toFixed(2)),
|
||
project_auto_create_threshold: Number(routingDraft.project_auto_create_threshold.toFixed(2)),
|
||
project_uncertain_threshold: Number(routingDraft.project_uncertain_threshold.toFixed(2)),
|
||
});
|
||
}}
|
||
>
|
||
{isSaving ? "保存中…" : "保存设置"}
|
||
</Button>
|
||
</DialogFooter>
|
||
</DialogContent>
|
||
</Dialog>
|
||
);
|
||
}
|