-- ============================================= -- 智慧水务管理系统 - Issue #28: MQTT协议适配器 + 设备注册/发现API -- 版本: V28 -- ============================================= -- 更新 iot_device 表结构以匹配新的 Device 实体 -- 添加 JSON 位置字段和 WKT 几何字段,保留原有字段用于兼容性 -- 添加新的字段来统一设备模型 ALTER TABLE iot_device ADD COLUMN IF NOT EXISTS position JSONB, ADD COLUMN IF NOT EXISTS geom GEOMETRY(Point, 4326), ADD COLUMN IF NOT EXISTS remark TEXT; -- 更新现有字段的备注 COMMENT ON COLUMN iot_device.position IS '设备位置信息 (JSON格式: {lng, lat, address})'; COMMENT ON COLUMN iot_device.geom IS '设备几何位置 (WKT格式)'; COMMENT ON COLUMN iot_device.remark IS '设备备注信息'; -- 如果 position 和 geom 为空,从原有字段迁移数据 -- 注意:这是一个可选的迁移步骤,根据实际需求决定是否执行 -- UPDATE iot_device -- SET position = json_build_object('lng', loc_lng, 'lat', loc_lat, 'address', address) -- WHERE loc_lng IS NOT NULL OR loc_lat IS NOT NULL; -- 添加索引 CREATE INDEX IF NOT EXISTS idx_iot_device_position ON iot_device USING GIST(geom); CREATE INDEX IF NOT EXISTS idx_iot_device_area ON iot_device(area); CREATE INDEX IF NOT EXISTS idx_iot_device_type ON iot_device(device_type); CREATE INDEX IF NOT EXISTS idx_iot_device_status ON iot_device(status); -- 创建设备状态变更触发器函数 CREATE OR REPLACE FUNCTION iot_device_update_status() RETURNS TRIGGER AS $$ BEGIN IF NEW.status <> OLD.status THEN -- 记录设备状态变更事件 INSERT INTO iot_device_event (device_id, device_sn, event_type, event_data) VALUES (NEW.id, NEW.device_sn, NEW.status, json_build_object('old_status', OLD.status)); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- 创建设备状态变更触发器 CREATE TRIGGER tr_iot_device_status_change BEFORE UPDATE ON iot_device FOR EACH ROW WHEN (NEW.status <> OLD.status) EXECUTE FUNCTION iot_device_update_status(); -- 插入示例数据 INSERT INTO iot_device (device_sn, device_name, device_type, area, position, geom, status, remark) VALUES ('SN001', '流量计-1号', 'flow_meter', '东部片区', '{"lng": 116.1234, "lat": 39.5678, "address": "水厂主入口"}', ST_GeomFromText('POINT(116.1234 39.5678)', 4326), 'online', '主要流量监测设备'), ('SN002', '压力传感器-1号', 'pressure_sensor', '西部片区', '{"lng": 116.5678, "lat": 39.8765, "address": "调压站入口"}', ST_GeomFromText('POINT(116.5678 39.8765)', 4326), 'offline', '备用压力监测设备') ON CONFLICT (device_sn) DO NOTHING;