From 059b0922f532e59536fb6dd9e72b259c36689d23 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期五, 24 四月 2026 16:58:06 +0800
Subject: [PATCH] 优化文件预览功能,新增视频文件播放逻辑,改进文件URL处理,确保视频播放的稳定性和兼容性。

---
 src/pages/inspectionUpload/index.vue |  149 ++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 138 insertions(+), 11 deletions(-)

diff --git a/src/pages/inspectionUpload/index.vue b/src/pages/inspectionUpload/index.vue
index badcebb..cb07466 100644
--- a/src/pages/inspectionUpload/index.vue
+++ b/src/pages/inspectionUpload/index.vue
@@ -188,7 +188,8 @@
                 <view v-for="(file, index) in getCurrentFiles()"
                       :key="index"
                       class="file-item">
-                  <view class="file-preview-container">
+                  <view class="file-preview-container"
+                        @click="previewUploadedMedia(file)">
                     <image v-if="isImageFile(file)"
                            :src="getFileAccessUrl(file)"
                            class="file-preview"
@@ -335,7 +336,7 @@
         </view>
         <view class="video-modal-body">
           <video v-if="currentVideoFile"
-                 :src="getFileAccessUrl(currentVideoFile)"
+                 :src="currentVideoFile._playUrl"
                  class="video-player"
                  controls
                  autoplay
@@ -904,7 +905,7 @@
         return {
           ...file,
           // 鐢ㄤ簬涓夋爣绛鹃〉鍒嗙粍锛�0=鐢熶骇鍓� 1=鐢熶骇涓� 2=鐢熶骇鍚�
-          type: viewType,
+          viewType,
           name: file?.name || file?.originalFilename || file?.bucketFilename,
           bucketFilename: file?.bucketFilename || file?.name,
           originalFilename: file?.originalFilename || file?.name,
@@ -942,7 +943,7 @@
 
   // 鏍规嵁type鑾峰彇瀵瑰簲鍒嗙被鐨勯檮浠�
   const getAttachmentsByType = typeValue => {
-    return attachmentList.value.filter(file => file.type === typeValue) || [];
+    return attachmentList.value.filter(file => file.viewType === typeValue) || [];
   };
   // 鑾峰彇type鍊�
   const getTabType = () => {
@@ -1001,6 +1002,9 @@
 
   const normalizeFileUrl = (rawUrl = "") => {
     let fileUrl = rawUrl || "";
+    if (typeof fileUrl === "string") {
+      fileUrl = fileUrl.trim().replace(/^['"]|['"]$/g, "");
+    }
     const javaApi = filePreviewBase;
     const localPrefixes = ["wxfile://", "file://", "content://", "blob:", "data:"];
 
@@ -1011,14 +1015,33 @@
     if (fileUrl && fileUrl.indexOf("\\") > -1) {
       const lowerPath = fileUrl.toLowerCase();
       const uploadPathIndex = lowerPath.indexOf("uploadpath");
+      const prodIndex = lowerPath.indexOf("\\prod\\");
 
       if (uploadPathIndex > -1) {
         fileUrl = fileUrl.substring(uploadPathIndex).replace(/\\/g, "/");
+      } else if (prodIndex > -1) {
+        fileUrl = fileUrl
+          .substring(prodIndex + "\\prod\\".length)
+          .replace(/\\/g, "/");
       } else {
         fileUrl = fileUrl.replace(/\\/g, "/");
       }
     }
-    fileUrl = fileUrl.replace(/^\/?uploadPath/, "/profile");
+    // /javaWork/.../file/prod/xxx -> /profile/prod/xxx
+    const normalizedLower = String(fileUrl).toLowerCase();
+    const fileProdIdx = normalizedLower.indexOf("/file/prod/");
+    if (fileProdIdx > -1) {
+      fileUrl = `/profile/prod/${fileUrl.substring(fileProdIdx + "/file/prod/".length)}`;
+    }
+    // /javaWork/.../file/temp/xxx -> /profile/temp/xxx
+    const fileTempIdx = normalizedLower.indexOf("/file/temp/");
+    if (fileTempIdx > -1) {
+      fileUrl = `/profile/temp/${fileUrl.substring(fileTempIdx + "/file/temp/".length)}`;
+    }
+
+    if (/^\/?uploadPath/i.test(fileUrl)) {
+      fileUrl = fileUrl.replace(/^\/?uploadPath/i, "/profile");
+    }
 
     if (fileUrl && !fileUrl.startsWith("http")) {
       if (!fileUrl.startsWith("/")) fileUrl = "/" + fileUrl;
@@ -1033,7 +1056,37 @@
       if (String(file.link).startsWith("http")) return file.link;
       return normalizeFileUrl(file.link);
     }
-    return normalizeFileUrl(file?.url || file?.downloadUrl || "");
+    const remoteUrl = normalizeFileUrl(
+      file?.url ||
+        file?.downloadUrl ||
+        file?.tempPath ||
+        ""
+    );
+    if (remoteUrl) return remoteUrl;
+    // 鍏滃簳鏈湴璺緞锛堜笂浼犲綋娆¢瑙堬級
+    if (file?._localPreviewUrl) return file._localPreviewUrl;
+    return normalizeFileUrl(file?.tempFilePath || file?.path || "");
+  };
+
+  // 涓婁紶寮圭獥鍐呯殑濯掍綋棰勮锛堝浘鐗�/瑙嗛锛�
+  const previewUploadedMedia = file => {
+    if (!file) return;
+    if (isImageFile(file)) {
+      const imageUrls = getCurrentFiles()
+        .filter(f => isImageFile(f))
+        .map(f => getFileAccessUrl(f))
+        .filter(Boolean);
+      const current = getFileAccessUrl(file);
+      if (!imageUrls.length || !current) return;
+      uni.previewImage({
+        urls: imageUrls,
+        current,
+      });
+      return;
+    }
+    if (isVideoFile(file)) {
+      playVideoFile(file);
+    }
   };
 
   // 棰勮闄勪欢
@@ -1049,9 +1102,50 @@
         current: getFileAccessUrl(file),
       });
     } else {
-      // 棰勮瑙嗛 - 鏄剧ず瑙嗛鎾斁寮圭獥
-      showVideoPreview(file);
+      // 棰勮瑙嗛
+      playVideoFile(file);
     }
+  };
+
+  const safeEncodeUrl = url => {
+    if (!url) return "";
+    if (!/^https?:\/\//i.test(url)) return url;
+    try {
+      return encodeURI(url);
+    } catch (e) {
+      return url;
+    }
+  };
+
+  const getPlayableVideoUrl = file => {
+    return safeEncodeUrl(getFileAccessUrl(file));
+  };
+
+  const getFallbackLocalVideoUrl = file => {
+    const local = file?._localPreviewUrl || file?.tempFilePath || file?.path || "";
+    return safeEncodeUrl(local);
+  };
+
+  const playVideoFile = file => {
+    const remoteSrc = getPlayableVideoUrl(file);
+    const localSrc = getFallbackLocalVideoUrl(file);
+    // 寮圭獥鎾斁鍣ㄤ紭鍏堣繙绋嬪湴鍧�锛屽け璐ュ啀鑷姩鍥為��鏈湴鍦板潃
+    const src = remoteSrc || localSrc;
+    if (!src) {
+      uni.showToast({
+        title: "瑙嗛鍦板潃鏃犳晥",
+        icon: "none",
+      });
+      return;
+    }
+
+    // 缁熶竴浣跨敤椤甸潰鍐� video 寮圭獥鎾斁
+    showVideoPreview({
+      ...file,
+      _playUrl: src,
+      _playUrlLocal: localSrc,
+      _playUrlRemote: remoteSrc,
+    });
   };
 
   // 鏄剧ず瑙嗛棰勮
@@ -1067,7 +1161,32 @@
   };
 
   // 瑙嗛鎾斁閿欒澶勭悊
-  const handleVideoError = error => {
+  const handleVideoError = () => {
+    const localUrl = currentVideoFile.value?._playUrlLocal;
+    const remoteUrl = currentVideoFile.value?._playUrlRemote;
+    const currentUrl = currentVideoFile.value?._playUrl;
+    if (remoteUrl && currentUrl !== remoteUrl) {
+      currentVideoFile.value = {
+        ...currentVideoFile.value,
+        _playUrl: remoteUrl,
+      };
+      uni.showToast({
+        title: "宸插垏鎹㈣繙绋嬭棰戦噸璇曟挱鏀�",
+        icon: "none",
+      });
+      return;
+    }
+    if (localUrl && currentUrl !== localUrl) {
+      currentVideoFile.value = {
+        ...currentVideoFile.value,
+        _playUrl: localUrl,
+      };
+      uni.showToast({
+        title: "宸插垏鎹㈡湰鍦拌棰戦噸璇曟挱鏀�",
+        icon: "none",
+      });
+      return;
+    }
     uni.showToast({
       title: "瑙嗛鎾斁澶辫触",
       icon: "error",
@@ -1500,10 +1619,16 @@
       url:
         uploadedFile.url ||
         uploadedFile.downloadUrl ||
+        uploadedFile.tempPath ||
         file.tempFilePath ||
         file.path,
+      tempPath: uploadedFile.tempPath || file.tempPath || "",
+      _localPreviewUrl: file.tempFilePath || file.path || "",
       bucketFilename:
-        uploadedFile.bucketFilename || uploadedFile.originalFilename || file.name,
+        uploadedFile.bucketFilename ||
+        uploadedFile.originalFilename ||
+        uploadedFile.originalName ||
+        file.name,
       downloadUrl: uploadedFile.downloadUrl || uploadedFile.url,
       size: uploadedFile.size || uploadedFile.byteSize || file.size,
       createTime: uploadedFile.createTime || new Date().getTime(),
@@ -2216,8 +2341,10 @@
 
   .video-player {
     width: 100%;
-    height: auto;
+    height: 56vh;
+    min-height: 260px;
     max-height: 60vh;
     display: block;
+    object-fit: contain;
   }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3