feat: 升级算法包 delivery_v1.1 → v1.2,新增任务级 CAD 与测距面板

- 算法包替换为 delivery_v1.2(coupler_panel 新增 autotune/layer_select,underframe_deflection 新增 single_beam 管线),删除 delivery_v1.1
- manifests/adapters 的 PYTHONPATH 与版本说明同步更新到 v1.2
- 新增任务级 CAD 文件支持(task_cad_files 表、上传/读取路由、TaskManager 全选与加载显示)
- 新增 train-measurement 自定义前端面板(YAML 编辑器 + 可视化 ROI 配置 + 3D 取点)
- PointCloudViewer 支持 PLY 叠加层渲染与 ROI 拾取
- Dockerfile 改用 Miniforge 安装 pythonocc-core,修复 libgomp/libstdc++ 依赖
This commit is contained in:
2026-06-11 02:30:04 +00:00
parent 16811100d1
commit cec0766e67
143 changed files with 3087 additions and 12604 deletions

View File

@@ -172,6 +172,17 @@ export default function TaskManager({
onLoadPointClouds(activeTaskId, ids);
}
const allCadSelected = taskCadFiles.length > 0 && taskCadFiles.every((f) => selectedCadFileIds.has(f.id));
const someCadSelected = taskCadFiles.some((f) => selectedCadFileIds.has(f.id));
function toggleAllCadFiles() {
if (allCadSelected) {
setSelectedCadFileIds(new Set());
} else {
setSelectedCadFileIds(new Set(taskCadFiles.map((f) => f.id)));
}
}
function toggleCadFile(id: number) {
setSelectedCadFileIds((prev) => {
const next = new Set(prev);
@@ -467,12 +478,26 @@ export default function TaskManager({
({taskCadFiles.length})
</span>
</span>
<button
className="industrial-btn py-0.5 text-[10px] flex items-center gap-0.5"
onClick={() => cadFileRef.current?.click()}
>
<Upload className="w-3 h-3" /> 上传
</button>
<div className="flex items-center gap-1">
{taskCadFiles.length > 0 && (
<button
className="industrial-btn py-0.5 text-[10px] flex items-center gap-0.5"
onClick={toggleAllCadFiles}
title={allCadSelected ? '取消全选' : '全选'}
>
{allCadSelected
? <CheckSquare className="w-3 h-3" />
: <Square className="w-3 h-3" />}
全选
</button>
)}
<button
className="industrial-btn py-0.5 text-[10px] flex items-center gap-0.5"
onClick={() => cadFileRef.current?.click()}
>
<Upload className="w-3 h-3" /> 上传
</button>
</div>
</div>
{uploadingCadFor === activeTaskId && (
@@ -549,9 +574,26 @@ export default function TaskManager({
</div>
{selectedCadFileIds.size > 0 && (
<p className="text-[9px] text-primary/80 mt-1">
已选 {selectedCadFileIds.size} 个 CAD · 将作为算法输入
</p>
<div className="space-y-1 mt-1">
<p className="text-[9px] text-primary/80">
已选 {selectedCadFileIds.size} 个 CAD · 将作为算法输入
</p>
{selectedCadFileIds.size === 1 && onSelectTaskCad && (() => {
const f = taskCadFiles.find(f => selectedCadFileIds.has(f.id));
return f ? (
<button
className="industrial-btn w-full py-0.5 text-[10px] flex items-center justify-center gap-1"
onClick={() => onSelectTaskCad(
`/api/files/read/task-cad/${activeTaskId}/${encodeURIComponent(f.name)}`,
f.format,
f.name,
)}
>
<Eye className="w-3 h-3" /> 在 3D 中显示
</button>
) : null;
})()}
</div>
)}
</div>
)}

View File

@@ -3,7 +3,6 @@ import { useAuth } from '@/_core/hooks/useAuth';
import { getLoginUrl } from '@/const';
import PointCloudViewer from '@/components/PointCloudViewer';
import VehicleTree, { TreeSelection } from '@/components/VehicleTree';
import ModelManager from '@/components/ModelManager';
import TaskManager from '@/components/TaskManager';
import AnalysisPanel from '@/components/AnalysisPanel';
import AlgorithmRunPanel from '@/components/AlgorithmRunPanel';
@@ -310,14 +309,6 @@ export default function Home() {
<>
<VehicleTree selection={selection} onSelect={setSelection} />
<div className="h-px bg-border my-1" />
<ModelManager
modelId={selection.modelId}
onSelectCad={handleSelectCad}
activeCadName={activeCadName}
cadLoading={cadLoading}
cadLoadProgress={cadLoadProgress}
/>
<div className="h-px bg-border my-1" />
<TaskManager
modelId={selection.modelId}
activeTaskId={selection.taskId}