Files
akmon/doc_zhipao/wearable_devices_extension.sql
2026-01-20 08:04:15 +08:00

372 lines
14 KiB
PL/PgSQL

-- 可穿戴设备管理扩展表和数据
-- 扩展现有的 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;
$$;