From 12d9294f3d86f82a0c901f943a34668b42cff5fa Mon Sep 17 00:00:00 2001 From: wangys <3401275564@qq.com> Date: Thu, 22 Jan 2026 11:36:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/admin/workcase/WorkcaseView.vue | 2 +- .../packages/workcase_wechat/config/index.ts | 12 +- .../pages/chatRoom/chatRoom/chatRoom.uvue | 188 +++++++++++++----- .../workcase_wechat/pages/index/index.uvue | 3 +- .../pages/meeting/Meeting.uvue | 64 +++--- 5 files changed, 173 insertions(+), 96 deletions(-) diff --git a/urbanLifelineWeb/packages/workcase/src/views/admin/workcase/WorkcaseView.vue b/urbanLifelineWeb/packages/workcase/src/views/admin/workcase/WorkcaseView.vue index bf0e4f1e..50a11755 100644 --- a/urbanLifelineWeb/packages/workcase/src/views/admin/workcase/WorkcaseView.vue +++ b/urbanLifelineWeb/packages/workcase/src/views/admin/workcase/WorkcaseView.vue @@ -306,7 +306,7 @@ const loadChatRoomsByGuest = async (guestId: string) => { // 监听来客人员选择变化,加载对应的聊天室列表 watch(selectedGuestId, (newGuestId) => { - const selectedGuest = guestsList.value.find(guest => guest.userId === newGuestId) + const selectedGuest = guestsList.value.find((guest:TbGuestDTO) => guest.userId === newGuestId) if (selectedGuest) { formData.value.username = selectedGuest.name formData.value.userId = selectedGuest.userId diff --git a/urbanLifelineWeb/packages/workcase_wechat/config/index.ts b/urbanLifelineWeb/packages/workcase_wechat/config/index.ts index 739b06ff..fecdf2b6 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/config/index.ts +++ b/urbanLifelineWeb/packages/workcase_wechat/config/index.ts @@ -1,10 +1,10 @@ export const AGENT_ID = '17678420499370001' -export const BASE_URL = 'http://localhost:8180' +// export const BASE_URL = 'http://localhost:8180' // 根据宝塔nginx配置,/urban-lifeline/ 会代理到后端网关 -// export const BASE_URL = 'https://demo-urbanlifeline.tensorgrove.com/urban-lifeline' +export const BASE_URL = 'https://demo-urbanlifeline.tensorgrove.com/urban-lifeline' -export const MEET_URL = 'https://org.xyzh.yslg/workcase' -// export const MEET_URL = 'https://demo-urbanlifeline.tensorgrove.com/workcase' +// export const MEET_URL = 'https://org.xyzh.yslg/workcase' +export const MEET_URL = 'https://demo-urbanlifeline.tensorgrove.com/workcase' -export const WS_HOST = 'localhost:8180' // WebSocket host(不包含协议) -// export const WS_HOST = 'demo-urbanlifeline.tensorgrove.com/urban-lifeline' // WebSocket host(不包含协议) \ No newline at end of file +// export const WS_HOST = 'localhost:8180' // WebSocket host(不包含协议) +export const WS_HOST = 'demo-urbanlifeline.tensorgrove.com/urban-lifeline' // WebSocket host(不包含协议) \ No newline at end of file diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue b/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue index c559f653..b9fbf964 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/chatRoom/chatRoom/chatRoom.uvue @@ -156,10 +156,10 @@ - - 📎 - + + 📎 + @@ -697,45 +697,27 @@ async function handleJoinMeeting(meetingId: string) { const meetingName = meetingData.meetingName || '视频会议' console.log('[handleJoinMeeting] 获取到会议页面URL:', meetingPageUrl, '会议名称:', meetingName) - // 小程序环境:直接使用固定的HTTPS域名 - const protocol = 'https:' - const host = 'org.xyzh.yslg' - // 如果meetingPageUrl不包含/workcase,需要加上 - const fullPath = meetingPageUrl.startsWith('/workcase') - ? meetingPageUrl - : '/workcase' + meetingPageUrl - // 附加roomId参数,用于离开会议后返回聊天室 - const fullMeetingUrl = `${protocol}//${host}${fullPath}&roomId=${roomId.value}` + // 使用API返回的完整jitsiIframeUrl作为会议链接 + let fullMeetingUrl = meetingData.jitsiIframeUrl || '' + + // 如果没有jitsiIframeUrl,再使用iframeUrl构建 + if (!fullMeetingUrl && meetingData.iframeUrl) { + // 小程序环境:直接使用固定的HTTPS域名 + const protocol = 'https:' + const host = 'org.xyzh.yslg' + // 如果meetingPageUrl不包含/workcase,需要加上 + const fullPath = meetingData.iframeUrl.startsWith('/workcase') + ? meetingData.iframeUrl + : '/workcase' + meetingData.iframeUrl + // 附加roomId参数,用于离开会议后返回聊天室 + fullMeetingUrl = `${protocol}//${host}${fullPath}&roomId=${roomId.value}` + } console.log('[handleJoinMeeting] 完整会议URL:', fullMeetingUrl) - // 小程序环境:显示提示,引导用户复制链接在浏览器打开 - uni.showModal({ - title: '视频会议', - content: '微信小程序暂不支持视频会议,请复制链接在浏览器中打开', - confirmText: '复制链接', - cancelText: '取消', - success: (res) => { - if (res.confirm) { - // 复制链接到剪贴板 - uni.setClipboardData({ - data: fullMeetingUrl, - success: () => { - uni.showToast({ - title: '链接已复制,请在浏览器中打开', - icon: 'none', - duration: 3000 - }) - }, - fail: () => { - uni.showToast({ - title: '复制失败,请手动复制', - icon: 'none' - }) - } - }) - } - } + // 跳转到会议页面 + uni.navigateTo({ + url: `/pages/meeting/Meeting?meetingId=${meetingId}&meetingName=${encodeURIComponent(meetingName)}&jitsiIframeUrl=${encodeURIComponent(fullMeetingUrl)}` }) } else { console.error('[handleJoinMeeting] 加入会议失败, isSuccess:', isSuccess, 'data:', meetingData) @@ -780,23 +762,120 @@ async function handleCommentSubmit(rating: number) { // 文件操作相关函数 -// 选择文件 -async function chooseFile() { - try { - const res = await uni.chooseMessageFile({ - count: 9, // 最多选择9个文件 - type: 'file', - ext: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'jpg', 'jpeg', 'png', 'gif'] - }) - - if (res.tempFiles && res.tempFiles.length > 0) { - // 添加到选中文件列表 - selectedFiles.value = [...selectedFiles.value, ...res.tempFiles] +// 显示上传选项 +function showUploadOptions() { + uni.showActionSheet({ + itemList: ['拍照', '从相册选择', '选择文件'], + success: (res) => { + switch (res.tapIndex) { + case 0: + // 拍照 + chooseImageFromCamera() + break + case 1: + // 从相册选择 + chooseImageFromAlbum() + break + case 2: + // 选择文件 + chooseFile() + break + } } - } catch (error) { - console.error('选择文件失败:', error) - uni.showToast({ title: '选择文件失败', icon: 'none' }) + }) +} + +// 拍照 +function chooseImageFromCamera() { + uni.chooseImage({ + count: 9, + sourceType: ['camera'], + success: (res) => { + if (res.tempFiles && res.tempFiles.length > 0) { + // 添加到选中文件列表 + selectedFiles.value = [...selectedFiles.value, ...res.tempFiles] + } + }, + fail: (err) => { + console.error('拍照失败:', err) + uni.showToast({ title: '拍照失败', icon: 'none' }) + } + }) +} + +// 从相册选择 +function chooseImageFromAlbum() { + uni.chooseImage({ + count: 9, + sourceType: ['album'], + success: (res) => { + if (res.tempFiles && res.tempFiles.length > 0) { + // 添加到选中文件列表 + selectedFiles.value = [...selectedFiles.value, ...res.tempFiles] + } + }, + fail: (err) => { + console.error('从相册选择失败:', err) + uni.showToast({ title: '选择图片失败', icon: 'none' }) + } + }) +} + +// 选择文件 +function chooseFile() { + // #ifdef MP-WEIXIN + // 微信小程序使用 chooseMessageFile + uni.chooseMessageFile({ + count: 9, + type: 'file', + extension: ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'txt', 'jpg', 'jpeg', 'png', 'gif'], + success: (res : any) => { + console.log('选择文件成功:', res) + if (res.tempFiles && res.tempFiles.length > 0) { + // 添加到选中文件列表 + selectedFiles.value = [...selectedFiles.value, ...res.tempFiles] + } + }, + fail: (err : any) => { + console.error('选择文件失败:', err) + uni.showToast({ + title: '选择文件失败', + icon: 'none' + }) + } + }) + // #endif + + // #ifndef MP-WEIXIN + // 非微信小程序环境 + // @ts-ignore + if (typeof uni.chooseFile === 'function') { + // @ts-ignore + uni.chooseFile({ + count: 9, + extension: ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.txt', '.jpg', '.jpeg', '.png', '.gif'], + success: (res : any) => { + console.log('选择文件成功:', res) + if (res.tempFiles && res.tempFiles.length > 0) { + // 添加到选中文件列表 + selectedFiles.value = [...selectedFiles.value, ...res.tempFiles] + } + }, + fail: (err : any) => { + console.error('选择文件失败:', err) + uni.showToast({ + title: '选择文件失败', + icon: 'none' + }) + } + }) + } else { + uni.showToast({ + title: '当前环境不支持文件选择', + icon: 'none' + }) } + // #endif } // 删除选中的文件 @@ -822,6 +901,7 @@ async function uploadFiles(): Promise { isUploading.value = true uni.showLoading({ title: '上传中...' }) + try { // 获取文件路径数组 const filePaths = selectedFiles.value.map(file => file.path) diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue index 7338f6f2..461cd674 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/index/index.uvue @@ -720,7 +720,8 @@ onError: (error) => { console.error('SSE错误:', error) isTyping.value = false - messages.value[messageIndex].content = error + // 只返回友好的错误信息,而不是原始错误对象 + messages.value[messageIndex].content = '抱歉,AI服务暂时不可用,请稍后重试。' }, onComplete: () => { isTyping.value = false diff --git a/urbanLifelineWeb/packages/workcase_wechat/pages/meeting/Meeting.uvue b/urbanLifelineWeb/packages/workcase_wechat/pages/meeting/Meeting.uvue index 69f11b1f..1feb3aa5 100644 --- a/urbanLifelineWeb/packages/workcase_wechat/pages/meeting/Meeting.uvue +++ b/urbanLifelineWeb/packages/workcase_wechat/pages/meeting/Meeting.uvue @@ -284,27 +284,25 @@ function handleWebViewError(e: any) { // 复制会议链接 function copyUrl() { - if (!meetingUrl.value) { + // 获取页面参数 + const pages = getCurrentPages() + const currentPage = pages[pages.length - 1] as any + + // 优先检查页面参数中是否有jitsiIframeUrl + let fullMeetingUrl = '' + + // 检查是否直接传递了jitsiIframeUrl参数 + const jitsiIframeUrl = currentPage?.options?.jitsiIframeUrl || '' + if (jitsiIframeUrl) { + fullMeetingUrl = jitsiIframeUrl + } else if (meetingUrl.value) { + // 兼容老版本,使用meetingUrl + fullMeetingUrl = meetingUrl.value + } else { uni.showToast({ title: '会议链接为空', icon: 'none' }) return } - // 解析iframeUrl并构建完整的会议链接 - let fullMeetingUrl = meetingUrl.value - - // 检查是否为微信小程序环境 - // #ifdef MP-WEIXIN - // 获取页面参数中的iframeUrl - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] as any - const iframeUrl = currentPage?.options?.iframeUrl || '' - - if (iframeUrl) { - // 构建正确的会议链接:MEET_URL + iframeUrl - fullMeetingUrl = `${MEET_URL}${iframeUrl}` - } - // #endif - uni.setClipboardData({ data: fullMeetingUrl, success: () => { @@ -318,27 +316,25 @@ function copyUrl() { // 在浏览器中打开 function openInBrowser() { - if (!meetingUrl.value) { + // 获取页面参数 + const pages = getCurrentPages() + const currentPage = pages[pages.length - 1] as any + + // 优先检查页面参数中是否有jitsiIframeUrl + let fullMeetingUrl = '' + + // 检查是否直接传递了jitsiIframeUrl参数 + const jitsiIframeUrl = currentPage?.options?.jitsiIframeUrl || '' + if (jitsiIframeUrl) { + fullMeetingUrl = jitsiIframeUrl + } else if (meetingUrl.value) { + // 兼容老版本,使用meetingUrl + fullMeetingUrl = meetingUrl.value + } else { uni.showToast({ title: '会议链接为空', icon: 'none' }) return } - // 解析iframeUrl并构建完整的会议链接 - let fullMeetingUrl = meetingUrl.value - - // 检查是否为微信小程序环境且会议链接不是完整的MEET_URL格式 - // #ifdef MP-WEIXIN - // 获取页面参数中的iframeUrl - const pages = getCurrentPages() - const currentPage = pages[pages.length - 1] as any - const iframeUrl = currentPage?.options?.iframeUrl || '' - - if (iframeUrl) { - // 构建正确的会议链接:MEET_URL + iframeUrl - fullMeetingUrl = `${MEET_URL}${iframeUrl}` - } - // #endif - // #ifdef MP-WEIXIN // 微信小程序:先复制链接,然后提示用户通过右上角菜单在浏览器中打开 uni.setClipboardData({