auto-save 2026-05-13 11:23 (~4)
This commit is contained in:
@@ -1323,6 +1323,13 @@
|
||||
"type": "session-heartbeat",
|
||||
"message": "Claude 会话活跃 · 最近命令:claude · 2 项未提交变更 · 最近提交:auto-save 2026-05-13 11:12 (~1)",
|
||||
"files_changed": 2
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-13T11:17:52+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-13 11:17 (~2)",
|
||||
"hash": "f4ce533",
|
||||
"files_changed": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
18
api/main.py
18
api/main.py
@@ -1037,10 +1037,22 @@ def cleanup_frame(job_id: str, idx: int, req: CleanupReq | None = None) -> Job:
|
||||
if not frame_path.exists():
|
||||
raise HTTPException(404, "frame file missing")
|
||||
|
||||
region_phrase = _region_to_phrase(req.region) if (req and req.region) else ""
|
||||
if region_phrase:
|
||||
region_phrases: list[str] = []
|
||||
if req and req.regions:
|
||||
for r in req.regions:
|
||||
p = _region_to_phrase(r)
|
||||
if p:
|
||||
region_phrases.append(p)
|
||||
# 去重保序
|
||||
region_phrases = list(dict.fromkeys(region_phrases))
|
||||
|
||||
if region_phrases:
|
||||
if len(region_phrases) == 1:
|
||||
zones = f"the {region_phrases[0]} part"
|
||||
else:
|
||||
zones = "these parts: " + ", ".join(region_phrases)
|
||||
prompt = (
|
||||
f"Erase the text and graphics in the {region_phrase} part of the image. "
|
||||
f"Erase the text and graphics in {zones} of the image. "
|
||||
"Keep all other parts unchanged."
|
||||
)
|
||||
else:
|
||||
|
||||
@@ -30,9 +30,11 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
const [addingZh, setAddingZh] = useState(false)
|
||||
const [addInput, setAddInput] = useState("")
|
||||
const [mounted, setMounted] = useState(false)
|
||||
// 画框模式 + 选区(相对坐标 0-1)
|
||||
// 画框模式 + 多选区(相对坐标 0-1)
|
||||
type Region = { x: number; y: number; w: number; h: number }
|
||||
const [cropMode, setCropMode] = useState(false)
|
||||
const [region, setRegion] = useState<{ x: number; y: number; w: number; h: number } | null>(null)
|
||||
const [regions, setRegions] = useState<Region[]>([])
|
||||
const [draftRegion, setDraftRegion] = useState<Region | null>(null) // 当前正在拖的
|
||||
const [dragStart, setDragStart] = useState<{ x: number; y: number } | null>(null)
|
||||
const [extractNamePrompt, setExtractNamePrompt] = useState(false) // 提取模式:要用户填名字
|
||||
const [extractName, setExtractName] = useState("")
|
||||
@@ -43,7 +45,8 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
// 切换分镜时清空选区
|
||||
useEffect(() => {
|
||||
setCropMode(false)
|
||||
setRegion(null)
|
||||
setRegions([])
|
||||
setDraftRegion(null)
|
||||
setDragStart(null)
|
||||
setExtractNamePrompt(false)
|
||||
setExtractName("")
|
||||
@@ -90,13 +93,14 @@ export function FrameLightbox({ jobId, frames, activeIndex, selected, onClose, o
|
||||
}
|
||||
}
|
||||
|
||||
const handleCleanup = async (withRegion = false) => {
|
||||
const handleCleanup = async (useRegions = false) => {
|
||||
setCleaning(true)
|
||||
try {
|
||||
const updated = await cleanupFrame(jobId, f.index, withRegion ? region : null)
|
||||
const usable = useRegions ? regions.filter((r) => r.w >= 0.03 && r.h >= 0.03) : null
|
||||
const updated = await cleanupFrame(jobId, f.index, usable && usable.length > 0 ? usable : null)
|
||||
onJobUpdate?.(updated)
|
||||
toast.success(`分镜 ${f.index + 1} 清洗完成 · 下方查看${withRegion ? "(框内)" : ""}`)
|
||||
if (withRegion) { setCropMode(false); setRegion(null) }
|
||||
toast.success(`分镜 ${f.index + 1} 清洗完成${usable && usable.length > 0 ? `(${usable.length} 个区域)` : ""}`)
|
||||
if (useRegions) { setCropMode(false); setRegions([]); setDraftRegion(null) }
|
||||
} catch (e) {
|
||||
toast.error("清洗失败:" + (e instanceof Error ? e.message : String(e)))
|
||||
} finally {
|
||||
|
||||
@@ -212,12 +212,12 @@ export function cutoutUrl(jobId: string, frameIndex: number, elementId: string):
|
||||
export async function cleanupFrame(
|
||||
jobId: string,
|
||||
frameIdx: number,
|
||||
region?: { x: number; y: number; w: number; h: number } | null,
|
||||
regions?: Array<{ x: number; y: number; w: number; h: number }> | null,
|
||||
): Promise<Job> {
|
||||
const res = await fetch(`${API_BASE}/jobs/${jobId}/frames/${frameIdx}/cleanup`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ region: region ?? null }),
|
||||
body: JSON.stringify({ regions: regions ?? null }),
|
||||
})
|
||||
if (!res.ok) {
|
||||
const txt = await res.text().catch(() => "")
|
||||
|
||||
Reference in New Issue
Block a user