diff --git a/pages/message/components/chat-input.vue b/pages/message/components/chat-input.vue index 571e398..0bdc9be 100644 --- a/pages/message/components/chat-input.vue +++ b/pages/message/components/chat-input.vue @@ -199,12 +199,10 @@ const toggleMorePanel = () => { // 处理图片选择 const showImagePicker = () => { chooseImage( - (res) => { - console.log('选择图片成功,返回数据:', res); - // 提取实际的文件对象 - const imageFile = res.tempFiles && res.tempFiles.length > 0 ? res.tempFiles[0] : res; - console.log('准备发送图片:', imageFile); - sendImageMessage(imageFile); + (file) => { + console.log('选择图片成功,文件对象:', file); + // 直接传递文件对象,不需要额外处理 + sendImageMessage(file); }, (err) => { console.error('选择图片失败:', err); @@ -221,12 +219,10 @@ const showImagePicker = () => { const takePhoto = () => { takePhotoUtil( - (res) => { - console.log('拍照成功,返回数据:', res); - // 提取实际的文件对象 - const imageFile = res.tempFiles && res.tempFiles.length > 0 ? res.tempFiles[0] : res; - console.log('准备发送图片:', imageFile); - sendImageMessage(imageFile); + (file) => { + console.log('拍照成功,文件对象:', file); + // 直接传递文件对象,不需要额外处理 + sendImageMessage(file); }, (err) => { console.error('拍照失败:', err); diff --git a/utils/chat-utils.js b/utils/chat-utils.js index f172069..12849c4 100644 --- a/utils/chat-utils.js +++ b/utils/chat-utils.js @@ -346,31 +346,133 @@ export const chooseMedia = async (options, onSuccess, onFail) => { }; /** - * 选择图片 + * 选择图片(针对 TIM SDK 优化) * @param {function} onSuccess - 成功回调 * @param {function} onFail - 失败回调 */ -export const chooseImage = (onSuccess, onFail) => { +export const chooseImage = async (onSuccess, onFail) => { + // 检查权限 + const sourceType = ['album', 'camera']; + if (sourceType.includes('album')) { + const hasPermission = await checkAlbumPermission(); + if (!hasPermission) { + console.log('用户未授予相册权限'); + if (onFail) { + onFail({ errMsg: '未授权相册权限' }); + } + return; + } + } + + // 使用 wx.chooseImage 以确保与 TIM SDK 兼容 + // #ifdef MP-WEIXIN + wx.chooseImage({ + count: 1, + sizeType: ['original', 'compressed'], + sourceType: sourceType, + success: function (res) { + console.log('wx.chooseImage 成功,完整返回数据:', JSON.stringify(res)); + console.log('tempFilePaths:', res.tempFilePaths); + console.log('tempFiles:', res.tempFiles); + + // TIM SDK 需要完整的 wx.chooseImage 返回对象,而不是单个文件 + // 直接传递整个 res 对象 + if (onSuccess) onSuccess(res); + }, + fail: function (err) { + // 用户取消选择 + if (err.errMsg && err.errMsg.includes('cancel')) { + console.log('用户取消选择'); + return; + } + + // 权限相关错误 + if (err.errMsg && (err.errMsg.includes('permission') || err.errMsg.includes('auth') || err.errMsg.includes('拒绝'))) { + console.error('相册权限被拒绝:', err); + uni.showModal({ + title: '需要相册权限', + content: '请在设置中开启相册权限后重试', + confirmText: '去设置', + success: (modalRes) => { + if (modalRes.confirm) { + uni.openSetting(); + } + } + }); + if (onFail) { + onFail(err); + } + return; + } + + // 其他错误 + console.error('选择图片失败:', err); + if (onFail) { + onFail(err); + } else { + showMessage('选择图片失败,请重试'); + } + } + }); + // #endif + + // #ifndef MP-WEIXIN + // 非微信小程序环境,使用 uni.chooseMedia chooseMedia({ count: 1, mediaType: ['image'], sizeType: ['original', 'compressed'], - sourceType: ['album', 'camera'] + sourceType: sourceType }, onSuccess, onFail); + // #endif }; /** - * 拍照 + * 拍照(针对 TIM SDK 优化) * @param {function} onSuccess - 成功回调 * @param {function} onFail - 失败回调 */ export const takePhoto = (onSuccess, onFail) => { + // 使用 wx.chooseImage 以确保与 TIM SDK 兼容 + // #ifdef MP-WEIXIN + wx.chooseImage({ + count: 1, + sizeType: ['original', 'compressed'], + sourceType: ['camera'], + success: function (res) { + console.log('wx.chooseImage (拍照) 成功,完整返回数据:', JSON.stringify(res)); + console.log('tempFilePaths:', res.tempFilePaths); + console.log('tempFiles:', res.tempFiles); + + // TIM SDK 需要完整的 wx.chooseImage 返回对象 + if (onSuccess) onSuccess(res); + }, + fail: function (err) { + // 用户取消 + if (err.errMsg && err.errMsg.includes('cancel')) { + console.log('用户取消拍照'); + return; + } + + console.error('拍照失败:', err); + if (onFail) { + onFail(err); + } else { + showMessage('拍照失败,请重试'); + } + } + }); + // #endif + + // #ifndef MP-WEIXIN + // 非微信小程序环境 chooseMedia({ count: 1, mediaType: ['image'], sizeType: ['original', 'compressed'], sourceType: ['camera'] }, onSuccess, onFail); + // #endif }; // ==================== 录音相关工具方法 ==================== diff --git a/utils/tim-chat.js b/utils/tim-chat.js index d57d8ce..87840bc 100644 --- a/utils/tim-chat.js +++ b/utils/tim-chat.js @@ -2161,19 +2161,30 @@ class TimChatManager { console.log('发送图片消息,conversationID:', conversationID, 'groupID:', groupID); - // 处理文件对象 - 确保获取正确的文件 - let actualFile = imageFile; - if (imageFile?.tempFiles?.length > 0) { - actualFile = imageFile.tempFiles[0]; - console.log('从 tempFiles 中提取文件:', actualFile); - } else if (imageFile?.tempFilePath) { - // 如果已经是单个文件对象 - actualFile = imageFile; - console.log('使用单个文件对象:', actualFile); + // imageFile 现在是完整的 wx.chooseImage 返回对象 + console.log('接收到的图片选择结果:', imageFile); + console.log('类型:', typeof imageFile); + console.log('keys:', imageFile ? Object.keys(imageFile) : 'null'); + + // 验证对象 + if (!imageFile) { + console.error('图片选择结果为空'); + this.triggerCallback('onError', '图片文件无效'); + return { success: false, error: '图片选择结果为空' }; } - // 获取图片尺寸信息 - const imageInfo = await this.getImageInfo(actualFile); + // 获取文件路径用于显示预览 + let previewPath = ''; + if (imageFile.tempFilePaths && imageFile.tempFilePaths.length > 0) { + previewPath = imageFile.tempFilePaths[0]; + } else if (imageFile.tempFiles && imageFile.tempFiles.length > 0) { + previewPath = imageFile.tempFiles[0].tempFilePath || imageFile.tempFiles[0].path; + } + + console.log('预览路径:', previewPath); + + // 获取图片尺寸信息(用于本地预览) + const imageInfo = await this.getImageInfo(previewPath); const localMessage = { ID: `local_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, @@ -2181,7 +2192,7 @@ class TimChatManager { type: 'TIMImageElem', payload: { imageInfoArray: [{ - url: this.getImageUrl(actualFile), + url: previewPath, width: imageInfo.width, height: imageInfo.height }] @@ -2200,17 +2211,20 @@ class TimChatManager { // 触发消息接收回调,让UI立即显示 this.triggerCallback('onMessageReceived', localMessage) - console.log('准备创建 TIM 图片消息,groupID:', groupID, 'file:', actualFile); + console.log('准备创建 TIM 图片消息,groupID:', groupID, 'imageFile:', imageFile); - const message = this.tim.createImageMessage({ - to: groupID, - conversationType: TIM.TYPES.CONV_GROUP, - payload: { file: actualFile } - }) - - console.log('TIM 图片消息已创建:', message); - try { + // 创建图片消息 - 直接传递 wx.chooseImage 的完整返回对象 + const message = this.tim.createImageMessage({ + to: groupID, + conversationType: TIM.TYPES.CONV_GROUP, + payload: { + file: imageFile // 传递完整的 wx.chooseImage 返回对象 + } + }) + + console.log('TIM 图片消息已创建:', message); + console.log('开始发送图片消息...'); const sendResult = await this.tim.sendMessage(message); console.log('图片消息发送成功:', sendResult); @@ -2218,6 +2232,11 @@ class TimChatManager { return { success: true, message: localMessage } } catch (error) { console.error('图片消息发送失败:', error) + console.error('错误详情:', { + message: error.message, + stack: error.stack, + imageFile: imageFile + }); localMessage.status = 'failed' // 如果是因为未登录导致的失败,尝试重连 @@ -2478,37 +2497,40 @@ class TimChatManager { } getImageUrl(imageFile) { - // 处理 tempFiles 数组格式 - if (imageFile?.tempFiles?.length > 0) { - return imageFile.tempFiles[0].tempFilePath - } - // 处理单个文件对象 + // 支持 tempFilePath 或 path if (imageFile?.tempFilePath) { - return imageFile.tempFilePath + return imageFile.tempFilePath; + } + if (imageFile?.path) { + return imageFile.path; } // 处理字符串路径 if (typeof imageFile === 'string') { - return imageFile + return imageFile; } console.warn('无法获取图片URL,使用默认图片:', imageFile); - return '/static/home/photo.png' + return '/static/home/photo.png'; } // 获取图片尺寸信息 - getImageInfo(imageFile) { + getImageInfo(imagePath) { return new Promise((resolve) => { - let imagePath = ''; + // 如果传入的是对象,尝试提取路径 + if (typeof imagePath === 'object') { + if (imagePath?.tempFilePath) { + imagePath = imagePath.tempFilePath; + } else if (imagePath?.path) { + imagePath = imagePath.path; + } else { + console.warn('无法从对象中获取图片路径,使用默认尺寸:', imagePath); + resolve({ width: 400, height: 300 }); + return; + } + } - // 获取图片路径 - 处理多种格式 - if (imageFile?.tempFiles?.length > 0) { - imagePath = imageFile.tempFiles[0].tempFilePath; - } else if (imageFile?.tempFilePath) { - imagePath = imageFile.tempFilePath; - } else if (typeof imageFile === 'string') { - imagePath = imageFile; - } else { - console.warn('无法获取图片路径,使用默认尺寸:', imageFile); - // 默认尺寸 + // 如果不是字符串,使用默认尺寸 + if (typeof imagePath !== 'string' || !imagePath) { + console.warn('图片路径无效,使用默认尺寸:', imagePath); resolve({ width: 400, height: 300 }); return; }