/** * 传感器数据服务 - 使用 executeAs 方式进行类型转换 * 减少UI层的类型转换问题 */ import supa from '@/components/supadb/aksupainstance.uts' import type { AkReqResponse } from '@/uni_modules/ak-req/index.uts' import type { SensorMeasurement, SensorAnalysisResult, DeviceInfo } from './types.uts' // Helper function to create error response factories function createErrorResponseFactory(defaults: T) { return (message: string): AkReqResponse => ({ status: 500, data: defaults, headers: {}, error: new UniError('SenseDataService', -1, message), total: null, page: null, limit: null, hasmore: null, origin: null }); } // 保留原 createErrorResponse 以兼容其它调用(如有) function createErrorResponse(data: T, message: string): AkReqResponse { return createErrorResponseFactory(data)(message); } // 查询参数类型 export type SensorDataParams = { device_id ?: string | null user_id ?: string | null measurement_type ?: string | null start_date ?: string | null end_date ?: string | null limit ?: number | null offset ?: number | null } export type DeviceParams = { user_id ?: string | null device_type ?: string | null status ?: string | null } /** * 传感器数据服务类 */ export class SenseDataService { /** * 获取传感器测量数据列表 */ static async getMeasurements(params : SensorDataParams) : Promise>> { try { let query = supa .from('ss_sensor_measurements') .select('*', {}) .order('measured_at', { ascending: false }) // 添加筛选条件 const deviceId = params.device_id if (deviceId != null) { query = query.eq('device_id', deviceId) } const userId = params.user_id if (userId != null && userId !== '') { query = query.eq('user_id', userId) } const measurementType = params.measurement_type if (measurementType != null) { query = query.eq('measurement_type', measurementType) } const startDate = params.start_date if (startDate != null) { query = query.gte('measured_at', startDate) } const endDate = params.end_date if (endDate != null) { query = query.lte('measured_at', endDate) } // 分页 const limit = params.limit ?? 20 const offset = params.offset ?? 0 console.log(limit, offset) // 先设置 limit,这会自动计算并设置对应的 range query = query.limit(limit) // 如果有 offset,需要重新调整 range if (offset > 0) { query = query.range(offset, offset + limit - 1) } // 如果 limit 为 1,使用 single() 方法优化查询 if (limit == 1) { query = query.single() } const response = await query.executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取传感器数据失败'; const empty: SensorMeasurement = { id: '', device_id: '', user_id: '', measurement_type: '', measured_at: '', unit: '', raw_data: new UTSJSONObject(), created_at: '' }; const errorSensorMeasurement = createErrorResponseFactory(empty); const errorSensorMeasurementArr = createErrorResponseFactory([] as SensorMeasurement[]); if ((params.limit ?? 20) === 1) { return errorSensorMeasurement(errorMsg); } else { return errorSensorMeasurementArr(errorMsg); } } } /** * 获取单条传感器测量数据 */ static async getMeasurementById(id : string) : Promise> { try { const response = await supa .from('ss_sensor_measurements') .select('*', {}) .eq('id', id) .single() .executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取传感器数据详情失败'; const empty: SensorMeasurement = { id: '', device_id: '', user_id: '', measurement_type: '', measured_at: '', unit: '', raw_data: new UTSJSONObject(), created_at: '' }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 获取最新的传感器测量数据(单条记录) */ static async getLatestMeasurement(params : SensorDataParams) : Promise> { try { let query = supa .from('ss_sensor_measurements') .select('*', {}) .order('measured_at', { ascending: false }) // 添加筛选条件 const deviceId = params.device_id if (deviceId != null) { query = query.eq('device_id', deviceId) } const userId = params.user_id if (userId != null) { query = query.eq('user_id', userId) } const measurementType = params.measurement_type if (measurementType != null) { query = query.eq('measurement_type', measurementType) } // 使用 single() 方法获取单条最新记录 const response = await query.single().executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取最新传感器数据失败'; const empty: SensorMeasurement = { id: '', device_id: '', user_id: '', measurement_type: '', measured_at: '', unit: '', raw_data: new UTSJSONObject(), created_at: '' }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 获取设备列表 */ static async getDevices(params : DeviceParams) : Promise>> { try { let query = supa .from('ak_devices') .select('*', {}) .order('bind_time', { ascending: false }) // 添加筛选条件 const userId = params.user_id if (userId != null) { query = query.eq('user_id', userId) } const deviceType = params.device_type if (deviceType != null) { query = query.eq('device_type', deviceType) } const status = params.status if (status != null) { query = query.eq('status', status) } const response = await query.executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取设备列表失败'; return createErrorResponseFactory([] as DeviceInfo[])(errorMsg); } } /** * 获取设备详情 */ static async getDeviceById(id : string) : Promise>> { try { const response = await supa .from('ak_devices') .select('*', {}) .eq('id', id) .single() .executeAs() console.log(response) return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取设备详情失败'; const empty: DeviceInfo = { id: '', user_id: '', device_type: '', device_name: '', device_mac: '', bind_time: '', status: '', extra: new UTSJSONObject() }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 获取分析结果列表 */ static async getAnalysisResults(user_id : string, analysis_type ?: string | null) : Promise>> { try { let query = supa .from('ak_sensor_analysis') .select('*', {}) .eq('user_id', user_id) .order('created_at', { ascending: false }) const analysisType = analysis_type if (analysisType != null) { query = query.eq('analysis_type', analysisType) } const response = await query.executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '获取分析结果失败'; return createErrorResponseFactory([] as SensorAnalysisResult[])(errorMsg); } }/** * 创建传感器测量数据 - 支持单个或批量 */ static async createMeasurement(data : UTSJSONObject | Array) : Promise>> { return await this.insertMeasurementData(data) }/** * 批量创建传感器测量数据(用于模拟器) * @deprecated 使用 createMeasurement 方法,它现在支持批量插入 */ static async createMeasurements(dataList : Array) : Promise>> { const result = await this.createMeasurement(dataList) return result as AkReqResponse> } /** * 绑定设备 */ static async bindDevice(deviceData : UTSJSONObject) : Promise> { try { const data = new UTSJSONObject() // 复制传入的数据 const keys = UTSJSONObject.keys(data) for (let i = 0; i < keys.length; i++) { const key = keys[i] data.set(key, deviceData.get(key)) } data.set('bind_time', new Date().toISOString()) data.set('status', 'online') const response = await supa .from('ak_devices') .insert(data) .select('*', {}) .single() .executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '绑定设备失败'; const empty: DeviceInfo = { id: '', user_id: '', device_type: '', device_name: '', device_mac: '', bind_time: '', status: '', extra: new UTSJSONObject() }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 更新设备状态 */ static async updateDeviceStatus(device_id : string, status : string) : Promise> { try { const response = await supa .from('ak_devices') .update({ status: status }) .eq('id', device_id) .select('*', {}) .single() .executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '更新设备状态失败'; const empty: DeviceInfo = { id: '', user_id: '', device_type: '', device_name: '', device_mac: '', bind_time: '', status: '', extra: new UTSJSONObject() }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 解绑设备 */ static async unbindDevice(device_id : string) : Promise> { try { const response = await supa .from('ak_devices') .delete() .eq('id', device_id) .execute() if (response.error === null) { return { status: 200, data: true, headers: {}, error: null, total: null, page: null, limit: null, hasmore: null, origin: null } } else { return createErrorResponseFactory(false)(response.error?.message ?? '设备解绑失败'); } } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '设备解绑失败'; return createErrorResponseFactory(false)(errorMsg); } } /** * 更新设备信息 */ static async updateDevice(device_id : string, deviceData : UTSJSONObject) : Promise> { try { const response = await supa .from('ak_devices') .update(deviceData) .eq('id', device_id) .select('*', {}) .single() .executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '更新设备信息失败'; const empty: DeviceInfo = { id: '', user_id: '', device_type: '', device_name: '', device_mac: '', bind_time: '', status: '', extra: new UTSJSONObject() }; return createErrorResponseFactory(empty)(errorMsg); } } /** * 统一的插入方法 - 支持单个或批量插入 * @param data 单个对象或对象数组 * @returns 插入结果 */ static async insertMeasurements(data : UTSJSONObject | Array) : Promise>> { try { let processedData : UTSJSONObject | Array let isBatch = false if (Array.isArray(data)) { // 批量插入 isBatch = true const measurementDataList : Array = [] for (let i = 0; i < data.length; i++) { const item = data[i] const measurementData = new UTSJSONObject() // 复制传入的数据 const keys = UTSJSONObject.keys(item) for (let j = 0; j < keys.length; j++) { const key = keys[j] measurementData.set(key, item.get(key)) } measurementData.set('created_at', new Date().toISOString()) measurementDataList.push(measurementData) } processedData = measurementDataList } else { // 单个插入 const measurementData = new UTSJSONObject() // 复制传入的数据 const keys = UTSJSONObject.keys(data) for (let i = 0; i < keys.length; i++) { const key = keys[i] measurementData.set(key, data.get(key)) } measurementData.set('created_at', new Date().toISOString()) processedData = measurementData } let query = supa .from('ss_sensor_measurements') .insert(processedData) .select('*', {}) // 根据是否批量决定是否使用 single() if (!isBatch) { query = query.single() } if (isBatch) { const response = await query.executeAs() return response } else { const response = await query.executeAs() return response } } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? (Array.isArray(data) ? '批量创建传感器数据失败' : '创建传感器数据失败'); const empty: SensorMeasurement = { id: '', device_id: '', user_id: '', measurement_type: '', measured_at: '', unit: '', raw_data: new UTSJSONObject(), created_at: '' }; const errorSensorMeasurement = createErrorResponseFactory(empty); const errorSensorMeasurementArr = createErrorResponseFactory([] as SensorMeasurement[]); if (Array.isArray(data)) { return errorSensorMeasurementArr(errorMsg) as AkReqResponse>; } else { return errorSensorMeasurement(errorMsg) as AkReqResponse>; } } } /** * 传感器测量数据插入方法 - 支持单个或批量插入 * @param data 单个对象或对象数组 * @returns 插入结果 */ static async insertMeasurementData(data : UTSJSONObject | Array) : Promise>> { try { let processedData : UTSJSONObject | Array let isBatch = Array.isArray(data) if (isBatch) { // 批量插入 const dataList : Array = [] const dataArray = data as Array for (let i = 0; i < dataArray.length; i++) { const item = dataArray[i] const processedItem = new UTSJSONObject() // 复制传入的数据 const keys = UTSJSONObject.keys(item) for (let j = 0; j < keys.length; j++) { const key = keys[j] processedItem.set(key, item.get(key)) } processedItem.set('created_at', new Date().toISOString()) dataList.push(processedItem) } processedData = dataList } else { // 单个插入 const singleData = data as UTSJSONObject const processedItem = new UTSJSONObject() // 复制传入的数据 const keys = UTSJSONObject.keys(singleData) for (let i = 0; i < keys.length; i++) { const key = keys[i] processedItem.set(key, singleData.get(key)) } processedItem.set('created_at', new Date().toISOString()) processedData = processedItem } let query = supa .from('ss_sensor_measurements') .insert(processedData) const response = await query.executeAs() return response } catch (error) { const errorMsg = typeof error === 'string' ? error : error?.message ?? '插入传感器数据失败'; return createErrorResponseFactory([] as SensorMeasurement[])(errorMsg) as AkReqResponse>; } } }