From 33f1c72791e971320d93a5166342f67f6286377c Mon Sep 17 00:00:00 2001 From: yuding <1023798085@qq.com> Date: Wed, 28 Jan 2026 11:58:16 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=9E=84=E4=BB=B6?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E5=BC=B9=E7=AA=97=E7=AE=A1=E7=90=86=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/managers/component-detail-manager.ts | 119 +++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/managers/component-detail-manager.ts diff --git a/src/managers/component-detail-manager.ts b/src/managers/component-detail-manager.ts new file mode 100644 index 0000000..87e6f10 --- /dev/null +++ b/src/managers/component-detail-manager.ts @@ -0,0 +1,119 @@ +import { BaseManager } from '../core/base-manager'; +import { BimCollapse } from '../components/collapse/index'; +import { BimDescription } from '../components/description/index'; + +export class ComponentDetailManager extends BaseManager { + private dialogId = 'component-detail-dialog'; + private dialog: any = null; + + constructor() { + super(); + } + + public show(modelUrl: string, componentId: string): void { + if (!this.registry.dialog) { + console.warn('[ComponentDetailManager] Dialog manager not initialized'); + return; + } + + if (this.isOpen()) { + this.hide(); + } + + this.createDialog(); + this.showLoading(); + + this.registry.engine3d?.getComponentProperties(modelUrl, componentId, (data) => { + this.renderProperties(data, componentId); + }); + } + + private createDialog(): void { + const width = 400; + const x = document.body.clientWidth - width - 40; + + this.dialog = this.registry.dialog?.create({ + id: this.dialogId, + title: 'panel.componentDetail.title', + content: '', + width: `${width}px`, + height: '500px', + position: { x, y: 20 }, + resizable: true, + onClose: () => this.hide() + } as any); + } + + private showLoading(): void { + const container = document.createElement('div'); + container.style.padding = '20px'; + container.style.textAlign = 'center'; + container.textContent = '加载中...'; + this.dialog?.setContent(container); + } + + private renderProperties(data: any, _componentId: string): void { + if (!this.dialog) return; + + const container = document.createElement('div'); + container.style.height = '100%'; + container.style.overflowY = 'auto'; + + const properties = data?.properties || []; + + if (properties.length === 0) { + container.innerHTML = '
无属性数据
'; + this.dialog.setContent(container); + return; + } + + const collapseItems = properties.map((category: any, index: number) => ({ + id: `category-${index}`, + title: category.name || `分类 ${index + 1}`, + content: this.createCategoryContent(category.children || []) + })); + + new BimCollapse({ + container, + accordion: false, + activeIds: collapseItems.length > 0 ? [collapseItems[0].id] : [], + items: collapseItems + }); + + this.dialog.setContent(container); + } + + private createCategoryContent(items: any[]): HTMLElement { + const container = document.createElement('div'); + + const descItems = items.map((item: any) => ({ + label: item.name || '-', + value: String(item.value ?? '-') + })); + + new BimDescription({ + container, + labelWidth: '120px', + bordered: true, + items: descItems + }); + + return container; + } + + public isOpen(): boolean { + return this.dialog !== null; + } + + public hide(): void { + if (this.dialog) { + this.dialog.destroy(); + this.dialog = null; + } + } + + public destroy(): void { + this.hide(); + super.destroy(); + } +}