import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { authApi, statsApi } from '@/api' export const useAppStore = defineStore('app', () => { // 用户状态 const user = ref(JSON.parse(localStorage.getItem('user') || 'null')) const token = ref(localStorage.getItem('token') || '') const isLoggedIn = computed(() => !!token.value) const isAdmin = computed(() => user.value?.role === 'admin') function setUser(userData, tokenStr) { user.value = userData token.value = tokenStr localStorage.setItem('user', JSON.stringify(userData)) localStorage.setItem('token', tokenStr) } function logout() { user.value = null token.value = '' localStorage.removeItem('user') localStorage.removeItem('token') } // 仪表盘统计缓存 const dashboardData = ref(null) const loading = ref(false) async function fetchDashboard() { loading.value = true try { dashboardData.value = await statsApi.getDashboard() } finally { loading.value = false } } // WebSocket 连接 let ws = null function connectWebSocket() { if (ws) return const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:' const wsUrl = `${protocol}//${location.host}/ws` ws = new WebSocket(wsUrl) ws.onopen = () => { console.log('[WS] 已连接') } ws.onmessage = (event) => { try { const data = JSON.parse(event.data) if (data.type === 'device_status_change') { // 触发 dashboard 刷新 fetchDashboard() } } catch (e) { // ignore } } ws.onclose = () => { console.log('[WS] 已断开,3秒后重连') ws = null setTimeout(() => connectWebSocket(), 3000) } // 心跳 setInterval(() => { if (ws?.readyState === WebSocket.OPEN) { ws.send('ping') } }, 30000) } return { user, token, isLoggedIn, isAdmin, setUser, logout, dashboardData, loading, fetchDashboard, connectWebSocket, } })