import supa, { supaReady } from '@/components/supadb/aksupainstance.uts' import type { UserProfile, UserStats } from '@/pages/user/types.uts' import type { DeviceInfo } from '@/pages/sense/types.uts' import { SenseDataService, type DeviceParams } from '@/pages/sense/senseDataService.uts' import { reactive } from 'vue' import { ensureUserProfile } from './sapi.uts' // 设备状态类型 export type DeviceState = { devices : Array currentDevice : DeviceInfo | null isLoading : boolean lastUpdated : number | null } //定义一个大写的State类型 export type State = { globalNum : number userProfile ?: UserProfile isLoggedIn : boolean // 新增字段 deviceState : DeviceState // 新增设备状态 // 如有需要,可增加更多属性 } // 实例化为state export const state = reactive({ globalNum: 0, userProfile: { username: '', email: '' }, isLoggedIn: false, deviceState: { devices: [], currentDevice: null, isLoading: false, lastUpdated: null } as DeviceState } as State) // 定义修改属性值的方法 export const setGlobalNum = (num : number) => { state.globalNum = num } // 新增:设置登录状态的方法 export const setIsLoggedIn = (val : boolean) => { state.isLoggedIn = val } // 定义全局设置用户信息的方法 export const setUserProfile = (profile : UserProfile) => { state.userProfile = profile } // 获取当前用户信息(含补全 profile) export async function getCurrentUser() : Promise { try { await supaReady } catch (_) {} const sessionInfo = supa.getSession() if (sessionInfo.user == null) { state.userProfile = { username: '', email: '' } state.isLoggedIn = false // 未登录 return null } const userId = sessionInfo.user?.getString("id") if (userId == null) { state.userProfile = { username: '', email: '' } state.isLoggedIn = false // 未登录 return null } // 查询 ak_users 表补全 profile const res = await supa.from('ak_users').select('*', {}).eq('id', userId).execute() console.log(res) if (res.status >= 200 && res.status < 300 && (res.data != null)) { let user : UTSJSONObject | null = null; const data = res.data as any; if (Array.isArray(data)) { if (data.length > 0) { user = data[0] as UTSJSONObject; } } else if (data != null) { user = data as UTSJSONObject; } console.log(user) if (user == null) { console.log('用户资料为空,尝试创建基础资料...') // 如果用户资料为空,尝试创建基础用户资料 const sessionUser = sessionInfo.user if (sessionUser != null) { const createdProfile = await ensureUserProfile(sessionUser) if (createdProfile != null) { state.userProfile = createdProfile state.isLoggedIn = true return createdProfile } else { console.error('创建用户资料失败') state.userProfile = { username: '', email: '' } state.isLoggedIn = false return null } } else { console.error('会话用户信息为空') state.userProfile = { username: '', email: '' } state.isLoggedIn = false return null } } console.log(user) // 直接用 getString/getNumber,无需兜底属性 const profile : UserProfile = { id: user.getString('id'), username: user.getString('username') ?? "", email: user.getString('email') ?? "", gender: user.getString('gender'), birthday: user.getString('birthday'), height_cm: user.getNumber('height_cm'), weight_kg: user.getNumber('weight_kg'), bio: user.getString('bio'), avatar_url: user.getString('avatar_url'), preferred_language: user.getString('preferred_language'), role: user.getString('role'), school_id: user.getString('school_id'), grade_id: user.getString('grade_id'), class_id: user.getString('class_id') } state.userProfile = profile state.isLoggedIn = true // 登录成功 return profile } else { state.userProfile = { username: '', email: '' } state.isLoggedIn = false // 未登录 return null } } // 登出并清空用户信息 export function logout() { supa.signOut() state.userProfile = { username: '', email: '' } state.isLoggedIn = false // 登出 } // 获取当前用户ID(优先级:state.userProfile.id > session > localStorage) export function getCurrentUserId() : string { try { const profile = state.userProfile if (profile != null && profile.id != null) { const profileId = profile.id if (profileId != null) { return profileId } } } catch (e) { } try { const session = supa.getSession() if (session != null) { const curuser = session.user const userId = curuser?.getString('id') if (userId != null) return userId } } catch (e) { } return '' } // 获取当前用户的class_id export function getCurrentUserClassId() : string | null { try { const profile = state.userProfile if (profile != null && profile.class_id != null) { return profile.class_id } } catch (e) { console.error('获取用户class_id失败:', e) } return null } // User store API for component compatibility export function getUserStore() { return { getUserId() : string | null { const sessionInfo = supa.getSession() return sessionInfo.user?.getString("id") ?? null }, getUserName() : string | null { return state.userProfile?.username ?? null }, getUserRole() : string | null { // Default role logic - can be enhanced based on your needs const sessionInfo = supa.getSession() if (sessionInfo.user == null) return null // You can add role detection logic here // For now, return a default role return 'teacher' // or determine from user profile/database }, getProfile() : UserProfile | null { return state.userProfile } } } // ========== 设备状态管理方法 ========== /** * 设置设备加载状态 */ export const setDeviceLoading = (loading : boolean) => { state.deviceState.isLoading = loading } /** * 设置设备列表 */ export const setDevices = (devices : Array) => { state.deviceState.devices = devices state.deviceState.lastUpdated = Date.now() } /** * 添加设备到列表 */ export const addDevice = (device : DeviceInfo) => { const existingIndex = state.deviceState.devices.findIndex(d => d.id === device.id) if (existingIndex >= 0) { // 更新现有设备 state.deviceState.devices[existingIndex] = device } else { // 添加新设备 state.deviceState.devices.push(device) } state.deviceState.lastUpdated = Date.now() } /** * 从列表中移除设备 */ export const removeDevice = (deviceId : string) => { const index = state.deviceState.devices.findIndex(d => d.id === deviceId) if (index >= 0) { state.deviceState.devices.splice(index, 1) // 如果移除的是当前设备,清空当前设备 if (state.deviceState.currentDevice?.id === deviceId) { state.deviceState.currentDevice = null } state.deviceState.lastUpdated = Date.now() } } /** * 更新设备信息 */ export const updateDevice = (device : DeviceInfo) => { const index = state.deviceState.devices.findIndex(d => d.id === device.id) if (index >= 0) { state.deviceState.devices[index] = device // 如果更新的是当前设备,也更新当前设备 if (state.deviceState.currentDevice?.id === device.id) { state.deviceState.currentDevice = device } state.deviceState.lastUpdated = Date.now() } } /** * 设置当前选中的设备 */ export const setCurrentDevice = (device : DeviceInfo | null) => { state.deviceState.currentDevice = device } /** * 根据设备ID获取设备信息 */ export const getDeviceById = (deviceId : string) : DeviceInfo | null => { return state.deviceState.devices.find(d => d.id === deviceId) ?? null } /** * 获取在线设备列表 */ export const getOnlineDevices = () : Array => { return state.deviceState.devices.filter(d => d.status === 'online') } /** * 从服务器加载设备列表 */ export const loadDevices = async (forceRefresh : boolean) : Promise => { const userId = getCurrentUserId() if (userId == null || userId === '') { console.log('用户未登录,无法加载设备列表') return false } // 如果不是强制刷新且数据较新(5分钟内),直接返回 const now = Date.now() const lastUpdated = state.deviceState.lastUpdated if (forceRefresh == false && lastUpdated != null && (now - lastUpdated < 5 * 60 * 1000)) { console.log('设备数据较新,跳过刷新') return true } setDeviceLoading(true) try { const result = await SenseDataService.getDevices({ user_id: userId }) if (result.error === null && result.data != null) { const devices = result.data as Array setDevices(devices) console.log(`加载设备列表成功,共${devices.length}个设备`) return true } else { console.log('加载设备列表失败:', result.error?.message ?? '未知错误') return false } } catch (error) { console.log('加载设备列表异常:', error) return false } finally { setDeviceLoading(false) } } /** * 从服务器加载设备列表 - 带默认参数的重载版本 */ export const loadDevicesWithDefault = async () : Promise => { return await loadDevices(false) } /** * 绑定新设备 */ export const bindNewDevice = async (deviceData : UTSJSONObject) : Promise => { const userId = getCurrentUserId() if (userId == null) { console.log('用户未登录,无法绑定设备') return false } // 确保设备数据中包含用户ID deviceData.set('user_id', userId) try { const result = await SenseDataService.bindDevice(deviceData) if (result.error === null && result.data != null) { // 添加到本地状态 addDevice(result.data as DeviceInfo) const deviceName = (result.data as DeviceInfo).device_name ?? '未知设备' console.log('设备绑定成功:', deviceName) return true } else { console.log('设备绑定失败:', result.error?.message ?? '未知错误') return false } } catch (error) { console.log('设备绑定异常:', error) return false } } /** * 解绑设备 */ export const unbindDevice = async (deviceId : string) : Promise => { try { const result = await SenseDataService.unbindDevice(deviceId) if (result.error === null) { // 从本地状态中移除 removeDevice(deviceId) console.log('设备解绑成功') return true } else { console.log('设备解绑失败:', result.error?.message ?? '未知错误') return false } } catch (error) { console.log('设备解绑异常:', error) return false } } /** * 更新设备配置 */ export const updateDeviceConfig = async (deviceId : string, configData : UTSJSONObject) : Promise => { try { const result = await SenseDataService.updateDevice(deviceId, configData) if (result.error === null && result.data != null) { // 更新本地状态 updateDevice(result.data as DeviceInfo) console.log('设备配置更新成功') return true } else { console.log('设备配置更新失败:', result.error?.message ?? '未知错误') return false } } catch (error) { console.log('设备配置更新异常:', error) return false } } // ========== 设备管理 API ========== /** * 获取设备管理相关的API */ export function getDeviceStore() { return { // 获取设备状态 getDevices() : Array { return state.deviceState.devices }, getCurrentDevice() : DeviceInfo | null { return state.deviceState.currentDevice }, isLoading() : boolean { return state.deviceState.isLoading }, getLastUpdated() : number | null { return state.deviceState.lastUpdated }, // 设备操作方法 async loadDevices(forceRefresh : boolean) : Promise { return await loadDevices(forceRefresh) }, async refreshDevices() : Promise { return await loadDevicesWithDefault() }, async bindDevice(deviceData : UTSJSONObject) : Promise { return await bindNewDevice(deviceData) }, async unbindDevice(deviceId : string) : Promise { return await unbindDevice(deviceId) }, async updateDevice(deviceId : string, configData : UTSJSONObject) : Promise { return await updateDeviceConfig(deviceId, configData) }, // 设备查询方法 getDeviceById(deviceId : string) : DeviceInfo | null { return getDeviceById(deviceId) }, getOnlineDevices() : Array { return getOnlineDevices() }, // 设备选择 setCurrentDevice(device : DeviceInfo | null) { setCurrentDevice(device) } } }