jisti-meet服务开启

This commit is contained in:
2025-12-26 18:55:54 +08:00
parent c2b37503fc
commit 0658b82f39
43 changed files with 3979 additions and 1208 deletions

View File

@@ -366,6 +366,11 @@
max-width: 480rpx;
}
// 会议卡片需要更宽的空间
.message-content.meeting-card-wrapper {
max-width: 600rpx;
}
.self-row .message-content {
align-items: flex-end;
}

View File

@@ -64,7 +64,13 @@
</view>
<text class="sender-name">{{ msg.senderName || '客服' }}</text>
</view>
<view class="message-content">
<!-- 会议消息卡片 -->
<view class="message-content meeting-card-wrapper" v-if="msg.messageType === 'meet' && msg.contentExtra">
<MeetingCard :meeting="getMeetingData(msg.contentExtra)" @join="handleJoinMeeting" />
<text class="message-time">{{ formatTime(msg.sendTime) }}</text>
</view>
<!-- 普通消息 -->
<view class="message-content" v-else>
<view class="bubble other-bubble">
<rich-text :nodes="renderMarkdown(msg.content || '')" class="message-rich-text"></rich-text>
</view>
@@ -73,7 +79,13 @@
</view>
<!-- 自己消息(右侧) -->
<view class="message-row self-row" v-else>
<view class="message-content">
<!-- 会议消息卡片 -->
<view class="message-content meeting-card-wrapper" v-if="msg.messageType === 'meet' && msg.contentExtra">
<MeetingCard :meeting="getMeetingData(msg.contentExtra)" @join="handleJoinMeeting" />
<text class="message-time">{{ formatTime(msg.sendTime) }}</text>
</view>
<!-- 普通消息 -->
<view class="message-content" v-else>
<view class="bubble self-bubble">
<text class="message-text">{{ msg.content }}</text>
</view>
@@ -107,7 +119,8 @@
<script setup lang="ts">
import { ref, reactive, computed, nextTick, onMounted, onUnmounted, watch } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import type { ChatRoomMessageVO, CustomerVO, ChatMemberVO, TbChatRoomMessageDTO } from '@/types/workcase'
import MeetingCard from '../../meeting/meetingCard/MeetingCard.uvue'
import type { ChatRoomMessageVO, CustomerVO, ChatMemberVO, TbChatRoomMessageDTO, VideoMeetingVO } from '@/types/workcase'
import { workcaseChatAPI } from '@/api/workcase'
import { wsClient } from '@/utils/websocket'
import { WS_HOST } from '@/config'
@@ -396,6 +409,14 @@ function formatTime(time?: string): string {
return `${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
}
// 获取会议数据将contentExtra转换为VideoMeetingVO
function getMeetingData(contentExtra: Record<string, any> | undefined): VideoMeetingVO {
if (!contentExtra) {
return {} as VideoMeetingVO
}
return contentExtra as VideoMeetingVO
}
// Markdown渲染函数返回富文本HTML
function renderMarkdown(text: string): string {
if (!text) return ''
@@ -531,43 +552,65 @@ function handleWorkcaseAction() {
}
}
// 发起会议
// 发起会议 - 跳转到会议创建页面
async function startMeeting() {
// 先检查是否有活跃会议
try {
uni.showLoading({ title: '创建会议中...' })
// 调用后端API创建会议
const res = await workcaseChatAPI.createVideoMeeting({
roomId: roomId.value,
workcaseId: workcaseId.value,
meetingName: `工单 ${workcaseId.value || roomId.value} 技术支持`,
maxParticipants: 10
})
uni.hideLoading()
const res = await workcaseChatAPI.getActiveMeeting(roomId.value)
if (res.success && res.data) {
// 已有活跃会议,直接加入
const meetingUrl = res.data.iframeUrl
const meetingId = res.data.meetingId
// 小程序/App使用webview打开会议
uni.navigateTo({
url: `/pages/meeting/MeetingView/MeetingView?meetingUrl=${encodeURIComponent(meetingUrl)}&meetingId=${meetingId}`,
success: () => {
console.log('[chatRoom] 跳转会议页面成功')
},
url: `/pages/meeting/Meeting?meetingUrl=${encodeURIComponent(meetingUrl)}&meetingId=${meetingId}`,
fail: (err) => {
console.error('[chatRoom] 跳转会议页面失败:', err)
uni.showToast({ title: '打开会议失败', icon: 'none' })
}
})
return
}
} catch (e) {
console.log('[chatRoom] 无活跃会议,跳转创建页面')
}
// 没有活跃会议,跳转到创建会议页面
uni.navigateTo({
url: `/pages/meeting/MeetingCreate?roomId=${roomId.value}&workcaseId=${workcaseId.value || ''}`,
fail: (err) => {
console.error('[chatRoom] 跳转创建会议页面失败:', err)
uni.showToast({ title: '打开创建会议页面失败', icon: 'none' })
}
})
}
// 加入会议从MeetingCard点击加入
async function handleJoinMeeting(meetingId: string) {
try {
// 调用加入会议接口获取iframe URL
const joinRes = await workcaseChatAPI.joinMeeting(meetingId)
if (joinRes.success && joinRes.data?.iframeUrl) {
const meetingUrl = joinRes.data.iframeUrl
// 跳转到会议页面
uni.navigateTo({
url: `/pages/meeting/Meeting?meetingUrl=${encodeURIComponent(meetingUrl)}&meetingId=${meetingId}`,
fail: (err) => {
console.error('[chatRoom] 跳转会议页面失败:', err)
uni.showToast({ title: '打开会议失败', icon: 'none' })
}
})
} else {
uni.showToast({ title: res.message || '创建会议失败', icon: 'none' })
uni.showToast({
title: joinRes.message || '加入会议失败',
icon: 'none'
})
}
} catch (e) {
uni.hideLoading()
console.error('[chatRoom] 创建会议失败:', e)
uni.showToast({ title: '创建会议失败', icon: 'none' })
} catch (error) {
console.error('[chatRoom] 加入会议失败:', error)
uni.showToast({
title: '加入会议失败',
icon: 'none'
})
}
}