diff --git a/zdxt-web-client/zdxt-efcode-enterprise-app/src/util/w6sMedia.js b/zdxt-web-client/zdxt-efcode-enterprise-app/src/util/w6sMedia.js index 1d96131e..3f6d117d 100644 --- a/zdxt-web-client/zdxt-efcode-enterprise-app/src/util/w6sMedia.js +++ b/zdxt-web-client/zdxt-efcode-enterprise-app/src/util/w6sMedia.js @@ -113,6 +113,47 @@ export const takePhotoWithWaterMark = async ({ }) } +// 将文件从公共目录复制到应用私有目录(解决 Android 11+ 分区存储导致的 EACCES 权限问题) +const copyFileToAppDir = (sourcePath) => { + return new Promise((resolve, reject) => { + if (!window.cordova?.file?.dataDirectory) { + reject(new Error('cordova.file.dataDirectory 不可用')) + return + } + window.resolveLocalFileSystemURL( + sourcePath, + (fileEntry) => { + window.resolveLocalFileSystemURL( + window.cordova.file.dataDirectory, + (dataDirEntry) => { + const fileName = fileEntry.name + fileEntry.copyTo( + dataDirEntry, + fileName, + (newFileEntry) => { + console.log('[w6sMedia] 文件已复制到应用私有目录:', newFileEntry.fullPath) + resolve(newFileEntry.fullPath) + }, + (copyErr) => { + console.error('[w6sMedia] 复制文件失败:', copyErr) + reject(copyErr) + } + ) + }, + (dirErr) => { + console.error('[w6sMedia] 获取应用私有目录失败:', dirErr) + reject(dirErr) + } + ) + }, + (fileErr) => { + console.error('[w6sMedia] 解析源文件失败:', fileErr, 'sourcePath:', sourcePath) + reject(fileErr) + } + ) + }) +} + // 录制视频(使用 Cordova 原生 Media Capture API) export const startVideoRecorder = async ({ duration = 60, @@ -130,17 +171,29 @@ export const startVideoRecorder = async ({ return } navigator.device.capture.captureVideo( - (mediaFiles) => { + async (mediaFiles) => { console.log('[w6sMedia] captureVideo success, mediaFiles:', mediaFiles) if (mediaFiles && mediaFiles.length > 0) { const file = mediaFiles[0] console.log('[w6sMedia] 视频文件: fullPath=', file.fullPath, 'name=', file.name, 'size=', file.size, 'type=', file.type) - resolve({ - video_path: file.fullPath, - name: file.name, - size: file.size, - type: file.type || 'video/mp4', - }) + try { + const appDirPath = await copyFileToAppDir(file.fullPath) + console.log('[w6sMedia] 视频已复制到应用私有目录:', appDirPath) + resolve({ + video_path: appDirPath, + name: file.name, + size: file.size, + type: file.type || 'video/mp4', + }) + } catch (copyErr) { + console.warn('[w6sMedia] 复制视频失败,尝试使用原路径:', copyErr) + resolve({ + video_path: file.fullPath, + name: file.name, + size: file.size, + type: file.type || 'video/mp4', + }) + } } else { reject(new Error('录制未生成视频文件')) } diff --git a/zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/nos/components/NosDetailMaterialsTab.vue b/zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/nos/components/NosDetailMaterialsTab.vue index c5c47372..cc9d55c3 100644 --- a/zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/nos/components/NosDetailMaterialsTab.vue +++ b/zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/nos/components/NosDetailMaterialsTab.vue @@ -64,10 +64,36 @@ - -
- -
+ +
@@ -540,6 +566,34 @@ const onPreview = (url, itemValue) => { startPosition: start >= 0 ? start : 0 }) } + +const onPreviewItem = (item, fileIndex) => { + const file = item.fileList?.[fileIndex] + if (!file) return + if (file.isImage) { + const images = (item.fileList || []) + .filter((f) => f.isImage && f.status === 'done') + .map((f) => f.url) + const start = images.indexOf(file.url) + showImagePreview({ + images, + startPosition: start >= 0 ? start : 0 + }) + } else { + previewVideoUrl.value = file.url + showVideoPreview.value = true + } +} + +const onRemoveFile = (item, fileIndex) => { + showConfirmDialog({ + title: '确认删除', + message: '确定删除该文件吗?', + }).then(() => { + item.fileList.splice(fileIndex, 1) + showToast('已删除') + }).catch(() => {}) +}