From 0797fd7265233e630d1eacc8e46537ea52ff6340 Mon Sep 17 00:00:00 2001 From: "wangmingyong@163.com" Date: Wed, 26 Aug 2026 16:45:24 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=86=E9=A2=91=E4=B8=8A=E4=BC=A0=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/util/w6sMedia.js | 68 ++++++++----------- .../nos/components/NosDetailMaterialsTab.vue | 20 +++--- 2 files changed, 38 insertions(+), 50 deletions(-) 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 3f6d117d..cc5f2bda 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 @@ -114,49 +114,34 @@ 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) - } - ) +const copyFileToAppDir = async (sourcePath) => { + if (!window.cordova?.file?.dataDirectory) { + throw new Error('cordova.file.dataDirectory 不可用') + } + console.log('[w6sMedia] copyFileToAppDir sourcePath:', sourcePath) + + const sourceEntry = await new Promise((resolve, reject) => { + window.resolveLocalFileSystemURL(sourcePath, resolve, reject) + }) + console.log('[w6sMedia] 源文件 entry:', sourceEntry.fullPath, 'name:', sourceEntry.name) + + const dataDirEntry = await new Promise((resolve, reject) => { + window.resolveLocalFileSystemURL(window.cordova.file.dataDirectory, resolve, reject) + }) + console.log('[w6sMedia] 应用私有目录:', dataDirEntry.fullPath) + + const newFileEntry = await new Promise((resolve, reject) => { + sourceEntry.copyTo(dataDirEntry, sourceEntry.name, resolve, reject) }) + // toURL() 返回 file:// 格式的 URL,FileTransfer 可直接使用 + const fileUrl = newFileEntry.toURL() + console.log('[w6sMedia] 文件已复制到应用私有目录, fileUrl:', fileUrl, 'fullPath:', newFileEntry.fullPath) + return fileUrl } // 录制视频(使用 Cordova 原生 Media Capture API) export const startVideoRecorder = async ({ - duration = 60, + duration = 0, quality = 1, // 0 高清 / 1 一般 / 2 流畅 front = false, syncSystemAlbum = false, @@ -202,7 +187,7 @@ export const startVideoRecorder = async ({ console.error('[w6sMedia] captureVideo fail:', error, 'code:', error?.code, 'message:', error?.message) reject(error) }, - { limit: 1, duration } + duration ? { limit: 1, duration } : { limit: 1 } ) }) } @@ -249,7 +234,7 @@ export const uploadLocalFileToBackend = async ({ success: (res) => { console.log('[w6sMedia] file.upload success 原始返回:', res) try { - const parsed = typeof res.response === 'string' ? JSON.parse(res.response) : res.response + const parsed = JSON.parse(res.response) console.log('[w6sMedia] 解析后的上传响应:', parsed) resolve(parsed) } catch (e) { @@ -264,7 +249,8 @@ export const uploadLocalFileToBackend = async ({ }, opts ).catch((err) => { - console.error('[w6sMedia] w6s.file.upload 异常:', err) + // w6s.file.upload 在 responseCode !== 200 时会 reject 但不调用 fail 回调 + console.error('[w6sMedia] w6s.file.upload Promise reject:', err) reject(err) }) }) 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 cc9d55c3..0a796001 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 @@ -486,7 +486,9 @@ const pushSdkFileToFileList = async (item, { localPath, fileName, mimeType, isIm message: '上传中...', } item.fileList.push(fileObj) - console.log('[NosDetail] 已 push 到 fileList, 当前 fileList 长度:', item.fileList.length, 'fileObj:', fileObj) + // 取数组中的响应式引用,避免后续直接修改原始普通对象导致视图不更新 + const reactiveFile = item.fileList[item.fileList.length - 1] + console.log('[NosDetail] 已 push 到 fileList, 当前 fileList 长度:', item.fileList.length) try { const res = await uploadLocalFileToBackend({ fileURL: localPath, fileName, mimeType }) console.log('[NosDetail] 上传后端返回 res:', res) @@ -496,19 +498,19 @@ const pushSdkFileToFileList = async (item, { localPath, fileName, mimeType, isIm : (data && (data.data || data.url || data.fileUrl || data.path)) || '' console.log('[NosDetail] 解析出的 filePath:', filePath, 'data:', data) if (filePath) { - fileObj.url = toFullFileUrl(filePath) - fileObj.status = 'done' - fileObj.message = '' - console.log('[NosDetail] 上传成功, fileObj.url:', fileObj.url) + reactiveFile.url = toFullFileUrl(filePath) + reactiveFile.status = 'done' + reactiveFile.message = '' + console.log('[NosDetail] 上传成功, url:', reactiveFile.url) } else { - fileObj.status = 'failed' - fileObj.message = '上传失败' + reactiveFile.status = 'failed' + reactiveFile.message = '上传失败' console.warn('[NosDetail] 上传失败: filePath 为空') } } catch (err) { console.error('[NosDetail] w6s 上传后端失败:', err) - fileObj.status = 'failed' - fileObj.message = '上传失败' + reactiveFile.status = 'failed' + reactiveFile.message = '上传失败' } }