|
|
@@ -53,9 +53,10 @@
|
|
|
v-show="!showModel && currentDisplayArtifact.imgFiles && currentDisplayArtifact.imgFiles.length > 0"
|
|
|
ref="imageCarouselRef"
|
|
|
height="512px"
|
|
|
+ trigger="click"
|
|
|
:autoplay="true"
|
|
|
:interval="5000"
|
|
|
- arrow="always"
|
|
|
+ :arrow="imageList.length > 1 ? 'always' : 'never'"
|
|
|
indicator-position="outside"
|
|
|
@change="handleImageCarouselChange"
|
|
|
>
|
|
|
@@ -65,7 +66,7 @@
|
|
|
>
|
|
|
<div class="image-item">
|
|
|
<el-image
|
|
|
- :src="image.src"
|
|
|
+ :src="getImageUrl(image)"
|
|
|
:alt="image.alt"
|
|
|
fit="contain"
|
|
|
loading="lazy"
|
|
|
@@ -253,6 +254,7 @@ import { useRoute } from 'vue-router';
|
|
|
import { Close } from '@element-plus/icons-vue';
|
|
|
import iconVoiceOff from '@/assets/img/icon_voiceoff.png';
|
|
|
import iconVoiceOn from '@/assets/img/icon_voiceon.png';
|
|
|
+import { addWatermarkToCollectionImage } from "@/utils/index.js";
|
|
|
const route = useRoute();
|
|
|
const imguRL = import.meta.env.VITE_COS_BASE_URL
|
|
|
const modelUrl = import.meta.env.VITE_MODEL_URL
|
|
|
@@ -325,20 +327,27 @@ const imageCount = computed(() => {
|
|
|
// 图片URL列表(用于预览器)
|
|
|
const imageUrlList = computed(() => {
|
|
|
const imgFiles = currentDisplayArtifact.value?.imgFiles || [];
|
|
|
- return imgFiles.map(imgFile => `${imguRL}${imgFile}`);
|
|
|
+ return imgFiles.map((imgFile, index) => {
|
|
|
+ // 使用与imageList相同的ID生成方式,确保水印缓存一致性
|
|
|
+ const imageItem = imageList.value[index];
|
|
|
+ if (imageItem) {
|
|
|
+ // 获取带水印的图片URL,如果已处理过则返回水印图片,否则返回原图
|
|
|
+ const watermarkedUrl = getImageUrl(imageItem);
|
|
|
+ return watermarkedUrl;
|
|
|
+ }
|
|
|
+ // 如果imageList还没有生成,使用临时对象(保持ID一致性)
|
|
|
+ const item = {
|
|
|
+ id: `${currentDisplayArtifact.value.id}_image_${index}`, // 使用与imageList相同的ID生成逻辑
|
|
|
+ originalImage: `${imguRL}${imgFile}`,
|
|
|
+ src: `${imguRL}${imgFile}`
|
|
|
+ };
|
|
|
+ const watermarkedUrl = getImageUrl(item);
|
|
|
+ return watermarkedUrl;
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
const toggleDisplayMode = (isModel) => {
|
|
|
showModel.value = isModel;
|
|
|
- // if(isModel){
|
|
|
- // currentCarouselIndex.value = modelCount.value > 0 ? 1 : 0;
|
|
|
- // // 重置图片索引为1
|
|
|
- // currentImageIndex.value = imageCount.value > 0 ? 1 : 0;
|
|
|
- // }else{
|
|
|
- // currentImageIndex.value = imageCount.value > 0 ? 1 : 0;
|
|
|
- // // 重置模型索引为1
|
|
|
- // currentCarouselIndex.value = modelCount.value > 0 ? 1 : 0;
|
|
|
- // }
|
|
|
};
|
|
|
|
|
|
// 模型列表数据
|
|
|
@@ -353,15 +362,61 @@ const modelList = computed(() => {
|
|
|
alt: `${currentDisplayArtifact.value.name} 3D模型${index + 1}`
|
|
|
}));
|
|
|
});
|
|
|
-console.log('modelList', modelList.value)
|
|
|
+
|
|
|
+// 处理图片水印
|
|
|
+const watermarkedImages = ref(new Map()); // 存储处理后的水印图片
|
|
|
+const processImageWithWatermark = async (item) => {
|
|
|
+ // 如果已经处理过,直接返回
|
|
|
+ if (watermarkedImages.value.has(item.id)) {
|
|
|
+ // console.log('图片已处理过,直接返回缓存结果');
|
|
|
+ return watermarkedImages.value.get(item.id);
|
|
|
+ }
|
|
|
+ // 如果正在处理,避免重复处理
|
|
|
+ if (item.watermarkProcessing) {
|
|
|
+ return item.originalImage;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ // 标记为处理中
|
|
|
+ item.watermarkProcessing = true;
|
|
|
+ // 处理水印
|
|
|
+ const watermarkedImageUrl = await addWatermarkToCollectionImage(item.originalImage, {
|
|
|
+ position: 'center',
|
|
|
+ opacity: 1,
|
|
|
+ scale: 0.7,
|
|
|
+ margin: 15
|
|
|
+ });
|
|
|
+ // 存储处理后的图片
|
|
|
+ watermarkedImages.value.set(item.id, watermarkedImageUrl);
|
|
|
+ // 更新图片地址
|
|
|
+ item.src = watermarkedImageUrl;
|
|
|
+ return watermarkedImageUrl;
|
|
|
+ } catch (error) {
|
|
|
+ console.error('水印处理失败:', error);
|
|
|
+ // 失败时使用原图
|
|
|
+ return item.originalImage;
|
|
|
+ } finally {
|
|
|
+ // 标记处理完成
|
|
|
+ item.watermarkProcessing = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+// 获取图片地址(带水印处理)
|
|
|
+const getImageUrl = (item) => {
|
|
|
+ if (watermarkedImages.value.has(item.id)) {
|
|
|
+ return watermarkedImages.value.get(item.id);
|
|
|
+ }
|
|
|
+ processImageWithWatermark(item);
|
|
|
+ return item.originalImage;
|
|
|
+};
|
|
|
// 图片列表数据
|
|
|
const imageList = computed(() => {
|
|
|
if (!currentDisplayArtifact.value) return [];
|
|
|
|
|
|
const imgFiles = currentDisplayArtifact.value.imgFiles || [];
|
|
|
return imgFiles.map((imgFile, index) => ({
|
|
|
+ id: `${currentDisplayArtifact.value.id}_image_${index}`, // 使用文物ID + 图片索引作为唯一ID
|
|
|
type: 'image',
|
|
|
src: `${imguRL}${imgFile}`,
|
|
|
+ originalImage: `${imguRL}${imgFile}`,
|
|
|
alt: `${currentDisplayArtifact.value.name} 图片${index + 1}`
|
|
|
}));
|
|
|
});
|
|
|
@@ -450,6 +505,20 @@ const navigateArtifact = (direction) => {
|
|
|
|
|
|
const newArtifact = effectiveArtifactList.value[newIndex];
|
|
|
|
|
|
+ // 清理当前文物的水印缓存,避免内存泄漏
|
|
|
+ const currentArtifactId = currentDisplayArtifact.value?.id;
|
|
|
+ if (currentArtifactId) {
|
|
|
+ // 清理当前文物相关的水印缓存
|
|
|
+ const keysToDelete = [];
|
|
|
+ watermarkedImages.value.forEach((value, key) => {
|
|
|
+ if (key.startsWith(`${currentArtifactId}_image_`)) {
|
|
|
+ keysToDelete.push(key);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ keysToDelete.forEach(key => watermarkedImages.value.delete(key));
|
|
|
+ // console.log(`清理了 ${keysToDelete.length} 个水印缓存`);
|
|
|
+ }
|
|
|
+
|
|
|
// 重置详情数据,触发新的详情加载
|
|
|
artifactDetail.value = null;
|
|
|
|