release: v1.2.0 手术图文病历报告系统

This commit is contained in:
2026-04-16 21:41:21 +08:00
parent ebe13ba8af
commit c55a55a27b
42 changed files with 73 additions and 1922 deletions

View File

@@ -36,9 +36,11 @@ export default function SystemSettings() {
savedSettings.defaultTemplate = savedTemplates[0].id;
}
if (!savedSettings.frameMode) savedSettings.frameMode = 'uniform';
if (typeof savedSettings.autoInsertFrames !== 'boolean') savedSettings.autoInsertFrames = false;
if (typeof savedSettings.autoInsertDelay !== 'number') savedSettings.autoInsertDelay = 0;
setSettings(savedSettings);
} else if (savedTemplates.length > 0) {
setSettings(prev => ({ ...prev, defaultTemplate: savedTemplates[0].id, frameMode: prev.frameMode || 'uniform' }));
setSettings(prev => ({ ...prev, defaultTemplate: savedTemplates[0].id, frameMode: prev.frameMode || 'uniform', autoInsertFrames: typeof prev.autoInsertFrames === 'boolean' ? prev.autoInsertFrames : false, autoInsertDelay: typeof prev.autoInsertDelay === 'number' ? prev.autoInsertDelay : 0 }));
}
setTemplates(savedTemplates);
}, [navigate]);
@@ -172,6 +174,33 @@ export default function SystemSettings() {
</div>
</div>
<div className="flex items-center gap-2">
<input
type="checkbox"
id="autoInsertFrames"
checked={settings.autoInsertFrames || false}
onChange={(e) => setSettings({ ...settings, autoInsertFrames: e.target.checked })}
className="w-4 h-4 accent-accent cursor-pointer"
/>
<label htmlFor="autoInsertFrames" className="text-sm text-text-main cursor-pointer"></label>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div className="space-y-1.5">
<label className="block text-xs font-bold text-text-main uppercase tracking-wider"> (s)</label>
<input
type="number"
min={0}
step={0.1}
value={settings.autoInsertDelay || 0}
onChange={(e) => setSettings({ ...settings, autoInsertDelay: Math.max(0, parseFloat(e.target.value) || 0) })}
className="input-minimal bg-white w-full"
/>
</div>
</div>
<p className="text-[11px] text-text-muted"></p>
<div className="space-y-1.5">
<label className="block text-xs font-bold text-text-main uppercase tracking-wider"> (%)</label>
<div className="grid grid-cols-2 sm:grid-cols-4 md:grid-cols-6 gap-3">
@@ -191,11 +220,30 @@ export default function SystemSettings() {
className="input-minimal w-full pr-6 text-center"
/>
<span className="absolute right-2 top-1/2 -translate-y-1/2 text-[10px] text-text-muted">%</span>
{settings.autoInsertFrames && (
<span
onClick={() => {
const current = settings.autoInsertFrameIndices || [];
const next = current.includes(idx)
? current.filter(i => i !== idx)
: [...current, idx].sort((a, b) => a - b);
setSettings({ ...settings, autoInsertFrameIndices: next });
}}
className={`absolute top-1 left-1 cursor-pointer transition-colors ${
(settings.autoInsertFrameIndices || []).includes(idx) ? 'text-green-500' : 'text-slate-300'
}`}
>
<Check size={12} />
</span>
)}
<button
type="button"
onClick={() => {
const newPos = settings.framePositions.filter((_, i) => i !== idx);
setSettings({ ...settings, framePositions: newPos, frameCount: newPos.length });
const newIndices = (settings.autoInsertFrameIndices || [])
.filter(i => i !== idx)
.map(i => i > idx ? i - 1 : i);
setSettings({ ...settings, framePositions: newPos, frameCount: newPos.length, autoInsertFrameIndices: newIndices });
}}
className="absolute -top-2 -right-2 w-5 h-5 bg-red-500 text-white rounded-full flex items-center justify-center text-[10px] opacity-0 group-hover:opacity-100 transition-all shadow-sm"
>

View File

@@ -75,4 +75,7 @@ export interface SystemSettings {
apiKey: string;
defaultTemplate?: string;
frameMode?: 'uniform' | 'keep';
autoInsertFrames?: boolean;
autoInsertFrameIndices?: number[];
autoInsertDelay?: number;
}