100 lines
3.0 KiB
Vue
100 lines
3.0 KiB
Vue
<script>
|
||
/**
|
||
* 应用入口
|
||
*
|
||
* 全局生命周期:
|
||
* - onLaunch: 初始化 WebSocket 连接(如果用户已登录)和事件监听
|
||
* - onShow: 检查 WebSocket 连接状态并恢复
|
||
*/
|
||
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'
|
||
|
||
function _isSsoLaunch(options) {
|
||
// 来自外部系统 SSO 桥接:onLaunch 阶段不应使用 localStorage 旧 token 调任何接口,
|
||
// 避免触发 request.js 401 → reLaunch 到登录页。SSO 页 onLoad 完成 token 写入后再统一初始化。
|
||
if (!options) return false
|
||
const path = String(options.path || '')
|
||
const url = String(options.query && options.query.path ? options.query.path : '')
|
||
if (path.indexOf('pages/auth/sso') >= 0 || url.indexOf('pages/auth/sso') >= 0) return true
|
||
// #ifdef H5
|
||
try {
|
||
const hash = String(window.location?.hash || '')
|
||
const search = String(window.location?.search || '')
|
||
return hash.indexOf('/pages/auth/sso') >= 0
|
||
|| search.indexOf('pages/auth/sso') >= 0
|
||
|| search.indexOf('cloudLawSso=') >= 0
|
||
} catch (e) {
|
||
return false
|
||
}
|
||
// #endif
|
||
return false
|
||
}
|
||
|
||
export default {
|
||
onLaunch(options) {
|
||
console.log('App Launch', options)
|
||
if (_isSsoLaunch(options)) {
|
||
console.log('[App] launched via SSO, defer global init until token refresh')
|
||
return
|
||
}
|
||
this._initGlobalWS()
|
||
},
|
||
onShow() {
|
||
console.log('App Show')
|
||
const userStore = useUserStore()
|
||
const wsStore = useWebSocketStore()
|
||
if (userStore.isLoggedIn && !wsStore.isConnected) {
|
||
wsStore.connect()
|
||
}
|
||
},
|
||
onHide() {
|
||
console.log('App Hide')
|
||
},
|
||
methods: {
|
||
_initGlobalWS() {
|
||
const userStore = useUserStore()
|
||
if (!userStore.isLoggedIn) return
|
||
const wsStore = useWebSocketStore()
|
||
wsStore.connect()
|
||
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(() => {})
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
/* 每个页面公共 css */
|
||
|
||
/*
|
||
* 基础全屏容器:防止 uni-app H5 在大窗口下祖先容器尺寸小于视口
|
||
* 导致 position: fixed 元素(如会议房间 .room)"偏左上"。
|
||
* 同时让普通页面在桌面宽屏下仍能把内容区(.page / uni-page-body)
|
||
* 拉伸到视口高度,避免下方出现大片浏览器默认底色。
|
||
*/
|
||
/* #ifdef H5 */
|
||
html, body, #app {
|
||
width: 100%;
|
||
height: 100%;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
uni-app, uni-app > uni-page, uni-page-wrapper, uni-page-body {
|
||
width: 100%;
|
||
min-height: 100%;
|
||
}
|
||
/* #endif */
|
||
</style>
|