fix(home): 修复模型预览UI没对齐的bug

This commit is contained in:
ErSan 2026-03-23 17:30:58 +08:00
parent ada597137f
commit ad2dd979eb

View File

@ -1,138 +1,152 @@
<template> <template>
<n-modal :show="visible" @update:show="emits('update:visible',$event)" display-directive="show" <n-modal
class="w-66vw h-66vh min-w-1000px" @close="emits('update:visible',false)"> :show="visible"
<n-card :title="asset.name" embedded size="small" content-class="!p-0 flex gap-x-15px" closable @update:show="emits('update:visible', $event)"
@close="handleClose"> display-directive="show"
<div ref="assetPreviewRef" id="assetPreview"></div> class="w-66vw h-66vh min-w-1000px"
@close="emits('update:visible', false)"
>
<n-card
:title="asset.name"
embedded
size="small"
content-class="!p-0 flex gap-x-15px"
content-style="height: calc(100% - 48px);"
closable
@close="handleClose"
>
<div ref="assetPreviewRef" id="assetPreview"></div>
<div class="w-345px mr-15px h-full"> <div class="w-345px mr-15px h-full">
<n-descriptions label-placement="left" label-class="w-100px" bordered :column="1"> <n-descriptions label-placement="left" label-class="w-100px" bordered :column="1">
<n-descriptions-item :label="t('home.assets.Name')"> <n-descriptions-item :label="t('home.assets.Name')">
{{ asset.name }} {{ asset.name }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item :label="t('home.assets.Type')"> <n-descriptions-item :label="t('home.assets.Type')">
{{ t(`home.assets.${asset.type}`) }} {{ t(`home.assets.${asset.type}`) }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item :label="t('home.assets.Category')"> <n-descriptions-item :label="t('home.assets.Category')">
{{ asset.categoryName || asset.category }} {{ asset.categoryName || asset.category }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item :label="t('bim.Thumbnail')"> <n-descriptions-item :label="t('bim.Thumbnail')">
<n-image <n-image width="120" :src="getServiceStaticFile(asset.thumbnail)" />
width="120" {{}}
:src="getServiceStaticFile(asset.thumbnail)" </n-descriptions-item>
/> <n-descriptions-item :label="t('home.assets.Size')">
{{ }} {{ filterSize(asset.size) }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item :label="t('home.assets.Size')"> <n-descriptions-item :label="t('home.assets.Tags')">
{{ filterSize(asset.size) }} <n-tag type="success" :bordered="false" class="ml-5px" v-for="tag in asset.tags ? asset.tags.split(',') : []" :key="tag">
</n-descriptions-item> {{ tag }}
<n-descriptions-item :label="t('home.assets.Tags')"> </n-tag>
<n-tag type="success" :bordered="false" class="ml-5px" </n-descriptions-item>
v-for="tag in (asset.tags ? asset.tags.split(',') : [])" :key="tag"> <n-descriptions-item :label="t('scene.Create time')">
{{ tag }} {{ asset.createTime }}
</n-tag> </n-descriptions-item>
</n-descriptions-item> <n-descriptions-item :label="t('scene.Update time')">
<n-descriptions-item :label="t('scene.Create time')"> {{ asset.updateTime }}
{{ asset.createTime }} </n-descriptions-item>
</n-descriptions-item> </n-descriptions>
<n-descriptions-item :label="t('scene.Update time')">
{{ asset.updateTime }}
</n-descriptions-item>
</n-descriptions>
<n-button type="primary" class="w-full" :loading="downloadLoading" @click="handleDownload"> <n-button type="primary" class="w-full" :loading="downloadLoading" @click="handleDownload">
{{ t('plugin.gltfHandler.Download') }} {{ t("plugin.gltfHandler.Download") }}
</n-button> </n-button>
</div> </div>
</n-card> </n-card>
</n-modal> </n-modal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {ref, nextTick, watch, useTemplateRef, onBeforeUnmount} from "vue"; import { ref, nextTick, watch, useTemplateRef, onBeforeUnmount } from "vue";
import {Preview} from "@astral3d/engine"; import { Preview } from "@astral3d/engine";
import {t} from "@/language"; import { t } from "@/language";
import {downloadWithFetch, filterSize, getServiceStaticFile} from "@/utils/common/file"; import { downloadWithFetch, filterSize, getServiceStaticFile } from "@/utils/common/file";
const props = withDefaults(defineProps<{ const props = withDefaults(
visible: boolean, defineProps<{
asset: IAssets.Item visible: boolean;
}>(), { asset: IAssets.Item;
visible: false, }>(),
asset: () => ({ {
name: "", visible: false,
type: 'Model', asset: () => ({
category: "", name: "",
thumbnail: "", type: "Model",
size: 0, category: "",
file: '', thumbnail: "",
createTime: "", size: 0,
updateTime: "" file: "",
}) createTime: "",
}) updateTime: "",
const emits = defineEmits(['update:visible']) }),
}
);
const emits = defineEmits(["update:visible"]);
let previewer:Preview | null = null; let previewer: Preview | null = null;
const assetPreviewRef = useTemplateRef("assetPreviewRef"); const assetPreviewRef = useTemplateRef("assetPreviewRef");
watch(() => props.visible, async (newVal) => { watch(
if (newVal) { () => props.visible,
if(!previewer){ async newVal => {
await nextTick(); if (newVal) {
if (!previewer) {
await nextTick();
previewer = new Preview({ previewer = new Preview({
container: assetPreviewRef.value, container: assetPreviewRef.value,
hdr: "/static/resource/hdr/cloudy.hdr", hdr: "/static/resource/hdr/cloudy.hdr",
request: { request: {
baseUrl:"/file/static/" baseUrl: "/file/static/",
} },
}); });
} }
if(props.asset.file){ if (props.asset.file) {
previewer.load(getServiceStaticFile(props.asset.file),props.asset.type); previewer.load(getServiceStaticFile(props.asset.file), props.asset.type);
} }
} else { } else {
disposePreviewer(); disposePreviewer();
} }
}) }
);
onBeforeUnmount(() => { onBeforeUnmount(() => {
disposePreviewer(); disposePreviewer();
}) });
function disposePreviewer() { function disposePreviewer() {
if(previewer){ if (previewer) {
previewer.dispose(); previewer.dispose();
previewer = null; previewer = null;
} }
} }
function handleClose() { function handleClose() {
emits('update:visible', false); emits("update:visible", false);
} }
const downloadLoading = ref(false); const downloadLoading = ref(false);
function handleDownload() { function handleDownload() {
downloadLoading.value = true; downloadLoading.value = true;
downloadWithFetch(getServiceStaticFile(props.asset.file)).finally(() => { downloadWithFetch(getServiceStaticFile(props.asset.file)).finally(() => {
downloadLoading.value = false; downloadLoading.value = false;
}) });
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
#assetPreview { #assetPreview {
width: calc(100% - 360px); width: calc(100% - 360px);
height: 100%; height: 100%;
} }
.n-descriptions { .n-descriptions {
height: calc(100% - 65px); height: calc(100% - 65px);
margin-bottom: 15px; margin-bottom: 15px;
overflow-y: auto; overflow-y: auto;
} }
</style> </style>