Initial commit of akmon project
This commit is contained in:
457
utils/store.uts
Normal file
457
utils/store.uts
Normal file
@@ -0,0 +1,457 @@
|
||||
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<DeviceInfo>
|
||||
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<UserProfile | null> {
|
||||
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<DeviceInfo>) => {
|
||||
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<DeviceInfo> => {
|
||||
return state.deviceState.devices.filter(d => d.status === 'online')
|
||||
}
|
||||
|
||||
/**
|
||||
* 从服务器加载设备列表
|
||||
*/
|
||||
export const loadDevices = async (forceRefresh : boolean) : Promise<boolean> => {
|
||||
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<DeviceInfo>
|
||||
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<boolean> => {
|
||||
return await loadDevices(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定新设备
|
||||
*/
|
||||
export const bindNewDevice = async (deviceData : UTSJSONObject) : Promise<boolean> => {
|
||||
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<boolean> => {
|
||||
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<boolean> => {
|
||||
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<DeviceInfo> {
|
||||
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<boolean> {
|
||||
return await loadDevices(forceRefresh)
|
||||
},
|
||||
|
||||
async refreshDevices() : Promise<boolean> {
|
||||
return await loadDevicesWithDefault()
|
||||
},
|
||||
|
||||
async bindDevice(deviceData : UTSJSONObject) : Promise<boolean> {
|
||||
return await bindNewDevice(deviceData)
|
||||
},
|
||||
|
||||
async unbindDevice(deviceId : string) : Promise<boolean> {
|
||||
return await unbindDevice(deviceId)
|
||||
},
|
||||
|
||||
async updateDevice(deviceId : string, configData : UTSJSONObject) : Promise<boolean> {
|
||||
return await updateDeviceConfig(deviceId, configData)
|
||||
},
|
||||
|
||||
// 设备查询方法
|
||||
getDeviceById(deviceId : string) : DeviceInfo | null {
|
||||
return getDeviceById(deviceId)
|
||||
},
|
||||
|
||||
getOnlineDevices() : Array<DeviceInfo> {
|
||||
return getOnlineDevices()
|
||||
},
|
||||
|
||||
// 设备选择
|
||||
setCurrentDevice(device : DeviceInfo | null) {
|
||||
setCurrentDevice(device)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user