小程序优化
This commit is contained in:
@@ -306,7 +306,7 @@ const loadChatRoomsByGuest = async (guestId: string) => {
|
|||||||
|
|
||||||
// 监听来客人员选择变化,加载对应的聊天室列表
|
// 监听来客人员选择变化,加载对应的聊天室列表
|
||||||
watch(selectedGuestId, (newGuestId) => {
|
watch(selectedGuestId, (newGuestId) => {
|
||||||
const selectedGuest = guestsList.value.find(guest => guest.userId === newGuestId)
|
const selectedGuest = guestsList.value.find((guest:TbGuestDTO) => guest.userId === newGuestId)
|
||||||
if (selectedGuest) {
|
if (selectedGuest) {
|
||||||
formData.value.username = selectedGuest.name
|
formData.value.username = selectedGuest.name
|
||||||
formData.value.userId = selectedGuest.userId
|
formData.value.userId = selectedGuest.userId
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
export const AGENT_ID = '17678420499370001'
|
export const AGENT_ID = '17678420499370001'
|
||||||
export const BASE_URL = 'http://localhost:8180'
|
// export const BASE_URL = 'http://localhost:8180'
|
||||||
// 根据宝塔nginx配置,/urban-lifeline/ 会代理到后端网关
|
// 根据宝塔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://org.xyzh.yslg/workcase'
|
||||||
// export const MEET_URL = 'https://demo-urbanlifeline.tensorgrove.com/workcase'
|
export const MEET_URL = 'https://demo-urbanlifeline.tensorgrove.com/workcase'
|
||||||
|
|
||||||
export const WS_HOST = 'localhost:8180' // WebSocket host(不包含协议)
|
// export const WS_HOST = 'localhost:8180' // WebSocket host(不包含协议)
|
||||||
// export const WS_HOST = 'demo-urbanlifeline.tensorgrove.com/urban-lifeline' // WebSocket host(不包含协议)
|
export const WS_HOST = 'demo-urbanlifeline.tensorgrove.com/urban-lifeline' // WebSocket host(不包含协议)
|
||||||
@@ -156,7 +156,7 @@
|
|||||||
<!-- 输入和操作行 -->
|
<!-- 输入和操作行 -->
|
||||||
<view class="input-row">
|
<view class="input-row">
|
||||||
<view class="input-actions">
|
<view class="input-actions">
|
||||||
<view class="action-btn" @tap="chooseFile">
|
<view class="action-btn" @tap="showUploadOptions">
|
||||||
<text class="action-icon">📎</text>
|
<text class="action-icon">📎</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -697,45 +697,27 @@ async function handleJoinMeeting(meetingId: string) {
|
|||||||
const meetingName = meetingData.meetingName || '视频会议'
|
const meetingName = meetingData.meetingName || '视频会议'
|
||||||
console.log('[handleJoinMeeting] 获取到会议页面URL:', meetingPageUrl, '会议名称:', meetingName)
|
console.log('[handleJoinMeeting] 获取到会议页面URL:', meetingPageUrl, '会议名称:', meetingName)
|
||||||
|
|
||||||
|
// 使用API返回的完整jitsiIframeUrl作为会议链接
|
||||||
|
let fullMeetingUrl = meetingData.jitsiIframeUrl || ''
|
||||||
|
|
||||||
|
// 如果没有jitsiIframeUrl,再使用iframeUrl构建
|
||||||
|
if (!fullMeetingUrl && meetingData.iframeUrl) {
|
||||||
// 小程序环境:直接使用固定的HTTPS域名
|
// 小程序环境:直接使用固定的HTTPS域名
|
||||||
const protocol = 'https:'
|
const protocol = 'https:'
|
||||||
const host = 'org.xyzh.yslg'
|
const host = 'org.xyzh.yslg'
|
||||||
// 如果meetingPageUrl不包含/workcase,需要加上
|
// 如果meetingPageUrl不包含/workcase,需要加上
|
||||||
const fullPath = meetingPageUrl.startsWith('/workcase')
|
const fullPath = meetingData.iframeUrl.startsWith('/workcase')
|
||||||
? meetingPageUrl
|
? meetingData.iframeUrl
|
||||||
: '/workcase' + meetingPageUrl
|
: '/workcase' + meetingData.iframeUrl
|
||||||
// 附加roomId参数,用于离开会议后返回聊天室
|
// 附加roomId参数,用于离开会议后返回聊天室
|
||||||
const fullMeetingUrl = `${protocol}//${host}${fullPath}&roomId=${roomId.value}`
|
fullMeetingUrl = `${protocol}//${host}${fullPath}&roomId=${roomId.value}`
|
||||||
|
}
|
||||||
|
|
||||||
console.log('[handleJoinMeeting] 完整会议URL:', fullMeetingUrl)
|
console.log('[handleJoinMeeting] 完整会议URL:', fullMeetingUrl)
|
||||||
|
|
||||||
// 小程序环境:显示提示,引导用户复制链接在浏览器打开
|
// 跳转到会议页面
|
||||||
uni.showModal({
|
uni.navigateTo({
|
||||||
title: '视频会议',
|
url: `/pages/meeting/Meeting?meetingId=${meetingId}&meetingName=${encodeURIComponent(meetingName)}&jitsiIframeUrl=${encodeURIComponent(fullMeetingUrl)}`
|
||||||
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'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
console.error('[handleJoinMeeting] 加入会议失败, isSuccess:', isSuccess, 'data:', meetingData)
|
console.error('[handleJoinMeeting] 加入会议失败, isSuccess:', isSuccess, 'data:', meetingData)
|
||||||
@@ -780,23 +762,120 @@ async function handleCommentSubmit(rating: number) {
|
|||||||
|
|
||||||
// 文件操作相关函数
|
// 文件操作相关函数
|
||||||
|
|
||||||
|
// 显示上传选项
|
||||||
|
function showUploadOptions() {
|
||||||
|
uni.showActionSheet({
|
||||||
|
itemList: ['拍照', '从相册选择', '选择文件'],
|
||||||
|
success: (res) => {
|
||||||
|
switch (res.tapIndex) {
|
||||||
|
case 0:
|
||||||
|
// 拍照
|
||||||
|
chooseImageFromCamera()
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
// 从相册选择
|
||||||
|
chooseImageFromAlbum()
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
// 选择文件
|
// 选择文件
|
||||||
async function chooseFile() {
|
chooseFile()
|
||||||
try {
|
break
|
||||||
const res = await uni.chooseMessageFile({
|
}
|
||||||
count: 9, // 最多选择9个文件
|
}
|
||||||
type: 'file',
|
|
||||||
ext: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt', 'jpg', 'jpeg', 'png', 'gif']
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拍照
|
||||||
|
function chooseImageFromCamera() {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 9,
|
||||||
|
sourceType: ['camera'],
|
||||||
|
success: (res) => {
|
||||||
if (res.tempFiles && res.tempFiles.length > 0) {
|
if (res.tempFiles && res.tempFiles.length > 0) {
|
||||||
// 添加到选中文件列表
|
// 添加到选中文件列表
|
||||||
selectedFiles.value = [...selectedFiles.value, ...res.tempFiles]
|
selectedFiles.value = [...selectedFiles.value, ...res.tempFiles]
|
||||||
}
|
}
|
||||||
} catch (error) {
|
},
|
||||||
console.error('选择文件失败:', error)
|
fail: (err) => {
|
||||||
uni.showToast({ title: '选择文件失败', icon: 'none' })
|
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<string[]> {
|
|||||||
|
|
||||||
isUploading.value = true
|
isUploading.value = true
|
||||||
uni.showLoading({ title: '上传中...' })
|
uni.showLoading({ title: '上传中...' })
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取文件路径数组
|
// 获取文件路径数组
|
||||||
const filePaths = selectedFiles.value.map(file => file.path)
|
const filePaths = selectedFiles.value.map(file => file.path)
|
||||||
|
|||||||
@@ -720,7 +720,8 @@
|
|||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error('SSE错误:', error)
|
console.error('SSE错误:', error)
|
||||||
isTyping.value = false
|
isTyping.value = false
|
||||||
messages.value[messageIndex].content = error
|
// 只返回友好的错误信息,而不是原始错误对象
|
||||||
|
messages.value[messageIndex].content = '抱歉,AI服务暂时不可用,请稍后重试。'
|
||||||
},
|
},
|
||||||
onComplete: () => {
|
onComplete: () => {
|
||||||
isTyping.value = false
|
isTyping.value = false
|
||||||
|
|||||||
@@ -284,27 +284,25 @@ function handleWebViewError(e: any) {
|
|||||||
|
|
||||||
// 复制会议链接
|
// 复制会议链接
|
||||||
function copyUrl() {
|
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' })
|
uni.showToast({ title: '会议链接为空', icon: 'none' })
|
||||||
return
|
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({
|
uni.setClipboardData({
|
||||||
data: fullMeetingUrl,
|
data: fullMeetingUrl,
|
||||||
success: () => {
|
success: () => {
|
||||||
@@ -318,27 +316,25 @@ function copyUrl() {
|
|||||||
|
|
||||||
// 在浏览器中打开
|
// 在浏览器中打开
|
||||||
function openInBrowser() {
|
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' })
|
uni.showToast({ title: '会议链接为空', icon: 'none' })
|
||||||
return
|
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
|
// #ifdef MP-WEIXIN
|
||||||
// 微信小程序:先复制链接,然后提示用户通过右上角菜单在浏览器中打开
|
// 微信小程序:先复制链接,然后提示用户通过右上角菜单在浏览器中打开
|
||||||
uni.setClipboardData({
|
uni.setClipboardData({
|
||||||
|
|||||||
Reference in New Issue
Block a user