auto-save 2026-05-13 18:24 (~3)
This commit is contained in:
@@ -2076,6 +2076,19 @@
|
||||
"message": "auto-save 2026-05-13 18:13 (~1)",
|
||||
"hash": "40cf8b0",
|
||||
"files_changed": 1
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-13T18:18:55+08:00",
|
||||
"type": "commit",
|
||||
"message": "auto-save 2026-05-13 18:18 (~5)",
|
||||
"hash": "2226198",
|
||||
"files_changed": 5
|
||||
},
|
||||
{
|
||||
"ts": "2026-05-13T10:19:28Z",
|
||||
"type": "session-heartbeat",
|
||||
"message": "Codex 会话活跃 · 最近命令:codex · 1 项未提交变更 · 最近提交:auto-save 2026-05-13 18:18 (~5)",
|
||||
"files_changed": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
37
api/main.py
37
api/main.py
@@ -1209,6 +1209,12 @@ class AddElementReq(BaseModel):
|
||||
region: dict | None = None
|
||||
|
||||
|
||||
class UpdateElementReq(BaseModel):
|
||||
name_zh: str | None = None
|
||||
name_en: str | None = None
|
||||
position: str | None = None
|
||||
|
||||
|
||||
@app.post("/jobs/{job_id}/frames/{idx}/elements", response_model=Job)
|
||||
def add_element(job_id: str, idx: int, req: AddElementReq) -> Job:
|
||||
"""加一条元素 · 若 name_en 缺则自动 zh→en 翻译"""
|
||||
@@ -1265,6 +1271,37 @@ def add_element(job_id: str, idx: int, req: AddElementReq) -> Job:
|
||||
return job
|
||||
|
||||
|
||||
@app.patch("/jobs/{job_id}/frames/{idx}/elements/{element_id}", response_model=Job)
|
||||
def update_element(job_id: str, idx: int, element_id: str, req: UpdateElementReq) -> Job:
|
||||
"""更新元素标签 / 英文提示。提取不准时允许用户修正,不强制重建元素。"""
|
||||
job = JOBS.get(job_id)
|
||||
if not job:
|
||||
raise HTTPException(404, "job not found")
|
||||
changed_name = ""
|
||||
found = False
|
||||
new_frames = []
|
||||
for f in job.frames:
|
||||
if f.index == idx:
|
||||
for e in f.elements:
|
||||
if e.id == element_id:
|
||||
found = True
|
||||
if req.name_zh is not None:
|
||||
name_zh = req.name_zh.strip()
|
||||
if not name_zh:
|
||||
raise HTTPException(400, "name_zh required")
|
||||
e.name_zh = name_zh
|
||||
changed_name = name_zh
|
||||
if req.name_en is not None:
|
||||
e.name_en = req.name_en.strip()
|
||||
if req.position is not None:
|
||||
e.position = req.position.strip()
|
||||
new_frames.append(f)
|
||||
if not found:
|
||||
raise HTTPException(404, "element not found")
|
||||
update(job, frames=new_frames, message=f"更新元素 · 分镜 {idx + 1} · {changed_name or element_id}")
|
||||
return job
|
||||
|
||||
|
||||
@app.delete("/jobs/{job_id}/frames/{idx}/elements/{element_id}", response_model=Job)
|
||||
def delete_element(job_id: str, idx: int, element_id: str) -> Job:
|
||||
job = JOBS.get(job_id)
|
||||
|
||||
@@ -407,6 +407,24 @@ export async function deleteElement(jobId: string, frameIdx: number, elementId:
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function updateElement(
|
||||
jobId: string,
|
||||
frameIdx: number,
|
||||
elementId: string,
|
||||
body: { name_zh?: string; name_en?: string; position?: string },
|
||||
): Promise<Job> {
|
||||
const res = await fetch(`${API_BASE}/jobs/${jobId}/frames/${frameIdx}/elements/${elementId}`, {
|
||||
method: "PATCH",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(body),
|
||||
})
|
||||
if (!res.ok) {
|
||||
const txt = await res.text().catch(() => "")
|
||||
throw new Error(`updateElement ${res.status} ${txt.slice(0, 300)}`)
|
||||
}
|
||||
return res.json()
|
||||
}
|
||||
|
||||
export async function deleteFrame(jobId: string, frameIdx: number): Promise<Job> {
|
||||
const res = await fetch(`${API_BASE}/jobs/${jobId}/frames/${frameIdx}`, { method: "DELETE" })
|
||||
if (!res.ok) {
|
||||
|
||||
Reference in New Issue
Block a user