add per-state DICOM zip downloads
This commit is contained in:
@@ -815,6 +815,7 @@ export default function App() {
|
|||||||
].map(t => {
|
].map(t => {
|
||||||
const screenshotDir = deformationJob?.result?.previews?.screenshots;
|
const screenshotDir = deformationJob?.result?.previews?.screenshots;
|
||||||
const imagePath = screenshotDir ? `${screenshotDir}/${t.key}.png` : '';
|
const imagePath = screenshotDir ? `${screenshotDir}/${t.key}.png` : '';
|
||||||
|
const stateZip = deformationJob?.result?.stateZips?.[t.key];
|
||||||
return (
|
return (
|
||||||
<div key={t.key} className="bg-white p-4 rounded-2xl border flex flex-col hover:border-blue-200 transition-colors shadow-sm group min-h-[285px]">
|
<div key={t.key} className="bg-white p-4 rounded-2xl border flex flex-col hover:border-blue-200 transition-colors shadow-sm group min-h-[285px]">
|
||||||
<div className="flex justify-between items-center mb-3">
|
<div className="flex justify-between items-center mb-3">
|
||||||
@@ -831,6 +832,15 @@ export default function App() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
{stateZip?.path && (
|
||||||
|
<a
|
||||||
|
href={fileUrl(stateZip.path)}
|
||||||
|
download={stateZip.name}
|
||||||
|
className="mt-3 py-2.5 bg-slate-100 text-slate-600 rounded-xl text-[11px] font-black hover:bg-green-600 hover:text-white transition-all flex items-center justify-center gap-2"
|
||||||
|
>
|
||||||
|
<Download size={13} /> 下载本状态 DICOM ZIP
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -467,18 +467,27 @@ def make_preview(input_dir, angle_degrees):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def serialize_outputs(output_paths, preview_paths, zip_path=None):
|
def zip_metadata(zip_path):
|
||||||
|
zip_path = Path(zip_path).resolve()
|
||||||
|
return {
|
||||||
|
"path": str(zip_path),
|
||||||
|
"name": zip_path.name,
|
||||||
|
"size": zip_path.stat().st_size,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def serialize_outputs(output_paths, preview_paths, zip_path=None, state_zips=None):
|
||||||
return {
|
return {
|
||||||
"outputs": {key: str(Path(value).resolve()) for key, value in output_paths.items()},
|
"outputs": {key: str(Path(value).resolve()) for key, value in output_paths.items()},
|
||||||
"previews": {
|
"previews": {
|
||||||
"comparison": str(Path(preview_paths["comparison"]).resolve()),
|
"comparison": str(Path(preview_paths["comparison"]).resolve()),
|
||||||
"screenshots": str(Path(preview_paths["screenshots"]).resolve()),
|
"screenshots": str(Path(preview_paths["screenshots"]).resolve()),
|
||||||
},
|
},
|
||||||
"zip": {
|
"zip": zip_metadata(zip_path) if zip_path else None,
|
||||||
"path": str(Path(zip_path).resolve()),
|
"stateZips": {
|
||||||
"name": Path(zip_path).name,
|
key: zip_metadata(value)
|
||||||
"size": Path(zip_path).stat().st_size,
|
for key, value in (state_zips or {}).items()
|
||||||
} if zip_path else None,
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -591,12 +600,24 @@ class Handler(BaseHTTPRequestHandler):
|
|||||||
transition_width,
|
transition_width,
|
||||||
progress,
|
progress,
|
||||||
)
|
)
|
||||||
|
set_job(job_id, message="正在打包各状态 DICOM ZIP...")
|
||||||
|
state_zips = {}
|
||||||
|
for state_key in [
|
||||||
|
"original",
|
||||||
|
"hard_boundary",
|
||||||
|
"gaussian_smooth",
|
||||||
|
"soft_transition",
|
||||||
|
]:
|
||||||
|
state_zips[state_key] = zip_folder(
|
||||||
|
output_paths[state_key],
|
||||||
|
job_root / f"{state_key}_{job_id}.zip",
|
||||||
|
)
|
||||||
set_job(job_id, message="正在打包四状态输出 ZIP...")
|
set_job(job_id, message="正在打包四状态输出 ZIP...")
|
||||||
zip_path = zip_folder(
|
zip_path = zip_folder(
|
||||||
output_dir,
|
output_dir,
|
||||||
job_root / f"head_ct_morph_{job_id}.zip",
|
job_root / f"head_ct_morph_{job_id}.zip",
|
||||||
)
|
)
|
||||||
return serialize_outputs(output_paths, preview_paths, zip_path)
|
return serialize_outputs(output_paths, preview_paths, zip_path, state_zips)
|
||||||
|
|
||||||
self.send_json(start_job("deformation", worker), status=202)
|
self.send_json(start_job("deformation", worker), status=202)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user