CREATE TABLE IF NOT EXISTS rocket_configs ( id serial PRIMARY KEY, code varchar(50) NOT NULL UNIQUE, name varchar(100) NOT NULL, name_zh varchar(100), manufacturer varchar(100), country varchar(100), launch_site_name varchar(120) NOT NULL DEFAULT 'Equatorial Launch Site', launch_latitude_deg double precision NOT NULL DEFAULT 0 CHECK (launch_latitude_deg BETWEEN -90 AND 90), launch_longitude_deg double precision NOT NULL DEFAULT 0 CHECK (launch_longitude_deg BETWEEN -180 AND 180), description text, color varchar(20) NOT NULL DEFAULT '#f8fafc', height_m double precision NOT NULL CHECK (height_m > 0), diameter_m double precision NOT NULL CHECK (diameter_m > 0), payload_mass_kg double precision NOT NULL DEFAULT 0 CHECK (payload_mass_kg >= 0), drag_coefficient double precision NOT NULL DEFAULT 0.4 CHECK (drag_coefficient > 0), reference_area_m2 double precision NOT NULL CHECK (reference_area_m2 > 0), target_orbit_km double precision NOT NULL DEFAULT 200 CHECK (target_orbit_km > 0), target_velocity_mps double precision NOT NULL DEFAULT 7800 CHECK (target_velocity_mps > 0), separation_delay_seconds double precision NOT NULL DEFAULT 2 CHECK (separation_delay_seconds >= 0), second_stage_ignition_delay_seconds double precision NOT NULL DEFAULT 1 CHECK (second_stage_ignition_delay_seconds >= 0), stage_1 jsonb NOT NULL, stage_2 jsonb NOT NULL, is_active boolean NOT NULL DEFAULT true, sort_order integer NOT NULL DEFAULT 0, created_at timestamp DEFAULT now(), updated_at timestamp DEFAULT now() ); ALTER TABLE rocket_configs ADD COLUMN IF NOT EXISTS launch_site_name varchar(120) NOT NULL DEFAULT 'Equatorial Launch Site'; ALTER TABLE rocket_configs ADD COLUMN IF NOT EXISTS launch_latitude_deg double precision NOT NULL DEFAULT 0; ALTER TABLE rocket_configs ADD COLUMN IF NOT EXISTS launch_longitude_deg double precision NOT NULL DEFAULT 0; CREATE INDEX IF NOT EXISTS ix_rocket_configs_code ON rocket_configs (code); CREATE INDEX IF NOT EXISTS ix_rocket_configs_is_active ON rocket_configs (is_active); INSERT INTO rocket_configs ( code, name, name_zh, manufacturer, country, launch_site_name, launch_latitude_deg, launch_longitude_deg, description, color, height_m, diameter_m, payload_mass_kg, drag_coefficient, reference_area_m2, target_orbit_km, target_velocity_mps, separation_delay_seconds, second_stage_ignition_delay_seconds, stage_1, stage_2, is_active, sort_order ) VALUES ( 'falcon-9', 'Falcon 9', '猎鹰9号', 'SpaceX', '美国', 'Cape Canaveral', 28.5623, -80.5774, '两级可重复使用运载火箭,用于近地轨道发射任务模拟。', '#f8fafc', 70, 3.7, 15000, 0.4, 10.75, 200, 7800, 2.2, 1.0, jsonb_build_object('name', '一级推进器', 'dry_mass_kg', 25600, 'fuel_mass_kg', 411000, 'max_thrust_n', 7607000, 'specific_impulse_s', 282, 'engine_count', 9, 'length_ratio', 0.65), jsonb_build_object('name', '二级推进器', 'dry_mass_kg', 4000, 'fuel_mass_kg', 107500, 'max_thrust_n', 981000, 'specific_impulse_s', 348, 'engine_count', 1, 'length_ratio', 0.35), true, 1 ), ( 'long-march-5', 'Long March 5', '长征五号', '中国运载火箭技术研究院', '中国', '文昌航天发射场', 19.6145, 110.951, '中国大型两级液体运载火箭,用于重型载荷与深空任务模拟。', '#e8edf2', 56.97, 5, 18000, 0.42, 19.63, 200, 7800, 2.5, 1.2, jsonb_build_object('name', '芯一级', 'dry_mass_kg', 38000, 'fuel_mass_kg', 175000, 'max_thrust_n', 10600000, 'specific_impulse_s', 310, 'engine_count', 10, 'length_ratio', 0.62), jsonb_build_object('name', '芯二级', 'dry_mass_kg', 12000, 'fuel_mass_kg', 26000, 'max_thrust_n', 768000, 'specific_impulse_s', 442, 'engine_count', 2, 'length_ratio', 0.38), true, 2 ) ON CONFLICT (code) DO NOTHING; UPDATE rocket_configs SET launch_site_name = 'Cape Canaveral', launch_latitude_deg = 28.5623, launch_longitude_deg = -80.5774 WHERE code = 'falcon-9' AND launch_site_name = 'Equatorial Launch Site'; UPDATE rocket_configs SET launch_site_name = '文昌航天发射场', launch_latitude_deg = 19.6145, launch_longitude_deg = 110.951 WHERE code = 'long-march-5' AND launch_site_name = 'Equatorial Launch Site'; INSERT INTO menus ( parent_id, name, title, icon, path, component, sort_order, is_active, description ) SELECT parent.id, 'rocket_configs', '火箭数据管理', 'rocket', '/admin/rockets', 'admin/Rockets', 5, true, '管理火箭发射模拟使用的两级运载火箭数据' FROM menus AS parent WHERE parent.name = 'data_management' AND NOT EXISTS (SELECT 1 FROM menus WHERE name = 'rocket_configs') LIMIT 1; INSERT INTO role_menus (role_id, menu_id) SELECT roles.id, menus.id FROM roles JOIN menus ON menus.name = 'rocket_configs' WHERE roles.name = 'admin' AND NOT EXISTS ( SELECT 1 FROM role_menus WHERE role_menus.role_id = roles.id AND role_menus.menu_id = menus.id );