https 替换
This commit is contained in:
@@ -188,7 +188,7 @@ const handleUserCommand = (command: string) => {
|
||||
case 'logout':
|
||||
localStorage.clear()
|
||||
ElMessage.success('退出成功')
|
||||
router.push('/login')
|
||||
router.push('/platform/login')
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,18 @@ import { APP_CONFIG } from 'shared/config'
|
||||
// @ts-ignore
|
||||
import { loadRoutesFromStorage } from './dynamicRoute'
|
||||
|
||||
// workcase应用的动态路由会根据layout字段自动添加,不需要预定义Root布局
|
||||
const routes: RouteRecordRaw[] = []
|
||||
// 公开路由(不需要登录认证)
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
path: '/meeting',
|
||||
name: 'Meeting',
|
||||
component: () => import('@/views/public/JitsiMeeting/JitsiMeetingView.vue'),
|
||||
meta: {
|
||||
title: '视频会议',
|
||||
requiresAuth: false // 不需要登录认证,允许通过token访问
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory('/workcase'), // 与nginx保持一致,使用/workcase前缀
|
||||
@@ -34,9 +44,10 @@ router.beforeEach(async (to, from, next) => {
|
||||
// 检查URL参数中是否有token(用于外部链接和小程序访问)
|
||||
const tokenParam = to.query.token as string | undefined
|
||||
|
||||
// 如果URL中有token,但localStorage中没有loginDomain,使用refresh接口验证
|
||||
if (tokenParam && !localStorage.getItem('loginDomain')) {
|
||||
console.log('[Workcase Router] 检测到token参数,尝试验证登录状态...')
|
||||
// 如果URL中有token参数,使用refresh接口验证并刷新登录状态
|
||||
// 这样可以用新token覆盖旧的登录状态(如果有的话)
|
||||
if (tokenParam) {
|
||||
console.log('[Workcase Router] 检测到token参数,尝试验证并刷新登录状态...')
|
||||
try {
|
||||
const response = await fetch('/api/urban-lifeline/auth/refresh', {
|
||||
method: 'POST',
|
||||
@@ -52,12 +63,12 @@ router.beforeEach(async (to, from, next) => {
|
||||
const loginDomain = result.data
|
||||
const newToken = loginDomain.token
|
||||
|
||||
// 保存到localStorage
|
||||
// 保存到localStorage(覆盖旧的登录状态)
|
||||
localStorage.setItem('token', newToken)
|
||||
localStorage.setItem('loginDomain', JSON.stringify(loginDomain))
|
||||
TokenManager.setToken(newToken)
|
||||
|
||||
console.log('[Workcase Router] Token验证成功,登录状态已保存')
|
||||
console.log('[Workcase Router] Token验证成功,登录状态已刷新')
|
||||
} else {
|
||||
console.warn('[Workcase Router] Token验证失败:', result.message)
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import { workcaseChatAPI } from '@/api/workcase'
|
||||
// @ts-ignore
|
||||
import { TokenManager } from 'shared/api'
|
||||
import axios from 'axios'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
@@ -53,45 +52,6 @@ const getMeetingParams = () => {
|
||||
return { meetingId: meetingId.value, roomId: roomId.value, token: tokenParam }
|
||||
}
|
||||
|
||||
// 使用token刷新登录状态
|
||||
const refreshLoginWithToken = async (token: string) => {
|
||||
try {
|
||||
console.log('[JitsiMeetingView] 使用token刷新登录状态...')
|
||||
|
||||
const response = await axios.post(
|
||||
'/api/urban-lifeline/auth/refresh',
|
||||
{},
|
||||
{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
if (response.data?.success && response.data?.data) {
|
||||
const loginDomain = response.data.data
|
||||
const newToken = loginDomain.token
|
||||
|
||||
// 保存到localStorage
|
||||
localStorage.setItem('token', newToken)
|
||||
localStorage.setItem('loginDomain', JSON.stringify(loginDomain))
|
||||
|
||||
// 使用TokenManager设置token
|
||||
TokenManager.setToken(newToken)
|
||||
|
||||
console.log('[JitsiMeetingView] 登录状态刷新成功')
|
||||
return true
|
||||
} else {
|
||||
console.error('[JitsiMeetingView] 刷新登录失败:', response.data?.message)
|
||||
return false
|
||||
}
|
||||
} catch (err: any) {
|
||||
console.error('[JitsiMeetingView] 刷新登录异常:', err)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 加载 Jitsi External API 脚本
|
||||
const loadJitsiScript = (): Promise<void> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -102,7 +62,8 @@ const loadJitsiScript = (): Promise<void> => {
|
||||
}
|
||||
|
||||
const script = document.createElement('script')
|
||||
script.src = 'http://localhost:8280/external_api.js'
|
||||
// 从 Jitsi 子域名加载 External API
|
||||
script.src = 'https://org.xyzh.yslg.jitsi/external_api.js'
|
||||
script.async = true
|
||||
script.onload = () => {
|
||||
console.log('[JitsiMeetingView] Jitsi External API 脚本加载成功')
|
||||
@@ -129,29 +90,27 @@ const initJitsiMeet = async (jitsiServerUrl: string, roomName: string, jwt: stri
|
||||
|
||||
const JitsiMeetExternalAPI = (window as any).JitsiMeetExternalAPI
|
||||
|
||||
// 解析 URL 获取协议和域名
|
||||
// 解析 URL 获取协议和域名(子域名模式,无需路径处理)
|
||||
const urlObj = new URL(jitsiServerUrl)
|
||||
const domain = urlObj.host // 获取 host (localhost:8280)
|
||||
const domain = urlObj.host // org.xyzh.yslg.jitsi
|
||||
const useHttps = urlObj.protocol === 'https:'
|
||||
|
||||
console.log('[JitsiMeetingView] 解析服务器配置:', {
|
||||
domain,
|
||||
protocol: urlObj.protocol,
|
||||
useHttps
|
||||
useHttps,
|
||||
roomName
|
||||
})
|
||||
|
||||
// 配置选项 - 关键!指定是否使用 HTTPS
|
||||
// 👇 替换你原有的 options 全部代码,保留原有逻辑,仅修改配置项
|
||||
// 配置选项 - 子域名模式,直接使用域名和房间名
|
||||
const options: any = {
|
||||
roomName: roomName,
|
||||
roomName: roomName, // 直接使用房间名,无需路径前缀
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
parentNode: jitsiContainer.value,
|
||||
jwt: jwt,
|
||||
// ✅ 修复1:核心!正确的顶层配置项是 useHTTPS(不是 https),强制关闭HTTPS
|
||||
useHTTPS: false,
|
||||
// ✅ 修复2:禁用WebSocket的HTTPS,彻底阻止wss://请求(局域网必加)
|
||||
useWebSocket: false,
|
||||
// 使用 HTTPS 协议
|
||||
https: useHttps,
|
||||
configOverwrite: {
|
||||
startWithAudioMuted: false,
|
||||
startWithVideoMuted: false,
|
||||
@@ -159,13 +118,7 @@ const initJitsiMeet = async (jitsiServerUrl: string, roomName: string, jwt: stri
|
||||
prejoinPageEnabled: false,
|
||||
disableDeepLinking: true,
|
||||
enableChat: true,
|
||||
enableScreenSharing: true,
|
||||
// ✅ 修复3:叠加禁用,彻底阻断API内部的HTTPS强制逻辑(局域网核心)
|
||||
useHTTPS: false,
|
||||
// ✅ 修复4:禁用第三方HTTPS资源请求,避免混合内容报错
|
||||
disableThirdPartyRequests: false,
|
||||
// ✅ 修复5:关闭服务端的HTTPS重定向检测
|
||||
disableHttpsRedirect: true
|
||||
enableScreenSharing: true
|
||||
},
|
||||
interfaceConfigOverwrite: {
|
||||
SHOW_JITSI_WATERMARK: false,
|
||||
@@ -177,7 +130,12 @@ const initJitsiMeet = async (jitsiServerUrl: string, roomName: string, jwt: stri
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[JitsiMeetingView] 创建 JitsiMeetExternalAPI 实例,https=' + useHttps)
|
||||
console.log('[JitsiMeetingView] 创建 JitsiMeetExternalAPI 实例:', {
|
||||
domain,
|
||||
https: useHttps,
|
||||
roomName,
|
||||
预期URL: `${useHttps ? 'https' : 'http'}://${domain}/${roomName}`
|
||||
})
|
||||
jitsiApi = new JitsiMeetExternalAPI(domain, options)
|
||||
|
||||
// 监听会议准备就绪事件
|
||||
@@ -219,32 +177,13 @@ const joinMeeting = async () => {
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否有loginDomain
|
||||
const hasLoginDomain = !!localStorage.getItem('loginDomain')
|
||||
const hasToken = !!localStorage.getItem('token') || !!token
|
||||
|
||||
console.log('[JitsiMeetingView] 登录状态检查:', {
|
||||
hasLoginDomain,
|
||||
hasToken
|
||||
})
|
||||
|
||||
// 如果没有loginDomain但有token(小程序或外部链接访问),先刷新登录
|
||||
if (!hasLoginDomain && token) {
|
||||
const refreshed = await refreshLoginWithToken(token)
|
||||
if (!refreshed) {
|
||||
error.value = '登录验证失败,请重新获取会议链接'
|
||||
loading.value = false
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查登录状态
|
||||
// 检查登录状态(路由守卫已处理token刷新)
|
||||
if (!TokenManager.hasToken()) {
|
||||
error.value = '未登录,请先登录'
|
||||
loading.value = false
|
||||
// 重定向到登录页
|
||||
const currentUrl = window.location.href
|
||||
window.location.href = `/login?redirect=${encodeURIComponent(currentUrl)}`
|
||||
window.location.href = `/platform/login?redirect=${encodeURIComponent(currentUrl)}`
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user