-- 可穿戴设备管理扩展表和数据 -- 扩展现有的 ak_devices 表,添加可穿戴设备特有的信息 -- 设备类型表 - 定义各种设备类型的详细信息 CREATE TABLE IF NOT EXISTS public.ak_device_types ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), type_code VARCHAR(32) UNIQUE NOT NULL, -- 设备类型代码 type_name VARCHAR(64) NOT NULL, -- 设备类型名称 category VARCHAR(32) NOT NULL, -- 设备分类 (wearable, sensor, scale等) icon VARCHAR(32), -- 图标标识 description TEXT, -- 设备描述 supported_features TEXT[], -- 支持的功能列表 battery_life_hours INT DEFAULT 168, -- 预期电池续航时间(小时) connection_types TEXT[] DEFAULT ARRAY['bluetooth'], -- 连接方式 is_active BOOLEAN DEFAULT true, created_at TIMESTAMP WITH TIME ZONE DEFAULT now() ); COMMENT ON TABLE public.ak_device_types IS '设备类型定义表'; -- 插入可穿戴设备类型数据 INSERT INTO public.ak_device_types (type_code, type_name, category, icon, description, supported_features, battery_life_hours, connection_types) VALUES ('smart_band', '智能手环', 'wearable', '⌚', '轻便的腕戴式健康监测设备', ARRAY['heart_rate', 'steps', 'sleep', 'notifications'], 168, ARRAY['bluetooth']), ('smart_watch', '智能手表', 'wearable', '⌚', '功能丰富的智能穿戴设备', ARRAY['heart_rate', 'steps', 'sleep', 'gps', 'calls', 'apps'], 48, ARRAY['bluetooth', 'wifi']), ('smart_ring', '智能指环', 'wearable', '💍', '极简设计的指戴式健康监测设备', ARRAY['heart_rate', 'sleep', 'temperature'], 240, ARRAY['bluetooth']), ('heart_rate_monitor', '心率监测器', 'sensor', '❤️', '专业的心率监测设备', ARRAY['heart_rate', 'hrv'], 720, ARRAY['bluetooth', 'ant+']), ('fitness_tracker', '健身追踪器', 'wearable', '🏃', '专注运动数据追踪的设备', ARRAY['steps', 'calories', 'distance', 'workout'], 120, ARRAY['bluetooth']), ('smart_scale', '智能体重秤', 'scale', '⚖️', '智能体重和身体成分测量设备', ARRAY['weight', 'body_fat', 'muscle_mass', 'bone_mass'], 8760, ARRAY['bluetooth', 'wifi']), ('blood_pressure_monitor', '血压监测器', 'sensor', '🩺', '血压和脉搏监测设备', ARRAY['blood_pressure', 'pulse'], 720, ARRAY['bluetooth']), ('smart_earbuds', '智能耳机', 'wearable', '🎧', '具备健康监测功能的智能耳机', ARRAY['heart_rate', 'steps', 'music'], 24, ARRAY['bluetooth']), ('posture_monitor', '姿态监测器', 'sensor', '🧘', '姿态和动作分析设备', ARRAY['posture', 'movement', 'vibration_alert'], 240, ARRAY['bluetooth']), ('sleep_monitor', '睡眠监测器', 'sensor', '😴', '专业的睡眠质量监测设备', ARRAY['sleep', 'breathing', 'temperature'], 720, ARRAY['bluetooth']); -- 设备状态历史表 - 记录设备状态变化 CREATE TABLE IF NOT EXISTS public.ak_device_status_history ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), device_id uuid REFERENCES public.ak_devices(id) ON DELETE CASCADE, status VARCHAR(16) NOT NULL, -- active, offline, charging, low_battery, error battery_level INT, -- 电池电量百分比 firmware_version VARCHAR(32), -- 固件版本 last_sync_time TIMESTAMP WITH TIME ZONE, -- 最后同步时间 signal_strength INT, -- 信号强度 (-100 to 0 dBm) extra_data JSONB, -- 其他状态数据 recorded_at TIMESTAMP WITH TIME ZONE DEFAULT now() ); COMMENT ON TABLE public.ak_device_status_history IS '设备状态历史记录表'; CREATE INDEX idx_device_status_history_device_id ON public.ak_device_status_history(device_id); CREATE INDEX idx_device_status_history_recorded_at ON public.ak_device_status_history(recorded_at); -- 设备设置表 - 存储设备的个性化设置 CREATE TABLE IF NOT EXISTS public.ak_device_settings ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), device_id uuid REFERENCES public.ak_devices(id) ON DELETE CASCADE, setting_key VARCHAR(64) NOT NULL, -- 设置项名称 setting_value TEXT, -- 设置值 data_type VARCHAR(16) DEFAULT 'string', -- string, number, boolean, json description TEXT, -- 设置描述 is_user_configurable BOOLEAN DEFAULT true, -- 用户是否可配置 created_at TIMESTAMP WITH TIME ZONE DEFAULT now(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT now() ); COMMENT ON TABLE public.ak_device_settings IS '设备个性化设置表'; CREATE INDEX idx_device_settings_device_id ON public.ak_device_settings(device_id); CREATE UNIQUE INDEX idx_device_settings_unique ON public.ak_device_settings(device_id, setting_key); -- 设备数据同步记录表 CREATE TABLE IF NOT EXISTS public.ak_device_sync_logs ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), device_id uuid REFERENCES public.ak_devices(id) ON DELETE CASCADE, sync_type VARCHAR(32) NOT NULL, -- full, incremental, health_data, settings sync_status VARCHAR(16) NOT NULL, -- started, success, failed, partial records_synced INT DEFAULT 0, -- 同步的记录数 data_size_bytes BIGINT DEFAULT 0, -- 同步的数据大小 start_time TIMESTAMP WITH TIME ZONE DEFAULT now(), end_time TIMESTAMP WITH TIME ZONE, error_message TEXT, -- 错误信息 sync_details JSONB -- 同步详情 ); COMMENT ON TABLE public.ak_device_sync_logs IS '设备数据同步日志表'; CREATE INDEX idx_device_sync_logs_device_id ON public.ak_device_sync_logs(device_id); CREATE INDEX idx_device_sync_logs_start_time ON public.ak_device_sync_logs(start_time); -- 插入一些示例设备设置 INSERT INTO public.ak_device_settings (device_id, setting_key, setting_value, data_type, description, is_user_configurable) SELECT d.id, setting_key, setting_value, data_type, description, is_user_configurable FROM public.ak_devices d CROSS JOIN ( VALUES ('heart_rate_alert_enabled', 'true', 'boolean', '心率异常提醒开关', true), ('heart_rate_alert_threshold', '100', 'number', '心率提醒阈值(bpm)', true), ('step_goal', '10000', 'number', '每日步数目标', true), ('notification_enabled', 'true', 'boolean', '通知推送开关', true), ('auto_sleep_detection', 'true', 'boolean', '自动睡眠检测', true), ('vibration_intensity', 'medium', 'string', '震动强度设置', true), ('display_brightness', '80', 'number', '屏幕亮度百分比', true), ('auto_sync_interval', '30', 'number', '自动同步间隔(分钟)', true), ('sedentary_reminder', 'true', 'boolean', '久坐提醒', true), ('water_reminder_interval', '120', 'number', '喝水提醒间隔(分钟)', true) ) AS settings(setting_key, setting_value, data_type, description, is_user_configurable) WHERE d.device_type IN ('smart_band', 'smart_watch', 'fitness_tracker') ON CONFLICT (device_id, setting_key) DO NOTHING; -- 创建获取设备详细信息的函数 CREATE OR REPLACE FUNCTION get_device_details(p_device_id uuid) RETURNS TABLE ( device_id uuid, device_name VARCHAR(64), device_type VARCHAR(32), device_mac VARCHAR(64), status VARCHAR(16), battery_level INT, last_sync TIMESTAMP WITH TIME ZONE, firmware_version VARCHAR(32), bind_time TIMESTAMP WITH TIME ZONE, type_info JSONB, recent_settings JSONB, sync_stats JSONB ) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT d.id, d.device_name, d.device_type, d.device_mac, d.status, (d.extra->>'battery')::INT as battery_level, (d.extra->>'last_sync')::TIMESTAMP WITH TIME ZONE as last_sync, d.extra->>'firmware_version' as firmware_version, d.bind_time, -- 设备类型信息 CASE WHEN dt.id IS NOT NULL THEN jsonb_build_object( 'type_name', dt.type_name, 'category', dt.category, 'icon', dt.icon, 'description', dt.description, 'supported_features', dt.supported_features, 'battery_life_hours', dt.battery_life_hours, 'connection_types', dt.connection_types ) ELSE NULL END as type_info, -- 最近的设备设置 COALESCE( ( SELECT jsonb_object_agg(ds.setting_key, ds.setting_value) FROM public.ak_device_settings ds WHERE ds.device_id = d.id AND ds.is_user_configurable = true LIMIT 10 ), '{}'::jsonb ) as recent_settings, -- 同步统计 COALESCE( ( SELECT jsonb_build_object( 'total_syncs', COUNT(*), 'successful_syncs', COUNT(*) FILTER (WHERE sync_status = 'success'), 'last_sync_time', MAX(start_time), 'last_sync_status', ( SELECT sync_status FROM public.ak_device_sync_logs dsl2 WHERE dsl2.device_id = d.id ORDER BY start_time DESC LIMIT 1 ) ) FROM public.ak_device_sync_logs dsl WHERE dsl.device_id = d.id AND dsl.start_time >= CURRENT_DATE - INTERVAL '30 days' ), jsonb_build_object('total_syncs', 0, 'successful_syncs', 0) ) as sync_stats FROM public.ak_devices d LEFT JOIN public.ak_device_types dt ON dt.type_code = d.device_type WHERE d.id = p_device_id; END; $$; -- 创建获取用户设备统计的函数 CREATE OR REPLACE FUNCTION get_user_device_stats(p_user_id uuid) RETURNS TABLE ( total_devices INT, active_devices INT, online_devices INT, low_battery_devices INT, device_type_distribution JSONB, recent_activity JSONB ) LANGUAGE plpgsql AS $$ BEGIN RETURN QUERY SELECT COUNT(*)::INT as total_devices, COUNT(*) FILTER (WHERE d.status = 'active')::INT as active_devices, COUNT(*) FILTER ( WHERE d.status = 'active' AND (d.extra->>'last_sync')::TIMESTAMP WITH TIME ZONE > NOW() - INTERVAL '30 minutes' )::INT as online_devices, COUNT(*) FILTER ( WHERE (d.extra->>'battery')::INT < 20 )::INT as low_battery_devices, -- 设备类型分布 COALESCE( jsonb_object_agg( d.device_type, COUNT(*) ) FILTER (WHERE d.device_type IS NOT NULL), '{}'::jsonb ) as device_type_distribution, -- 最近活动 COALESCE( ( SELECT jsonb_build_object( 'recent_syncs', COUNT(*), 'successful_syncs', COUNT(*) FILTER (WHERE sync_status = 'success'), 'last_24h_syncs', COUNT(*) FILTER (WHERE start_time >= NOW() - INTERVAL '24 hours') ) FROM public.ak_device_sync_logs dsl JOIN public.ak_devices dd ON dd.id = dsl.device_id WHERE dd.user_id = p_user_id AND dsl.start_time >= NOW() - INTERVAL '7 days' ), jsonb_build_object('recent_syncs', 0, 'successful_syncs', 0, 'last_24h_syncs', 0) ) as recent_activity FROM public.ak_devices d WHERE d.user_id = p_user_id; END; $$; -- 创建更新设备状态的函数 CREATE OR REPLACE FUNCTION update_device_status( p_device_id uuid, p_status VARCHAR(16), p_battery_level INT DEFAULT NULL, p_firmware_version VARCHAR(32) DEFAULT NULL, p_signal_strength INT DEFAULT NULL, p_extra_data JSONB DEFAULT NULL ) RETURNS BOOLEAN LANGUAGE plpgsql AS $$ DECLARE device_exists BOOLEAN; BEGIN -- 检查设备是否存在 SELECT EXISTS( SELECT 1 FROM public.ak_devices WHERE id = p_device_id ) INTO device_exists; IF NOT device_exists THEN RETURN FALSE; END IF; -- 更新设备表中的状态 UPDATE public.ak_devices SET status = p_status, extra = extra || jsonb_build_object( 'battery', COALESCE(p_battery_level, (extra->>'battery')::INT), 'firmware_version', COALESCE(p_firmware_version, extra->>'firmware_version'), 'last_sync', CURRENT_TIMESTAMP ) WHERE id = p_device_id; -- 记录状态变化历史 INSERT INTO public.ak_device_status_history ( device_id, status, battery_level, firmware_version, last_sync_time, signal_strength, extra_data ) VALUES ( p_device_id, p_status, p_battery_level, p_firmware_version, CURRENT_TIMESTAMP, p_signal_strength, p_extra_data ); RETURN TRUE; END; $$; -- 创建设备数据同步记录函数 CREATE OR REPLACE FUNCTION log_device_sync( p_device_id uuid, p_sync_type VARCHAR(32), p_sync_status VARCHAR(16), p_records_synced INT DEFAULT 0, p_data_size_bytes BIGINT DEFAULT 0, p_error_message TEXT DEFAULT NULL, p_sync_details JSONB DEFAULT NULL ) RETURNS uuid LANGUAGE plpgsql AS $$ DECLARE sync_log_id uuid; BEGIN INSERT INTO public.ak_device_sync_logs ( device_id, sync_type, sync_status, records_synced, data_size_bytes, end_time, error_message, sync_details ) VALUES ( p_device_id, p_sync_type, p_sync_status, p_records_synced, p_data_size_bytes, CASE WHEN p_sync_status IN ('success', 'failed', 'partial') THEN CURRENT_TIMESTAMP ELSE NULL END, p_error_message, p_sync_details ) RETURNING id INTO sync_log_id; RETURN sync_log_id; END; $$; -- 创建清理旧数据的函数 CREATE OR REPLACE FUNCTION cleanup_device_old_data(p_days_to_keep INT DEFAULT 90) RETURNS INT LANGUAGE plpgsql AS $$ DECLARE deleted_count INT; BEGIN -- 清理旧的状态历史记录 DELETE FROM public.ak_device_status_history WHERE recorded_at < CURRENT_DATE - INTERVAL '1 day' * p_days_to_keep; GET DIAGNOSTICS deleted_count = ROW_COUNT; -- 清理旧的同步日志 DELETE FROM public.ak_device_sync_logs WHERE start_time < CURRENT_DATE - INTERVAL '1 day' * p_days_to_keep; RETURN deleted_count; END; $$;