QAUP_Management/sql/fix_vehicle_id_mapping.sql
Tian jianyong 5e1e9f4507 统一了前后端到一个项目,实现了无人车的位置和超速检测,并发送到前端。
管理端在 Ruoyi 框架的基础上,对菜单进行了修改,并添加了司机信息、车辆信息和车辆类型管理。
2025-07-08 20:04:14 +08:00

257 lines
9.8 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- ============================================
-- 修复车辆ID映射关系
-- 解决QAUP-Management和CollisionAvoidanceSystem之间的车辆标识符不一致问题
-- 创建时间: 2025-01-15
-- ============================================
-- ============================================
-- 方案一:优化表结构(推荐)
-- 在vehicle_locations表中添加license_plate字段保持vehicle_id作为车牌号
-- ============================================
-- 1. 为vehicle_locations表添加license_plate字段明确语义
ALTER TABLE vehicle_locations ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50);
-- 2. 将现有的vehicle_id数据复制到license_plate字段
UPDATE vehicle_locations SET license_plate = vehicle_id WHERE license_plate IS NULL;
-- 3. 添加索引优化查询性能
CREATE INDEX IF NOT EXISTS idx_vehicle_locations_license_plate ON vehicle_locations(license_plate);
-- 4. 为vehicle_locations表添加数字车辆ID字段可选用于外键关联
ALTER TABLE vehicle_locations ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT;
-- 5. 添加外键约束(可选,确保数据完整性)
-- 注意只有在sys_vehicle_info表中存在对应车牌号的记录时此约束才会生效
-- ALTER TABLE vehicle_locations
-- ADD CONSTRAINT fk_vehicle_locations_sys_vehicle_id
-- FOREIGN KEY (sys_vehicle_id) REFERENCES sys_vehicle_info(vehicle_id);
-- 6. 同样处理vehicle_trajectories表
ALTER TABLE vehicle_trajectories ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50);
UPDATE vehicle_trajectories SET license_plate = vehicle_id WHERE license_plate IS NULL;
CREATE INDEX IF NOT EXISTS idx_vehicle_trajectories_license_plate ON vehicle_trajectories(license_plate);
ALTER TABLE vehicle_trajectories ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT;
-- 7. 处理vehicle_commands表
ALTER TABLE vehicle_commands ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50);
UPDATE vehicle_commands SET license_plate = vehicle_id WHERE license_plate IS NULL;
CREATE INDEX IF NOT EXISTS idx_vehicle_commands_license_plate ON vehicle_commands(license_plate);
ALTER TABLE vehicle_commands ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT;
-- 8. 处理rule_violation_events表
ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS license_plate VARCHAR(50);
UPDATE rule_violation_events SET license_plate = subject_id WHERE license_plate IS NULL AND subject_type = 'VEHICLE';
CREATE INDEX IF NOT EXISTS idx_rule_violations_license_plate ON rule_violation_events(license_plate);
ALTER TABLE rule_violation_events ADD COLUMN IF NOT EXISTS sys_vehicle_id BIGINT;
-- ============================================
-- 更新业务视图 - 使用正确的关联字段
-- ============================================
-- 删除旧的视图
DROP VIEW IF EXISTS vehicle_complete_info;
DROP VIEW IF EXISTS vehicle_status_summary;
-- 重新创建车辆完整信息视图(修正关联逻辑)
CREATE OR REPLACE VIEW vehicle_complete_info AS
SELECT
vi.vehicle_id as sys_vehicle_id,
vi.license_plate_number,
vi.vin_number,
vi.type_id,
vt.type_name,
vi.brand,
vi.owning_unit,
vi.contact_person,
vi.phone_number,
vi.image_url,
vl.location,
vl.altitude,
vl.heading,
vl.speed,
vl.timestamp as last_location_time,
vl.data_quality,
vi.create_time,
vi.update_time
FROM sys_vehicle_info vi
LEFT JOIN sys_vehicle_type vt ON vi.type_id = vt.type_id
LEFT JOIN LATERAL (
SELECT * FROM vehicle_locations
WHERE license_plate = vi.license_plate_number
ORDER BY timestamp DESC
LIMIT 1
) vl ON true;
-- 重新创建车辆实时状态统计视图
CREATE OR REPLACE VIEW vehicle_status_summary AS
SELECT
vehicle_type,
COUNT(*) as total_vehicles,
COUNT(CASE WHEN timestamp > NOW() - INTERVAL '5 minutes' THEN 1 END) as active_vehicles,
COUNT(CASE WHEN timestamp <= NOW() - INTERVAL '5 minutes' THEN 1 END) as inactive_vehicles,
AVG(speed) as avg_speed,
MAX(speed) as max_speed
FROM vehicle_locations vl
WHERE timestamp > NOW() - INTERVAL '24 hours'
GROUP BY vehicle_type;
-- ============================================
-- 创建车牌号关联的便捷视图
-- ============================================
-- 车辆基础信息与最新位置关联视图(通过车牌号)
CREATE OR REPLACE VIEW vehicle_info_with_location AS
SELECT
vi.vehicle_id as sys_vehicle_id,
vi.license_plate_number as vehicle_plate,
vi.brand,
vi.owning_unit,
vt.type_name as vehicle_type_name,
vl.vehicle_type as location_vehicle_type,
vl.location,
ST_X(vl.location) as longitude,
ST_Y(vl.location) as latitude,
vl.altitude,
vl.heading,
vl.speed,
vl.timestamp as last_update_time,
CASE
WHEN vl.timestamp > NOW() - INTERVAL '5 minutes' THEN 'ACTIVE'
WHEN vl.timestamp > NOW() - INTERVAL '30 minutes' THEN 'INACTIVE'
ELSE 'OFFLINE'
END as status
FROM sys_vehicle_info vi
LEFT JOIN sys_vehicle_type vt ON vi.type_id = vt.type_id
LEFT JOIN LATERAL (
SELECT * FROM vehicle_locations
WHERE license_plate = vi.license_plate_number
ORDER BY timestamp DESC
LIMIT 1
) vl ON true;
-- 车辆轨迹查询视图(按车牌号)
CREATE OR REPLACE VIEW vehicle_trajectory_view AS
SELECT
vi.vehicle_id as sys_vehicle_id,
vi.license_plate_number as vehicle_plate,
vi.brand,
vt.trajectory_date,
vt.trajectory_line,
vt.total_distance,
vt.max_speed,
vt.avg_speed,
vt.duration_seconds,
vt.start_time,
vt.end_time
FROM sys_vehicle_info vi
INNER JOIN vehicle_trajectories vt ON vt.license_plate = vi.license_plate_number
LEFT JOIN sys_vehicle_type vtype ON vi.type_id = vtype.type_id;
-- ============================================
-- 创建数据同步函数
-- ============================================
-- 函数根据车牌号更新sys_vehicle_id
CREATE OR REPLACE FUNCTION update_sys_vehicle_id()
RETURNS void AS $$
BEGIN
-- 更新vehicle_locations表
UPDATE vehicle_locations vl
SET sys_vehicle_id = vi.vehicle_id
FROM sys_vehicle_info vi
WHERE vl.license_plate = vi.license_plate_number
AND vl.sys_vehicle_id IS NULL;
-- 更新vehicle_trajectories表
UPDATE vehicle_trajectories vt
SET sys_vehicle_id = vi.vehicle_id
FROM sys_vehicle_info vi
WHERE vt.license_plate = vi.license_plate_number
AND vt.sys_vehicle_id IS NULL;
-- 更新vehicle_commands表
UPDATE vehicle_commands vc
SET sys_vehicle_id = vi.vehicle_id
FROM sys_vehicle_info vi
WHERE vc.license_plate = vi.license_plate_number
AND vc.sys_vehicle_id IS NULL;
-- 更新rule_violation_events表
UPDATE rule_violation_events rve
SET sys_vehicle_id = vi.vehicle_id
FROM sys_vehicle_info vi
WHERE rve.license_plate = vi.license_plate_number
AND rve.sys_vehicle_id IS NULL
AND rve.subject_type = 'VEHICLE';
RAISE NOTICE '车辆ID同步完成';
END;
$$ LANGUAGE plpgsql;
-- 执行一次数据同步
SELECT update_sys_vehicle_id();
-- ============================================
-- 添加注释说明
-- ============================================
COMMENT ON COLUMN vehicle_locations.license_plate IS '车牌号对应sys_vehicle_info.license_plate_number';
COMMENT ON COLUMN vehicle_locations.sys_vehicle_id IS '系统车辆ID对应sys_vehicle_info.vehicle_id';
COMMENT ON COLUMN vehicle_trajectories.license_plate IS '车牌号对应sys_vehicle_info.license_plate_number';
COMMENT ON COLUMN vehicle_trajectories.sys_vehicle_id IS '系统车辆ID对应sys_vehicle_info.vehicle_id';
COMMENT ON COLUMN vehicle_commands.license_plate IS '车牌号对应sys_vehicle_info.license_plate_number';
COMMENT ON COLUMN vehicle_commands.sys_vehicle_id IS '系统车辆ID对应sys_vehicle_info.vehicle_id';
COMMENT ON VIEW vehicle_complete_info IS '车辆完整信息视图,包含基础信息和最新位置,通过车牌号关联';
COMMENT ON VIEW vehicle_info_with_location IS '车辆信息与位置关联视图,提供完整的车辆状态';
COMMENT ON VIEW vehicle_trajectory_view IS '车辆轨迹视图,通过车牌号关联基础信息和轨迹数据';
-- ============================================
-- 验证脚本
-- ============================================
-- 检查表结构更新
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name IN ('vehicle_locations', 'vehicle_trajectories', 'vehicle_commands', 'rule_violation_events')
AND column_name IN ('license_plate', 'sys_vehicle_id')
ORDER BY table_name, column_name;
-- 检查视图创建
SELECT viewname, viewowner
FROM pg_views
WHERE viewname IN ('vehicle_complete_info', 'vehicle_status_summary', 'vehicle_info_with_location', 'vehicle_trajectory_view')
ORDER BY viewname;
-- 检查数据同步结果(示例查询)
SELECT
'vehicle_locations' as table_name,
COUNT(*) as total_records,
COUNT(license_plate) as has_license_plate,
COUNT(sys_vehicle_id) as has_sys_vehicle_id
FROM vehicle_locations
UNION ALL
SELECT
'vehicle_trajectories' as table_name,
COUNT(*) as total_records,
COUNT(license_plate) as has_license_plate,
COUNT(sys_vehicle_id) as has_sys_vehicle_id
FROM vehicle_trajectories;
-- ============================================
-- 完成提示
-- ============================================
DO $$
BEGIN
RAISE NOTICE '==============================================';
RAISE NOTICE '车辆ID映射关系修复完成';
RAISE NOTICE '主要改进:';
RAISE NOTICE '1. 添加了license_plate字段明确语义';
RAISE NOTICE '2. 添加了sys_vehicle_id字段支持数字ID关联';
RAISE NOTICE '3. 更新了所有相关视图使用正确的关联逻辑';
RAISE NOTICE '4. 创建了数据同步函数';
RAISE NOTICE '建议在应用代码中使用license_plate字段进行车辆关联';
RAISE NOTICE '==============================================';
END $$;