ArtifactModelDetailView.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. <script setup lang="ts">
  2. import PageTopTitleBottomContent from '@/components/parts/PageTopTitleBottomContent.vue';
  3. import SimplePageContentLoader from '@/components/SimplePageContentLoader.vue';
  4. import SimpleRichHtml from '@/components/SimpleRichHtml.vue';
  5. import Title from '@/assets/images/Artifact/Title3DDetails.png';
  6. import UnmoveableContent from '@/api/inherit/UnmoveableContent';
  7. import { useSimpleDataLoader } from '@/composeable/SimpleDataLoader';
  8. import { ScrollRect } from '@imengyu/vue-scroll-rect';
  9. import { useRoute, useRouter } from 'vue-router';
  10. import { computed, ref } from 'vue';
  11. import ImageGrid from '@/components/small/ImageGrid.vue';
  12. import Box1 from '@/components/small/Box1.vue';
  13. import ImageLine from '@/components/small/ImageLine.vue';
  14. import ImagePreview from '@/components/small/ImagePreview.vue';
  15. import Viewer from '@/components/3d/Viewer.vue';
  16. import { getArtifactModelDetail } from '@/assets/data/3d';
  17. const route = useRoute();
  18. const router = useRouter();
  19. const newsData = useSimpleDataLoader(async () => {
  20. const data = (await UnmoveableContent.getContentDetail(parseInt(route.query.id as string)));
  21. return {
  22. detail: data,
  23. model: getArtifactModelDetail(data.id)
  24. };
  25. });
  26. const subPartModels = computed(() => {
  27. //return newsData.content.value?.detail.associationMeList.filter((p) => p.modelId === UnmoveableContent.SubPartModelId);
  28. return getArtifactModelDetail(parseInt(route.query.id as string))?.subParts;
  29. });
  30. const previewShow = ref(false);
  31. </script>
  32. <template>
  33. <PageTopTitleBottomContent :title-image="Title" :box="false" :full="true">
  34. <template #belowTitle>
  35. <h2 class="text-bold color-text-second size-base mt-3">文物名称:{{ newsData.content.value?.detail.title }}</h2>
  36. </template>
  37. <template #content>
  38. <SimplePageContentLoader :loader="newsData">
  39. <div class="d-flex flex-row color-text-second size-ss h-90 position-relative">
  40. <!-- 左 文物介绍 -->
  41. <div class="d-flex flex-col w-30 flex-shrink-0">
  42. <Box1 class="h-50">
  43. <ScrollRect scroll="vertical">
  44. <h3 class="text-bold size-base">文物简介</h3>
  45. <SimpleRichHtml :contents="[
  46. newsData.content.value!.detail.intro as string ,
  47. newsData.content.value!.detail.description as string ,
  48. ]" />
  49. </ScrollRect>
  50. </Box1>
  51. <Box1 class="h-50 mt-3">
  52. <ScrollRect scroll="vertical">
  53. <h3 class="text-bold size-base">文物实图</h3>
  54. <ImageGrid class="mt-3" :data="newsData.content.value!.detail.images" :rowCount="3" imageHeight="120px">
  55. <template #item="{ url, item, width, height }">
  56. <img
  57. :src="url"
  58. class="radius-base object-fit-cover bg-forth"
  59. tabindex="0"
  60. :style="{ width, height }"
  61. @click="previewShow=true"
  62. />
  63. </template>
  64. </ImageGrid>
  65. </ScrollRect>
  66. </Box1>
  67. </div>
  68. <!-- 中 3D模型 显示 -->
  69. <div class="d-flex flex-col w-40 flex-shrink-0">
  70. <div v-if="!newsData.content.value?.model?.model" class="h-100 d-flex flex-column justify-center align-center">
  71. 暂无可用3D模型数据
  72. </div>
  73. <Viewer
  74. v-else
  75. ref="modelRef"
  76. class="h-100"
  77. :path="newsData.content.value.model.model"
  78. />
  79. </div>
  80. <!-- 右 信息和构建 -->
  81. <div class="d-flex flex-col w-30 flex-shrink-0">
  82. <Box1 class="h-50">
  83. <h3 class="text-bold size-base">文物信息</h3>
  84. <div class="d-flex flex-col gap-ss size-s">
  85. <div>始建年代:{{ newsData.content.value!.detail.age }}</div>
  86. <div>文物类型:{{ newsData.content.value!.detail.crTypeText }}</div>
  87. <div>文物等级:{{ newsData.content.value!.detail.levelText }}</div>
  88. <div>所在区域:{{ newsData.content.value!.detail.regionText }}</div>
  89. </div>
  90. </Box1>
  91. <Box1 class="h-50 mt-3">
  92. <h3 class="text-bold size-base">构件3D模型</h3>
  93. <ImageLine
  94. :data="subPartModels"
  95. :max-count="3"
  96. imagekey="image"
  97. @more-click="router.push({name: 'ArtifactSubPart', query: route.query })"
  98. >
  99. <template #item="{ url, item, width, height }">
  100. <img
  101. :src="url"
  102. class="radius-base object-fit-cover bg-forth"
  103. :style="{ width, height }"
  104. tabindex="0"
  105. @click="router.push({name: 'ArtifactSubPartModelDetail', query: {
  106. ...route.query,
  107. model: item.model,
  108. } })"
  109. />
  110. </template>
  111. </ImageLine>
  112. </Box1>
  113. </div>
  114. </div>
  115. </SimplePageContentLoader>
  116. </template>
  117. </PageTopTitleBottomContent>
  118. <ImagePreview
  119. :list="newsData.content.value?.detail.images || []"
  120. v-model:show="previewShow"
  121. />
  122. </template>
  123. <style lang="scss" scoped>
  124. .image-box {
  125. background-size: 100% 100%;
  126. background-image: url('@/assets/images/Artifact/ImageBox.png');
  127. padding: 10px;
  128. width: 100%;
  129. img {
  130. width: 100%;
  131. height: 300px;
  132. object-fit: cover;
  133. }
  134. }
  135. </style>