视频会议

This commit is contained in:
duoaohui
2026-05-23 09:35:03 +08:00
parent 4c9f462ff1
commit 6347fdd2db
5 changed files with 255 additions and 85 deletions

View File

@@ -21,20 +21,100 @@ import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { saveToken, saveUserInfo } from '@/utils/storage'
import { useUserStore } from '@/store/user'
import { useWebSocketStore } from '@/store/websocket'
import { useChatStore } from '@/store/chat'
import { useContactStore } from '@/store/contact'
import { useGroupStore } from '@/store/group'
import { useNotifyStore } from '@/store/notify'
const statusText = ref('正在登录…')
function safeDecode(value) {
try {
return decodeURIComponent(value)
} catch (e) {
return value
}
}
function readRawQueryParams() {
const result = {}
try {
if (typeof window === 'undefined') return result
const search = String(window.location.search || '').replace(/^\?/, '')
const hash = String(window.location.hash || '')
const hashQuery = hash.indexOf('?') >= 0 ? hash.slice(hash.indexOf('?') + 1) : ''
;[search, hashQuery].forEach(raw => {
if (!raw) return
const params = new URLSearchParams(raw)
params.forEach((value, key) => {
if (result[key] === undefined) {
result[key] = value
}
})
})
} catch (e) {}
return result
}
function readSsoParam(query, key) {
const value = query && query[key] !== undefined ? query[key] : readRawQueryParams()[key]
return value === undefined || value === null ? '' : String(value)
}
function resolveSsoPayload(query) {
const payloadText = readSsoParam(query, 'payload')
if (payloadText) {
return JSON.parse(safeDecode(payloadText))
}
const token = readSsoParam(query, 'token')
const refreshToken = readSsoParam(query, 'refresh_token')
const expiresIn = Number(readSsoParam(query, 'expires_in') || 0)
const userText = readSsoParam(query, 'user')
const user = userText ? JSON.parse(safeDecode(userText)) : null
return { token, refresh_token: refreshToken, expires_in: expiresIn, user }
}
function markCloudLawEmbed() {
try {
if (typeof window === 'undefined') return
window.sessionStorage.setItem('echo_cloud_law_meeting_embed', '1')
} catch (e) {}
}
function bootstrapAfterSso(token) {
// 模拟 App.onLaunch 的初始化路径:先重连 WS顶掉旧 token 连接),再注册各 store 的 ws 监听并拉初始数据
try {
const wsStore = useWebSocketStore()
wsStore.disconnect()
wsStore.connect(token)
} catch (wsErr) {
console.warn('[SSO] WebSocket 重连失败', wsErr)
}
try {
const chatStore = useChatStore()
const contactStore = useContactStore()
const groupStore = useGroupStore()
const notifyStore = useNotifyStore()
chatStore.initWsListeners()
contactStore.initWsListeners()
groupStore.initWsListeners()
notifyStore.initWsListeners()
contactStore.fetchPendingRequests().catch(() => {})
notifyStore.fetchUnreadCount().catch(() => {})
} catch (storeErr) {
console.warn('[SSO] 全局 store 初始化异常', storeErr)
}
}
onLoad((query) => {
try {
if (!query?.payload) {
const payload = resolveSsoPayload(query || {})
if (!payload.token || !payload.user) {
statusText.value = '缺少 payload 参数'
return
}
const payload = JSON.parse(decodeURIComponent(query.payload))
if (!payload.token || !payload.user) {
statusText.value = 'payload 字段不完整'
return
}
markCloudLawEmbed()
// 写入持久化存储
saveToken(payload.token, payload.refresh_token || '', payload.expires_in || 0)
saveUserInfo(payload.user)
@@ -43,7 +123,10 @@ onLoad((query) => {
userStore.token = payload.token
userStore.userInfo = payload.user
const redirect = query.redirect ? decodeURIComponent(query.redirect) : '/pages/meeting/index'
bootstrapAfterSso(payload.token)
const rawRedirect = readSsoParam(query || {}, 'redirect')
const redirect = rawRedirect ? safeDecode(rawRedirect) : '/pages/meeting/index'
statusText.value = '登录成功,跳转中…'
// redirectTo 不保留历史,避免返回到 sso 页造成循环
setTimeout(() => {