feat: v2.8 3D 预览放大模式+类型修正

- 组合页 3D 预览卡片: 放大按钮切换近全屏浮层(inset 2.5vh/2.5vw)
- 默认高度 300→380, 切换后派发 resize 让 3D 自适应
- drawing.ts 滑扇附着 reduce 种子类型修正(移除未定义 BBox 引用)
- vue-tsc 零错误, 构建通过
This commit is contained in:
HHY
2026-09-23 02:48:21 -07:00
parent 96159d4f35
commit d6e70fc571
3 changed files with 20 additions and 3 deletions
+1
View File
@@ -1,5 +1,6 @@
# CHANGELOG # CHANGELOG
- [2026-09-23 00:20] FEAT: v2.8 3D 预览放大模式——组合页 3D 预览卡片加放大按钮(近全屏浮层 inset 2.5vh/2.5vw + z-index 2001), 默认高度 300→380, 切换后派发 resize 让 3D 自适应; drawing.ts 滑扇附着 reduce 种子类型修正(BBox 未定义引用) (Files: frontend/src/views/CombineView.vue, frontend/src/types/drawing.ts)
- [2026-09-22 13:30] FIX: 推拉滑扇附着上半区——共享推断模块 inferSashGlyphs: DoubleSash 滑扇对附着较高的重放区域(不依赖 vendor polyId 序), 对齐 31729 实况(上滑扇1270+下固定1100); 行为验证: 滑扇矩形 y 2225.8-3370.8 ✓; 同步 verify 脚本 console 过滤放宽 (Files: frontend/src/types/drawing.ts, frontend/scripts/vei-check.mjs, frontend/scripts/verify-v3.mjs) - [2026-09-22 13:30] FIX: 推拉滑扇附着上半区——共享推断模块 inferSashGlyphs: DoubleSash 滑扇对附着较高的重放区域(不依赖 vendor polyId 序), 对齐 31729 实况(上滑扇1270+下固定1100); 行为验证: 滑扇矩形 y 2225.8-3370.8 ✓; 同步 verify 脚本 console 过滤放宽 (Files: frontend/src/types/drawing.ts, frontend/scripts/vei-check.mjs, frontend/scripts/verify-v3.mjs)
- [2026-09-22 00:55] FIX: v2.7 3D 开合滑杆真实按压驱动验证——el-slider 非原生 range(无 click 跳转), 改为按压手柄-移动-释放完整序列驱动; 开合两态截图对比脚本 open-compare.mjs; 滑杆 v-model 正常回写 (Files: frontend/scripts/open-compare.mjs) - [2026-09-22 00:55] FIX: v2.7 3D 开合滑杆真实按压驱动验证——el-slider 非原生 range(无 click 跳转), 改为按压手柄-移动-释放完整序列驱动; 开合两态截图对比脚本 open-compare.mjs; 滑杆 v-model 正常回写 (Files: frontend/scripts/open-compare.mjs)
- [2026-09-22 00:30] FIX: v2.6 组合画布选中根因修复+右键菜单+3D 三场景。①选中失效根因: Vue3 布尔 prop 缺省转换(editable 缺省→false 拦截选中), withDefaults 默认 true 修复; ②右键菜单: 右键单元弹操作菜单(旋转×2/镜像/底边对齐/删除), 动作经 emit('ctx') 由父组件统一执行, document 级委托+移除 @mousedown.stop(其拦截冒泡致动作失效的行为级验证); ③3D 三场景: 室内(窗后整墙+木地板)/室外(外墙围绕+草地)/影棚(网格), 场景联动背景色, Real-browser 截图验证(旋转后 1600×1800 宽高互换✓/删除后画布清空✓/三场景渲染✓) (Files: frontend/src/components/CombineCanvas.vue, frontend/src/components/WindoorThreed.vue, frontend/src/views/CombineView.vue, frontend/scripts/verify-menu.mjs) - [2026-09-22 00:30] FIX: v2.6 组合画布选中根因修复+右键菜单+3D 三场景。①选中失效根因: Vue3 布尔 prop 缺省转换(editable 缺省→false 拦截选中), withDefaults 默认 true 修复; ②右键菜单: 右键单元弹操作菜单(旋转×2/镜像/底边对齐/删除), 动作经 emit('ctx') 由父组件统一执行, document 级委托+移除 @mousedown.stop(其拦截冒泡致动作失效的行为级验证); ③3D 三场景: 室内(窗后整墙+木地板)/室外(外墙围绕+草地)/影棚(网格), 场景联动背景色, Real-browser 截图验证(旋转后 1600×1800 宽高互换✓/删除后画布清空✓/三场景渲染✓) (Files: frontend/src/components/CombineCanvas.vue, frontend/src/components/WindoorThreed.vue, frontend/src/views/CombineView.vue, frontend/scripts/verify-menu.mjs)
+1 -1
View File
@@ -273,7 +273,7 @@ export function inferSashGlyphs(shape: FrameShape, replayed?: Segment[][]): {
// 推拉双扇: 附着较高的区域(推拉窗滑扇在上半部, 对齐 31729 实况) // 推拉双扇: 附着较高的区域(推拉窗滑扇在上半部, 对齐 31729 实况)
const kind = sub.type === 'DoubleSash' ? 'sliding' : 'casement' const kind = sub.type === 'DoubleSash' ? 'sliding' : 'casement'
if (kind === 'sliding') { if (kind === 'sliding') {
rb = regionBBs.reduce((p, c) => (!p || (c.y0 + c.y1) / 2 > (p.y0 + p.y1) / 2 ? c : p), null as BBox | null) rb = regionBBs.reduce((p, c) => (!p || (c.y0 + c.y1) / 2 > (p.y0 + p.y1) / 2 ? c : p), regionBBs[0] ?? null)
} }
if (rb) { if (rb) {
if (entries.length === 2) { if (entries.length === 2) {
+18 -2
View File
@@ -78,7 +78,15 @@
</div> </div>
</transition-group> </transition-group>
</el-card> </el-card>
<el-card header="3D 预览" style="margin-top:16px"> <el-card header="3D 预览" style="margin-top:16px" :class="{ 'preview-large': previewLarge }">
<template #header>
<div class="head-row">
<span>3D 预览</span>
<el-button size="small" text type="primary" @click="togglePreviewLarge">
<el-icon><FullScreen /></el-icon>{{ previewLarge ? '还原' : '放大' }}
</el-button>
</div>
</template>
<div class="threed-box"> <div class="threed-box">
<WindoorThreed v-if="shapes.length" :drawing-data="combinedJson" /> <WindoorThreed v-if="shapes.length" :drawing-data="combinedJson" />
<el-empty v-else description="—" :image-size="50" /> <el-empty v-else description="—" :image-size="50" />
@@ -111,6 +119,12 @@ const selectedUid = ref<number | null>(null)
const saveName = ref('') const saveName = ref('')
const saving = ref(false) const saving = ref(false)
const equalHeight = ref(true) const equalHeight = ref(true)
const previewLarge = ref(false)
function togglePreviewLarge() {
previewLarge.value = !previewLarge.value
setTimeout(() => window.dispatchEvent(new Event('resize')), 60)
}
const canvasRef = ref() const canvasRef = ref()
let uidSeq = 1 let uidSeq = 1
const rev = ref(0) const rev = ref(0)
@@ -343,7 +357,9 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onKeydown))
.unit-info { flex: 1; min-width: 0; } .unit-info { flex: 1; min-width: 0; }
.unit-name { font-size: 13px; color: #303133; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .unit-name { font-size: 13px; color: #303133; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.unit-size { font-size: 11px; color: #909399; } .unit-size { font-size: 11px; color: #909399; }
.threed-box { height: 300px; } .threed-box { height: 380px; }
.preview-large { position: fixed; inset: 2.5vh 2.5vw; z-index: 2001; margin: 0 !important; }
.preview-large .threed-box { height: calc(100% - 40px); }
.list-enter-active, .list-leave-active { transition: all .2s; } .list-enter-active, .list-leave-active { transition: all .2s; }
.list-enter-from, .list-leave-to { opacity: 0; transform: translateX(12px); } .list-enter-from, .list-leave-to { opacity: 0; transform: translateX(12px); }
</style> </style>