From fe80bc77bad8ccbbab8b5b7c90311d204f9ea4a1 Mon Sep 17 00:00:00 2001 From: WuYongJie Date: Fri, 29 May 2026 19:02:41 +0800 Subject: [PATCH] =?UTF-8?q?@=20refactor(asset-center):=20=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E9=A2=84=E8=A7=88=E5=8F=B3=E9=94=AE=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E5=AD=90=E8=8F=9C=E5=8D=95=E4=B8=BA=E7=8B=AC=E7=AB=8B=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - PreviewSubmenus.tsx(252 行):基材选择子菜单 + UV 渲染参数子菜单 - AssetCenterClient.tsx 3268→3085 行 @ --- .../app/asset-center/AssetCenterClient.tsx | 225 ++-------------- .../src/app/asset-center/PreviewSubmenus.tsx | 252 ++++++++++++++++++ 2 files changed, 273 insertions(+), 204 deletions(-) create mode 100644 furniture-3d-system/src/app/asset-center/PreviewSubmenus.tsx diff --git a/furniture-3d-system/src/app/asset-center/AssetCenterClient.tsx b/furniture-3d-system/src/app/asset-center/AssetCenterClient.tsx index 87e040d2..28a91a21 100644 --- a/furniture-3d-system/src/app/asset-center/AssetCenterClient.tsx +++ b/furniture-3d-system/src/app/asset-center/AssetCenterClient.tsx @@ -176,6 +176,7 @@ import { VariantEditModal } from './VariantEditModal' import { FamilyEditModal } from './FamilyEditModal' import { CadImportModal } from './CadImportModal' import { FamilyListPanel } from './FamilyListPanel' +import { SubstrateSubmenu, UvSettingsSubmenu } from './PreviewSubmenus' // ---- 主组件内的渲染辅助函数 ---- @@ -2898,212 +2899,28 @@ export default function AssetCenterClient({ bodyMaxHeight={previewContextMenuBodyMaxHeight} > {activePreviewSubmenu === 'preview-substrate' ? ( -
-
-
-

- 选择基材 -

-
- - setPreviewSubstrateSearch(event.target.value)} - placeholder="搜索名称或编码" - className="h-7 w-full rounded-apple-md border border-apple-separator/80 bg-white/80 pl-7 pr-2 text-[12px] text-[#2d3335] outline-hidden transition placeholder:text-[#5a6062]/45 focus:border-black/[0.12] focus:bg-white" - /> -
-
- -
- {previewFilteredSubstrateItems.length > 0 ? ( - previewFilteredSubstrateItems.map((item) => ( - - )) - ) : ( -
- 没有匹配基材 -
- )} -
-
-
+ ) : null} {activePreviewSubmenu === 'preview-uv' ? ( -
-
-
-
-

- {activeVariantUvNodeLabel} - {!selectedFinishMaterialConfig ? ' · 未绑定基材花色' : ''} -

-

- 渲染参数 -

-
- - {variantUvConfigDirty ? '待保存' : '已同步'} - -
- -
-
- - 投影轴 - -
- {UV_PROJECTION_AXIS_OPTIONS.map((option) => { - const isSelected = variantUvEditorForm.textureProjectionAxis === option.value - return ( - - ) - })} -
-
- {[ - { - label: '整体重复', - ariaLabel: '整体重复', - value: variantUvEditorForm.textureRepeat, - placeholder: '1.0', - field: 'textureRepeat' as const, - }, - { - label: '旋转角度 °', - ariaLabel: '旋转角度 °', - value: variantUvEditorForm.textureRotation, - placeholder: '0°', - field: 'textureRotation' as const, - }, - { - label: '纹理尺寸 mm', - ariaLabel: '纹理尺寸 mm', - value: variantUvEditorForm.textureSizeMm, - placeholder: '600', - field: 'textureSizeMm' as const, - }, - { - label: 'U 压缩', - ariaLabel: 'U 压缩', - value: variantUvEditorForm.textureRepeatU, - placeholder: '1.0', - field: 'textureRepeatU' as const, - }, - { - label: 'V 压缩', - ariaLabel: 'V 压缩', - value: variantUvEditorForm.textureRepeatV, - placeholder: '1.0', - field: 'textureRepeatV' as const, - }, - ].map((item) => ( -
- - - handlePatchVariantUvEditorForm({ [item.field]: event.target.value }) - } - placeholder={item.placeholder} - className="h-6 w-[108px] rounded-apple-sm border border-apple-separator bg-white/80 px-2 text-right text-[12px] text-apple-label-primary outline-hidden transition placeholder:text-apple-label-tertiary focus:border-[#2d3335]" - /> -
- ))} - -
- -
- - -
- -
-
-
+ ) : null} )} diff --git a/furniture-3d-system/src/app/asset-center/PreviewSubmenus.tsx b/furniture-3d-system/src/app/asset-center/PreviewSubmenus.tsx new file mode 100644 index 00000000..4c9076c0 --- /dev/null +++ b/furniture-3d-system/src/app/asset-center/PreviewSubmenus.tsx @@ -0,0 +1,252 @@ +'use client' + +import { Search } from 'lucide-react' +import { Badge } from '@/components/ui/Badge' +import { cn } from '@/lib/utils' +import type { AssetVariantUvProjectionAxis } from '@/lib/asset-variant-render-config' +import type { VariantUvEditorFormState } from './asset-center-types' +import { UV_PROJECTION_AXIS_OPTIONS } from './asset-center-types' + +// ---- 基材选择子菜单 ---- + +interface SubstrateSubmenuItem { + id: string + label: string +} + +interface SubstrateSubmenuMetrics { + left: number + top: number + width: number + maxHeight: number +} + +interface SubstrateSubmenuProps { + metrics: SubstrateSubmenuMetrics + search: string + onSearchChange: (value: string) => void + filteredItems: SubstrateSubmenuItem[] + onSelect: (item: SubstrateSubmenuItem) => void +} + +export function SubstrateSubmenu({ + metrics, + search, + onSearchChange, + filteredItems, + onSelect, +}: SubstrateSubmenuProps) { + return ( +
+
+
+

+ 选择基材 +

+
+ + onSearchChange(event.target.value)} + placeholder="搜索名称或编码" + className="h-7 w-full rounded-apple-md border border-apple-separator/80 bg-white/80 pl-7 pr-2 text-[12px] text-[#2d3335] outline-hidden transition placeholder:text-[#5a6062]/45 focus:border-black/[0.12] focus:bg-white" + /> +
+
+ +
+ {filteredItems.length > 0 ? ( + filteredItems.map((item) => ( + + )) + ) : ( +
+ 没有匹配基材 +
+ )} +
+
+
+ ) +} + +// ---- UV 渲染参数子菜单 ---- + +interface UvSettingsPanelPosition { + left: number + top: number + maxHeight: number +} + +interface UvSubmenuProps { + position: UvSettingsPanelPosition + form: VariantUvEditorFormState + onFormPatch: (patch: Partial) => void + onSelectProjectionAxis: (value: '' | AssetVariantUvProjectionAxis) => void + onReset: () => void + onClear: () => void + onKeepDraft: () => void + configDirty: boolean + submitting: boolean + nodeLabel: string + hasMaterialConfig: boolean +} + +export function UvSettingsSubmenu({ + position, + form, + onFormPatch, + onSelectProjectionAxis, + onReset, + onClear, + onKeepDraft, + configDirty, + submitting, + nodeLabel, + hasMaterialConfig, +}: UvSubmenuProps) { + return ( +
+
+
+
+

+ {nodeLabel} + {!hasMaterialConfig ? ' · 未绑定基材花色' : ''} +

+

+ 渲染参数 +

+
+ + {configDirty ? '待保存' : '已同步'} + +
+ +
+
+ + 投影轴 + +
+ {UV_PROJECTION_AXIS_OPTIONS.map((option) => { + const isSelected = form.textureProjectionAxis === option.value + return ( + + ) + })} +
+
+ {[ + { label: '整体重复', ariaLabel: '整体重复', value: form.textureRepeat, placeholder: '1.0', field: 'textureRepeat' as const }, + { label: '旋转角度 °', ariaLabel: '旋转角度 °', value: form.textureRotation, placeholder: '0°', field: 'textureRotation' as const }, + { label: '纹理尺寸 mm', ariaLabel: '纹理尺寸 mm', value: form.textureSizeMm, placeholder: '600', field: 'textureSizeMm' as const }, + { label: 'U 压缩', ariaLabel: 'U 压缩', value: form.textureRepeatU, placeholder: '1.0', field: 'textureRepeatU' as const }, + { label: 'V 压缩', ariaLabel: 'V 压缩', value: form.textureRepeatV, placeholder: '1.0', field: 'textureRepeatV' as const }, + ].map((item) => ( +
+ + onFormPatch({ [item.field]: event.target.value })} + placeholder={item.placeholder} + className="h-6 w-[108px] rounded-apple-sm border border-apple-separator bg-white/80 px-2 text-right text-[12px] text-apple-label-primary outline-hidden transition placeholder:text-apple-label-tertiary focus:border-[#2d3335]" + /> +
+ ))} + +
+ +
+ + +
+ +
+
+
+ ) +}