视频会议

This commit is contained in:
duoaohui
2026-05-23 12:19:10 +08:00
parent 6347fdd2db
commit 3e6ddb0e02

View File

@@ -75,6 +75,43 @@ function resolveSsoPayload(query) {
return { token, refresh_token: refreshToken, expires_in: expiresIn, user } return { token, refresh_token: refreshToken, expires_in: expiresIn, user }
} }
function decodeJwtPayload(token) {
try {
const parts = String(token || '').split('.')
if (parts.length < 2) return null
let base64 = parts[1].replace(/-/g, '+').replace(/_/g, '/')
while (base64.length % 4) base64 += '='
const binary = atob(base64)
const json = decodeURIComponent(Array.prototype.map.call(binary, c => {
return `%${(`00${c.charCodeAt(0).toString(16)}`).slice(-2)}`
}).join(''))
return JSON.parse(json)
} catch (e) {
return null
}
}
function resolveSsoUser(payload) {
if (payload && payload.user) return payload.user
const claims = decodeJwtPayload(payload && payload.token)
if (!claims || !claims.user_id) return null
const username = claims.username || String(claims.user_id)
return {
id: claims.user_id,
user_id: claims.user_id,
username,
nickname: username,
roles: Array.isArray(claims.roles) ? claims.roles : []
}
}
function resolveRedirect(query) {
const rawRedirect = readSsoParam(query || {}, 'redirect')
const decoded = rawRedirect ? safeDecode(rawRedirect) : '/pages/meeting/index'
const cleaned = String(decoded || '').trim().replace(/^["']+|["']+$/g, '')
return cleaned || '/pages/meeting/index'
}
function markCloudLawEmbed() { function markCloudLawEmbed() {
try { try {
if (typeof window === 'undefined') return if (typeof window === 'undefined') return
@@ -110,23 +147,23 @@ function bootstrapAfterSso(token) {
onLoad((query) => { onLoad((query) => {
try { try {
const payload = resolveSsoPayload(query || {}) const payload = resolveSsoPayload(query || {})
if (!payload.token || !payload.user) { const ssoUser = resolveSsoUser(payload)
if (!payload || !payload.token || !ssoUser) {
statusText.value = '缺少 payload 参数' statusText.value = '缺少 payload 参数'
return return
} }
markCloudLawEmbed() markCloudLawEmbed()
// 写入持久化存储 // 写入持久化存储
saveToken(payload.token, payload.refresh_token || '', payload.expires_in || 0) saveToken(payload.token, payload.refresh_token || '', payload.expires_in || 0)
saveUserInfo(payload.user) saveUserInfo(ssoUser)
// 同步 pinia store // 同步 pinia store
const userStore = useUserStore() const userStore = useUserStore()
userStore.token = payload.token userStore.token = payload.token
userStore.userInfo = payload.user userStore.userInfo = ssoUser
bootstrapAfterSso(payload.token) bootstrapAfterSso(payload.token)
const rawRedirect = readSsoParam(query || {}, 'redirect') const redirect = resolveRedirect(query || {})
const redirect = rawRedirect ? safeDecode(rawRedirect) : '/pages/meeting/index'
statusText.value = '登录成功,跳转中…' statusText.value = '登录成功,跳转中…'
// redirectTo 不保留历史,避免返回到 sso 页造成循环 // redirectTo 不保留历史,避免返回到 sso 页造成循环
setTimeout(() => { setTimeout(() => {