diff --git a/.gitignore b/.gitignore index 0faad47..aae295b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,5 +36,4 @@ build/ #log -log/ logs/ diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index 0cc271a..0316178 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/XNSimHtml/log/log_20250514_201953.log b/XNSimHtml/log/log_20250514_201953.log deleted file mode 100644 index 1d6ae20..0000000 --- a/XNSimHtml/log/log_20250514_201953.log +++ /dev/null @@ -1,12 +0,0 @@ -[2025-05-14 20:19:53.983] [INFO] RT thread bound to CPU 1 -[2025-05-14 20:19:53.992] [INFO] XNEventManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNTimeManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNDDSManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNServiceManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNThreadManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNModelManager Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNFramework Initialize Success! -[2025-05-14 20:19:53.992] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-14 20:19:53.993] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-14 20:19:54.018] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-14 20:19:54.019] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 diff --git a/XNSimHtml/log/log_20250514_202037.log b/XNSimHtml/log/log_20250514_202037.log deleted file mode 100644 index 770ccdf..0000000 --- a/XNSimHtml/log/log_20250514_202037.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-14 20:20:37.727] [INFO] RT thread bound to CPU 1 -[2025-05-14 20:20:37.735] [INFO] XNEventManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNTimeManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNDDSManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNServiceManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNThreadManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNModelManager Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNFramework Initialize Success! -[2025-05-14 20:20:37.735] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-14 20:20:37.735] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-14 20:20:37.761] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-14 20:20:37.762] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:20:38.477] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-14 20:20:38.480] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:20:39.185] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-14 20:20:39.188] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:20:39.916] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-14 20:20:39.917] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-14 20:20:39.917] [INFO] XNEngine Initialize Success! -[2025-05-14 20:20:39.917] [INFO] XNEventManager is prepared! -[2025-05-14 20:20:39.917] [INFO] XNTimeManager is prepared! -[2025-05-14 20:20:39.917] [INFO] XNDDSManager is prepared! -[2025-05-14 20:20:39.917] [INFO] XNServiceManager is prepared! -[2025-05-14 20:20:39.917] [INFO] XNThreadManager is preparing... -[2025-05-14 20:20:39.918] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-14 20:20:39.919] [INFO] Thread: 本体模型组 is prepared! -[2025-05-14 20:20:39.919] [INFO] XNThreadManager is prepared! -[2025-05-14 20:20:39.919] [INFO] XNScenarioManager is prepared! -[2025-05-14 20:20:39.919] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:20:39.920] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-14 20:20:39.920] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-14 20:20:39.923] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-14 20:20:39.923] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:20:39.924] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-14 20:20:39.924] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-14 20:20:39.926] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-14 20:20:39.926] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:20:39.926] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-14 20:20:39.926] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-14 20:20:39.928] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-14 20:20:39.928] [INFO] XNModelManager is prepared! -[2025-05-14 20:20:39.928] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-14 20:20:39.928] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-14 20:20:39.930] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-14 20:20:39.930] [INFO] XNSim Start! -[2025-05-14 20:20:39.930] [INFO] Thread: 本体模型组 Start! -[2025-05-14 20:20:39.930] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250514_203924.log b/XNSimHtml/log/log_20250514_203924.log deleted file mode 100644 index 4fca99a..0000000 --- a/XNSimHtml/log/log_20250514_203924.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-14 20:39:24.457] [INFO] RT thread bound to CPU 1 -[2025-05-14 20:39:24.466] [INFO] XNEventManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNTimeManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNDDSManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNServiceManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNThreadManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNModelManager Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNFramework Initialize Success! -[2025-05-14 20:39:24.466] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-14 20:39:24.467] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-14 20:39:24.492] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-14 20:39:24.492] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:39:25.119] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-14 20:39:25.122] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:39:25.777] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-14 20:39:25.780] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:39:26.353] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-14 20:39:26.354] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-14 20:39:26.354] [INFO] XNEngine Initialize Success! -[2025-05-14 20:39:26.354] [INFO] XNEventManager is prepared! -[2025-05-14 20:39:26.354] [INFO] XNTimeManager is prepared! -[2025-05-14 20:39:26.354] [INFO] XNDDSManager is prepared! -[2025-05-14 20:39:26.354] [INFO] XNServiceManager is prepared! -[2025-05-14 20:39:26.354] [INFO] XNThreadManager is preparing... -[2025-05-14 20:39:26.356] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-14 20:39:26.356] [INFO] Thread: 本体模型组 is prepared! -[2025-05-14 20:39:26.356] [INFO] XNThreadManager is prepared! -[2025-05-14 20:39:26.356] [INFO] XNScenarioManager is prepared! -[2025-05-14 20:39:26.357] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:39:26.358] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-14 20:39:26.358] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-14 20:39:26.362] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-14 20:39:26.363] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:39:26.363] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-14 20:39:26.364] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-14 20:39:26.366] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-14 20:39:26.366] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:39:26.367] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-14 20:39:26.367] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-14 20:39:26.369] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-14 20:39:26.369] [INFO] XNModelManager is prepared! -[2025-05-14 20:39:26.369] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-14 20:39:26.370] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-14 20:39:26.371] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-14 20:39:26.371] [INFO] XNSim Start! -[2025-05-14 20:39:26.372] [INFO] Thread: 本体模型组 Start! -[2025-05-14 20:39:26.372] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250514_204602.log b/XNSimHtml/log/log_20250514_204602.log deleted file mode 100644 index a01720d..0000000 --- a/XNSimHtml/log/log_20250514_204602.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-14 20:46:02.214] [INFO] RT thread bound to CPU 1 -[2025-05-14 20:46:02.223] [INFO] XNEventManager Initialize Success! -[2025-05-14 20:46:02.223] [INFO] XNTimeManager Initialize Success! -[2025-05-14 20:46:02.223] [INFO] XNDDSManager Initialize Success! -[2025-05-14 20:46:02.223] [INFO] XNServiceManager Initialize Success! -[2025-05-14 20:46:02.224] [INFO] XNThreadManager Initialize Success! -[2025-05-14 20:46:02.224] [INFO] XNModelManager Initialize Success! -[2025-05-14 20:46:02.224] [INFO] XNFramework Initialize Success! -[2025-05-14 20:46:02.224] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-14 20:46:02.224] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-14 20:46:02.250] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-14 20:46:02.251] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:46:02.873] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-14 20:46:02.876] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:46:03.663] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-14 20:46:03.666] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-14 20:46:04.291] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-14 20:46:04.291] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-14 20:46:04.291] [INFO] XNEngine Initialize Success! -[2025-05-14 20:46:04.291] [INFO] XNEventManager is prepared! -[2025-05-14 20:46:04.291] [INFO] XNTimeManager is prepared! -[2025-05-14 20:46:04.291] [INFO] XNDDSManager is prepared! -[2025-05-14 20:46:04.291] [INFO] XNServiceManager is prepared! -[2025-05-14 20:46:04.291] [INFO] XNThreadManager is preparing... -[2025-05-14 20:46:04.293] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-14 20:46:04.293] [INFO] Thread: 本体模型组 is prepared! -[2025-05-14 20:46:04.293] [INFO] XNThreadManager is prepared! -[2025-05-14 20:46:04.293] [INFO] XNScenarioManager is prepared! -[2025-05-14 20:46:04.294] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:46:04.294] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-14 20:46:04.295] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-14 20:46:04.300] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-14 20:46:04.301] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:46:04.301] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-14 20:46:04.302] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-14 20:46:04.304] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-14 20:46:04.304] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-14 20:46:04.305] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-14 20:46:04.305] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-14 20:46:04.308] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-14 20:46:04.308] [INFO] XNModelManager is prepared! -[2025-05-14 20:46:04.308] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-14 20:46:04.308] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-14 20:46:04.310] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-14 20:46:04.310] [INFO] XNSim Start! -[2025-05-14 20:46:04.311] [INFO] Thread: 本体模型组 Start! -[2025-05-14 20:46:04.311] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_084119.log b/XNSimHtml/log/log_20250515_084119.log deleted file mode 100644 index 0874b82..0000000 --- a/XNSimHtml/log/log_20250515_084119.log +++ /dev/null @@ -1,12 +0,0 @@ -[2025-05-15 08:41:19.850] [INFO] RT thread bound to CPU 1 -[2025-05-15 08:41:19.859] [INFO] XNEventManager Initialize Success! -[2025-05-15 08:41:19.859] [INFO] XNTimeManager Initialize Success! -[2025-05-15 08:41:19.859] [INFO] XNDDSManager Initialize Success! -[2025-05-15 08:41:19.859] [INFO] XNServiceManager Initialize Success! -[2025-05-15 08:41:19.859] [INFO] XNThreadManager Initialize Success! -[2025-05-15 08:41:19.860] [INFO] XNModelManager Initialize Success! -[2025-05-15 08:41:19.860] [INFO] XNFramework Initialize Success! -[2025-05-15 08:41:19.860] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 08:41:19.860] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 08:41:19.886] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 08:41:19.887] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 diff --git a/XNSimHtml/log/log_20250515_084202.log b/XNSimHtml/log/log_20250515_084202.log deleted file mode 100644 index e4851a0..0000000 --- a/XNSimHtml/log/log_20250515_084202.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-15 08:42:02.270] [INFO] RT thread bound to CPU 1 -[2025-05-15 08:42:02.279] [INFO] XNEventManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNTimeManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNDDSManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNServiceManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNThreadManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNModelManager Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNFramework Initialize Success! -[2025-05-15 08:42:02.279] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 08:42:02.279] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 08:42:02.305] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 08:42:02.305] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 08:42:02.932] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 08:42:02.935] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 08:42:03.637] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 08:42:03.640] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 08:42:04.411] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 08:42:04.411] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 08:42:04.411] [INFO] XNEngine Initialize Success! -[2025-05-15 08:42:04.411] [INFO] XNEventManager is prepared! -[2025-05-15 08:42:04.411] [INFO] XNTimeManager is prepared! -[2025-05-15 08:42:04.411] [INFO] XNDDSManager is prepared! -[2025-05-15 08:42:04.411] [INFO] XNServiceManager is prepared! -[2025-05-15 08:42:04.411] [INFO] XNThreadManager is preparing... -[2025-05-15 08:42:04.413] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 08:42:04.413] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 08:42:04.413] [INFO] XNThreadManager is prepared! -[2025-05-15 08:42:04.413] [INFO] XNScenarioManager is prepared! -[2025-05-15 08:42:04.414] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 08:42:04.415] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 08:42:04.415] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 08:42:04.418] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 08:42:04.418] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 08:42:04.418] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 08:42:04.419] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 08:42:04.420] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 08:42:04.421] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 08:42:04.421] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 08:42:04.421] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 08:42:04.423] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 08:42:04.423] [INFO] XNModelManager is prepared! -[2025-05-15 08:42:04.423] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 08:42:04.423] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 08:42:04.425] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 08:42:04.425] [INFO] XNSim Start! -[2025-05-15 08:42:04.425] [INFO] Thread: 本体模型组 Start! -[2025-05-15 08:42:04.425] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_090739.log b/XNSimHtml/log/log_20250515_090739.log deleted file mode 100644 index e9cb927..0000000 --- a/XNSimHtml/log/log_20250515_090739.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-15 09:07:40.023] [INFO] RT thread bound to CPU 1 -[2025-05-15 09:07:40.032] [INFO] XNEventManager Initialize Success! -[2025-05-15 09:07:40.032] [INFO] XNTimeManager Initialize Success! -[2025-05-15 09:07:40.032] [INFO] XNDDSManager Initialize Success! -[2025-05-15 09:07:40.033] [INFO] XNServiceManager Initialize Success! -[2025-05-15 09:07:40.033] [INFO] XNThreadManager Initialize Success! -[2025-05-15 09:07:40.033] [INFO] XNModelManager Initialize Success! -[2025-05-15 09:07:40.033] [INFO] XNFramework Initialize Success! -[2025-05-15 09:07:40.033] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 09:07:40.033] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 09:07:40.059] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 09:07:40.060] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:07:40.689] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 09:07:40.691] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:07:41.397] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 09:07:41.399] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:07:42.114] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 09:07:42.115] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 09:07:42.115] [INFO] XNEngine Initialize Success! -[2025-05-15 09:07:42.115] [INFO] XNEventManager is prepared! -[2025-05-15 09:07:42.115] [INFO] XNTimeManager is prepared! -[2025-05-15 09:07:42.115] [INFO] XNDDSManager is prepared! -[2025-05-15 09:07:42.115] [INFO] XNServiceManager is prepared! -[2025-05-15 09:07:42.115] [INFO] XNThreadManager is preparing... -[2025-05-15 09:07:42.116] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 09:07:42.116] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 09:07:42.116] [INFO] XNThreadManager is prepared! -[2025-05-15 09:07:42.117] [INFO] XNScenarioManager is prepared! -[2025-05-15 09:07:42.117] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:07:42.118] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 09:07:42.119] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 09:07:42.125] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 09:07:42.125] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:07:42.126] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 09:07:42.126] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 09:07:42.129] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 09:07:42.130] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:07:42.130] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 09:07:42.130] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 09:07:42.132] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 09:07:42.132] [INFO] XNModelManager is prepared! -[2025-05-15 09:07:42.132] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 09:07:42.133] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 09:07:42.135] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 09:07:42.136] [INFO] XNSim Start! -[2025-05-15 09:07:42.136] [INFO] Thread: 本体模型组 Start! -[2025-05-15 09:07:42.136] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_090823.log b/XNSimHtml/log/log_20250515_090823.log deleted file mode 100644 index 06e8b74..0000000 --- a/XNSimHtml/log/log_20250515_090823.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-15 09:08:23.926] [INFO] RT thread bound to CPU 1 -[2025-05-15 09:08:23.935] [INFO] XNEventManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNTimeManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNDDSManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNServiceManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNThreadManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNModelManager Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNFramework Initialize Success! -[2025-05-15 09:08:23.935] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 09:08:23.935] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 09:08:23.962] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 09:08:23.963] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:08:24.605] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 09:08:24.608] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:08:25.334] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 09:08:25.338] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:08:26.025] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 09:08:26.026] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 09:08:26.026] [INFO] XNEngine Initialize Success! -[2025-05-15 09:08:26.026] [INFO] XNEventManager is prepared! -[2025-05-15 09:08:26.026] [INFO] XNTimeManager is prepared! -[2025-05-15 09:08:26.026] [INFO] XNDDSManager is prepared! -[2025-05-15 09:08:26.026] [INFO] XNServiceManager is prepared! -[2025-05-15 09:08:26.026] [INFO] XNThreadManager is preparing... -[2025-05-15 09:08:26.028] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 09:08:26.028] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 09:08:26.028] [INFO] XNThreadManager is prepared! -[2025-05-15 09:08:26.028] [INFO] XNScenarioManager is prepared! -[2025-05-15 09:08:26.028] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:08:26.029] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 09:08:26.030] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 09:08:26.037] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 09:08:26.037] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:08:26.038] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 09:08:26.039] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 09:08:26.042] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 09:08:26.042] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:08:26.043] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 09:08:26.043] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 09:08:26.046] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 09:08:26.046] [INFO] XNModelManager is prepared! -[2025-05-15 09:08:26.046] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 09:08:26.046] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 09:08:26.048] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 09:08:26.048] [INFO] XNSim Start! -[2025-05-15 09:08:26.049] [INFO] Thread: 本体模型组 Start! -[2025-05-15 09:08:26.049] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_091632.log b/XNSimHtml/log/log_20250515_091632.log deleted file mode 100644 index 9848376..0000000 --- a/XNSimHtml/log/log_20250515_091632.log +++ /dev/null @@ -1,47 +0,0 @@ -[2025-05-15 09:16:32.263] [INFO] RT thread bound to CPU 1 -[2025-05-15 09:16:32.271] [INFO] XNEventManager Initialize Success! -[2025-05-15 09:16:32.271] [INFO] XNTimeManager Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNDDSManager Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNServiceManager Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNThreadManager Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNModelManager Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNFramework Initialize Success! -[2025-05-15 09:16:32.272] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 09:16:32.272] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 09:16:32.299] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 09:16:32.300] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:16:32.934] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 09:16:32.936] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:16:33.617] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 09:16:33.620] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 09:16:34.247] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 09:16:34.247] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 09:16:34.247] [INFO] XNEngine Initialize Success! -[2025-05-15 09:16:34.247] [INFO] XNEventManager is prepared! -[2025-05-15 09:16:34.247] [INFO] XNTimeManager is prepared! -[2025-05-15 09:16:34.247] [INFO] XNDDSManager is prepared! -[2025-05-15 09:16:34.247] [INFO] XNServiceManager is prepared! -[2025-05-15 09:16:34.247] [INFO] XNThreadManager is preparing... -[2025-05-15 09:16:34.249] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 09:16:34.249] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 09:16:34.249] [INFO] XNThreadManager is prepared! -[2025-05-15 09:16:34.249] [INFO] XNScenarioManager is prepared! -[2025-05-15 09:16:34.250] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:16:34.250] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 09:16:34.251] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 09:16:34.254] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 09:16:34.254] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:16:34.255] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 09:16:34.255] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 09:16:34.258] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 09:16:34.258] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 09:16:34.258] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 09:16:34.258] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 09:16:34.260] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 09:16:34.260] [INFO] XNModelManager is prepared! -[2025-05-15 09:16:34.260] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 09:16:34.260] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 09:16:34.262] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 09:16:34.262] [INFO] XNSim Start! -[2025-05-15 09:16:34.262] [INFO] Thread: 本体模型组 Start! -[2025-05-15 09:16:34.262] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_101556.log b/XNSimHtml/log/log_20250515_101556.log deleted file mode 100644 index 0e39db2..0000000 --- a/XNSimHtml/log/log_20250515_101556.log +++ /dev/null @@ -1,95 +0,0 @@ -[2025-05-15 10:15:56.638] [INFO] RT thread bound to CPU 1 -[2025-05-15 10:15:56.647] [INFO] XNEventManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNTimeManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNDDSManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNServiceManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNThreadManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNModelManager Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNFramework Initialize Success! -[2025-05-15 10:15:56.647] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 10:15:56.648] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 10:15:56.675] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:56.676] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:15:57.308] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 10:15:57.311] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:15:58.008] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 10:15:58.011] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:15:58.743] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 10:15:58.743] [INFO] Add Thread Success, Frequency: 60 Hz, Interval: 1.66667e+07 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 30 Hz, Interval: 3.33333e+07 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 15 Hz, Interval: 6.66667e+07 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 7.5 Hz, Interval: 1.33333e+08 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 3.75 Hz, Interval: 2.66667e+08 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:15:58.744] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 10:15:58.744] [INFO] XNEngine Initialize Success! -[2025-05-15 10:15:58.744] [INFO] XNEventManager is prepared! -[2025-05-15 10:15:58.745] [INFO] XNTimeManager is prepared! -[2025-05-15 10:15:58.745] [INFO] XNDDSManager is prepared! -[2025-05-15 10:15:58.745] [INFO] XNServiceManager is prepared! -[2025-05-15 10:15:58.745] [INFO] XNThreadManager is preparing... -[2025-05-15 10:15:58.747] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.747] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 10:15:58.747] [INFO] 0x2133 Create Publisher 5001 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.748] [INFO] Thread: 测试线程1 is prepared! -[2025-05-15 10:15:58.748] [INFO] 0x2133 Create Publisher 5002 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.748] [INFO] Thread: 测试线程2 is prepared! -[2025-05-15 10:15:58.749] [INFO] 0x2133 Create Publisher 5003 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.749] [INFO] Thread: 测试线程3 is prepared! -[2025-05-15 10:15:58.749] [INFO] 0x2133 Create Publisher 5004 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.750] [INFO] Thread: 测试线程4 is prepared! -[2025-05-15 10:15:58.750] [INFO] 0x2133 Create Publisher 5005 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.750] [INFO] Thread: 测试线程5 is prepared! -[2025-05-15 10:15:58.751] [INFO] 0x2133 Create Publisher 5006 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.751] [INFO] Thread: 测试线程11 is prepared! -[2025-05-15 10:15:58.751] [INFO] 0x2133 Create Publisher 5007 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.752] [INFO] Thread: 测试线程12 is prepared! -[2025-05-15 10:15:58.752] [INFO] 0x2133 Create Publisher 5008 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.752] [INFO] Thread: 测试线程13 is prepared! -[2025-05-15 10:15:58.753] [INFO] 0x2133 Create Publisher 5009 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.753] [INFO] Thread: 测试线程14 is prepared! -[2025-05-15 10:15:58.754] [INFO] 0x2133 Create Publisher 5010 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.754] [INFO] Thread: 测试线程15 is prepared! -[2025-05-15 10:15:58.754] [INFO] 0x2133 Create Publisher 5011 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.754] [INFO] Thread: 测试线程16 is prepared! -[2025-05-15 10:15:58.755] [INFO] 0x2133 Create Publisher 5012 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:15:58.755] [INFO] Thread: 测试线程17 is prepared! -[2025-05-15 10:15:58.755] [INFO] XNThreadManager is prepared! -[2025-05-15 10:15:58.755] [INFO] XNScenarioManager is prepared! -[2025-05-15 10:15:58.756] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:15:58.756] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 10:15:58.757] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 10:15:58.761] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 10:15:58.762] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:15:58.762] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 10:15:58.763] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 10:15:58.765] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 10:15:58.765] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:15:58.765] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 10:15:58.765] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 10:15:58.767] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 10:15:58.767] [INFO] XNModelManager is prepared! -[2025-05-15 10:15:58.767] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 10:15:58.767] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 10:15:58.769] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 10:15:58.769] [INFO] XNSim Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 本体模型组 Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 测试线程1 Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 测试线程2 Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 测试线程3 Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 测试线程4 Start! -[2025-05-15 10:15:58.770] [INFO] Thread: 测试线程5 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程11 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程12 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程13 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程14 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程15 Start! -[2025-05-15 10:15:58.771] [INFO] Thread: 测试线程16 Start! -[2025-05-15 10:15:58.772] [INFO] Thread: 测试线程17 Start! -[2025-05-15 10:15:58.772] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720001 (object: 20000, local: 1) diff --git a/XNSimHtml/log/log_20250515_104912.log b/XNSimHtml/log/log_20250515_104912.log deleted file mode 100644 index 953ee55..0000000 --- a/XNSimHtml/log/log_20250515_104912.log +++ /dev/null @@ -1,62 +0,0 @@ -[2025-05-15 10:49:12.475] [INFO] RT thread bound to CPU 1 -[2025-05-15 10:49:12.483] [INFO] XNEventManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNTimeManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNDDSManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNServiceManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNThreadManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNModelManager Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNFramework Initialize Success! -[2025-05-15 10:49:12.483] [INFO] XNFramework Analyze Scenario Xml ... -[2025-05-15 10:49:12.483] [INFO] Set engine base run frequency to 120 Hz, interval: 8.33333e+06 ns. -[2025-05-15 10:49:12.510] [INFO] Add Thread Success, Frequency: 120 Hz, Interval: 8.33333e+06 ns. -[2025-05-15 10:49:12.511] [INFO] Model [ 10000] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:49:13.267] [INFO] 0x2163 Model XNAerodynamics loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCAerodynamics_2.0.3.5H_20241106/libSACSCAerodynamics.so successfully! -[2025-05-15 10:49:13.270] [INFO] Model [ 10001] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:49:13.955] [INFO] 0x2163 Model XNGroundHandling loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_SACSCGroundHandling_2.0.27.1H_20241106/libSACSCGroundHandling.so successfully! -[2025-05-15 10:49:13.959] [INFO] Model [ 10002] register periodic function success! Run node: 0-0 Priority: 99 -[2025-05-15 10:49:14.553] [INFO] 0x2163 Model XNWeightBalance loaded algorithm dynamic library /home/jin/MyCode/XNSim/Release/Models/ATA04_WeightBalance_2.0.14.6H_20241106/libSACSCWeightBalance.so successfully! -[2025-05-15 10:49:14.560] [INFO] Model [ 10003] register periodic function success! Run node: 0-0 Priority: 98 -[2025-05-15 10:49:14.560] [INFO] XNFramework Analyze Scenario Xml Success! -[2025-05-15 10:49:14.560] [INFO] XNEngine Initialize Success! -[2025-05-15 10:49:14.560] [INFO] XNEventManager is prepared! -[2025-05-15 10:49:14.560] [INFO] XNTimeManager is prepared! -[2025-05-15 10:49:14.560] [INFO] XNDDSManager is prepared! -[2025-05-15 10:49:14.560] [INFO] XNServiceManager is prepared! -[2025-05-15 10:49:14.560] [INFO] XNThreadManager is preparing... -[2025-05-15 10:49:14.562] [INFO] 0x2133 Create Publisher 5000 for Topic XNSim::XNSimStatus::XNThreadStatus Success! -[2025-05-15 10:49:14.562] [INFO] Thread: 本体模型组 is prepared! -[2025-05-15 10:49:14.562] [INFO] XNThreadManager is prepared! -[2025-05-15 10:49:14.562] [INFO] XNScenarioManager is prepared! -[2025-05-15 10:49:14.563] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:49:14.564] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 10:49:14.564] [INFO] 0x2133 Create Publisher 10000 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 10:49:14.569] [INFO] 0x2137 Create Subscriber 10000 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 10:49:14.570] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:49:14.570] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 10:49:14.571] [INFO] 0x2133 Create Publisher 10001 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 10:49:14.574] [INFO] 0x2137 Create Subscriber 10001 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 10:49:14.574] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:49:14.575] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 10:49:14.575] [INFO] 0x2133 Create Publisher 10002 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 10:49:14.577] [INFO] 0x2137 Create Subscriber 10002 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 10:49:14.577] [INFO] 0x2133 Create Publisher 10003 for Topic XNSim::XNSimStatus::XNModelStatus Success! -[2025-05-15 10:49:14.578] [INFO] 0x2133 Create Publisher 10003 for Topic XNSim::ATA04::Aerodynamics_input Success! -[2025-05-15 10:49:14.578] [INFO] 0x2133 Create Publisher 10003 for Topic XNSim::ATA04::WeightBalance_input Success! -[2025-05-15 10:49:14.578] [INFO] 0x2133 Create Publisher 10003 for Topic XNSim::ATA04::GroundHandling_input Success! -[2025-05-15 10:49:14.580] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::WeightBalance_output Success! -[2025-05-15 10:49:14.582] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::GroundHandling_output Success! -[2025-05-15 10:49:14.584] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::Aerodynamics_output Success! -[2025-05-15 10:49:14.586] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::Aerodynamics_heartbeat Success! -[2025-05-15 10:49:14.587] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::WeightBalance_heartbeat Success! -[2025-05-15 10:49:14.589] [INFO] 0x2137 Create Subscriber 10003 for Topic XNSim::ATA04::GroundHandling_heartbeat Success! -[2025-05-15 10:49:14.589] [INFO] Registered async event handler for event: ATA04AeroInput, handler ID: 655556609 (object: 10003, local: 1) -[2025-05-15 10:49:14.589] [INFO] Registered async event handler for event: ATA04WbInput, handler ID: 655556610 (object: 10003, local: 2) -[2025-05-15 10:49:14.589] [INFO] Registered async event handler for event: ATA04GhInput, handler ID: 655556611 (object: 10003, local: 3) -[2025-05-15 10:49:14.589] [INFO] XNModelManager is prepared! -[2025-05-15 10:49:14.589] [INFO] XNCore is prepared for execute! Simulation will start soon... -[2025-05-15 10:49:14.590] [INFO] 0x2133 Create Publisher 0 for Topic XNSim::XNSimStatus::XNEngineStatus Success! -[2025-05-15 10:49:14.591] [INFO] 0x2137 Create Subscriber 0 for Topic XNSim::XNSimControl::XNRuntimeControl Success! -[2025-05-15 10:49:14.591] [INFO] XNSim Start! -[2025-05-15 10:49:14.592] [INFO] Thread: 本体模型组 Start! -[2025-05-15 10:49:14.592] [INFO] Registered async event handler for event: SendUDPData, handler ID: 1310720004 (object: 20000, local: 4) -[2025-05-15 10:49:14.592] [INFO] Registered async event handler for event: SendTestUDPData, handler ID: 1310785541 (object: 20001, local: 5) diff --git a/XNSimHtml/routes/interface-config.js b/XNSimHtml/routes/interface-config.js index 0c9c966..1630ea5 100644 --- a/XNSimHtml/routes/interface-config.js +++ b/XNSimHtml/routes/interface-config.js @@ -8,11 +8,8 @@ const { addDataInterface, updateDataInterface, deleteDataInterface, - getDataInterfaceStructs, - addDataInterfaceStruct, - updateDataInterfaceStruct, - deleteDataInterfaceStruct -} = require('../utils/db-utils'); + getDataInterfaceStructs +} = require('../utils/data-interface-utils'); const router = express.Router(); const upload = multer({ storage: multer.memoryStorage() }); @@ -30,31 +27,14 @@ async function ensureDataDirectory() { } } -// 读取数据 -async function readData() { - try { - await ensureDataDirectory(); - const data = await fs.readFile(DATA_FILE, 'utf8'); - return JSON.parse(data); - } catch (error) { - if (error.code === 'ENOENT') { - return []; - } - throw error; - } -} - -// 保存数据 -async function saveData(data) { - await ensureDataDirectory(); - await fs.writeFile(DATA_FILE, JSON.stringify(data, null, 2)); -} - // 获取接口列表 router.get('/list', async (req, res) => { try { - const { systemName, productName } = req.query; - const interfaces = await getDataInterfaces(systemName, productName); + const { systemName, confID } = req.query; + if (!confID) { + return res.status(400).json({ error: 'ConfID 是必填字段' }); + } + const interfaces = await getDataInterfaces(systemName, confID); res.json(interfaces); } catch (error) { console.error('获取接口列表失败:', error); @@ -87,8 +67,11 @@ router.put('/update', async (req, res) => { // 删除接口 router.delete('/delete', async (req, res) => { try { - const { systemName, productName, ataName, modelStructName, interfaceName } = req.query; - const result = await deleteDataInterface(systemName, productName, ataName, modelStructName, interfaceName); + const { interfaceName, confID } = req.query; + if (!interfaceName || !confID) { + return res.status(400).json({ error: 'InterfaceName 和 ConfID 是必填字段' }); + } + const result = await deleteDataInterface(interfaceName, confID); res.json(result); } catch (error) { console.error('删除接口失败:', error); @@ -99,8 +82,11 @@ router.delete('/delete', async (req, res) => { // 获取接口结构体列表 router.get('/struct/list', async (req, res) => { try { - const { systemName, productName, ataName } = req.query; - const structs = await getDataInterfaceStructs(systemName, productName, ataName); + const { systemName, planeName, ataName, confID } = req.query; + if (!confID) { + return res.status(400).json({ error: 'ConfID 是必填字段' }); + } + const structs = await getDataInterfaceStructs(systemName, planeName, ataName, confID); res.json(structs); } catch (error) { console.error('获取接口结构体列表失败:', error); @@ -108,72 +94,6 @@ router.get('/struct/list', async (req, res) => { } }); -// 添加接口结构体 -router.post('/struct/add', async (req, res) => { - try { - const result = await addDataInterfaceStruct(req.body); - res.json(result); - } catch (error) { - console.error('添加接口结构体失败:', error); - res.status(500).json({ error: error.message || '添加接口结构体失败' }); - } -}); - -// 更新接口结构体 -router.put('/struct/update', async (req, res) => { - try { - const result = await updateDataInterfaceStruct(req.body); - res.json(result); - } catch (error) { - console.error('更新接口结构体失败:', error); - res.status(500).json({ error: error.message || '更新接口结构体失败' }); - } -}); - -// 删除接口结构体 -router.delete('/struct/delete', async (req, res) => { - try { - const { systemName, productName, ataName, modelStructName } = req.query; - const result = await deleteDataInterfaceStruct(systemName, productName, ataName, modelStructName); - res.json(result); - } catch (error) { - console.error('删除接口结构体失败:', error); - res.status(500).json({ error: error.message || '删除接口结构体失败' }); - } -}); - -// 下载模板 -router.get('/template', async (req, res) => { - try { - const workbook = xlsx.utils.book_new(); - const worksheet = xlsx.utils.json_to_sheet([ - { - '系统名称': 'XNSim', - '产品名称': 'C909', - 'ATA章节': '', - '模型结构名': '', - '接口名': '', - '接口类型': '', - '接口选项': '', - '是否为数组': '', - '数组大小1': '', - '数组大小2': '', - '备注': '' - } - ]); - xlsx.utils.book_append_sheet(workbook, worksheet, '接口变量模板'); - - res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); - res.setHeader('Content-Disposition', 'attachment; filename=接口变量模板.xlsx'); - - const buffer = xlsx.write(workbook, { type: 'buffer', bookType: 'xlsx' }); - res.send(buffer); - } catch (error) { - console.error('下载模板失败:', error); - res.status(500).json({ error: '下载模板失败' }); - } -}); - // 导入数据 router.post('/import', async (req, res) => { try { @@ -188,7 +108,7 @@ router.post('/import', async (req, res) => { // 验证所有必填字段 const requiredFields = [ 'SystemName', - 'ProductName', + 'PlaneName', 'ATAName', 'ModelStructName', 'InterfaceName', @@ -197,7 +117,7 @@ router.post('/import', async (req, res) => { 'InterfaceIsArray', 'InterfaceArraySize_1', 'InterfaceArraySize_2', - 'InterfaceNotes' + 'ConfID' ]; // 检查所有必填字段是否存在 diff --git a/XNSimHtml/routes/model-dev.js b/XNSimHtml/routes/model-dev.js index 1c198d6..f9a810f 100644 --- a/XNSimHtml/routes/model-dev.js +++ b/XNSimHtml/routes/model-dev.js @@ -5,7 +5,7 @@ const { getModelsByChapterId, getModelVersionsByClassName, saveModelVersion -} = require('../utils/db-utils'); +} = require('../utils/model-utils'); // 获取所有ATA章节 router.get('/ata-chapters', (req, res) => { @@ -22,13 +22,13 @@ router.get('/ata-chapters', (req, res) => { router.get('/chapter-models/:chapterId', (req, res) => { try { const { chapterId } = req.params; - const { productName } = req.query; + const { planeName } = req.query; if (!chapterId) { return res.status(400).json({ error: '缺少章节ID参数' }); } - const models = getModelsByChapterId(chapterId, productName); + const models = getModelsByChapterId(chapterId, planeName); res.json(models); } catch (error) { console.error('处理章节模型请求时出错:', error); @@ -40,13 +40,13 @@ router.get('/chapter-models/:chapterId', (req, res) => { router.get('/model-versions/:className', (req, res) => { try { const className = req.params.className; - const { productName } = req.query; + const { planeName } = req.query; if (!className) { return res.status(400).json({ error: '模型类名不能为空' }); } - const versions = getModelVersionsByClassName(className, productName); + const versions = getModelVersionsByClassName(className, planeName); res.json(versions); } catch (error) { console.error(`获取模型版本失败: ${error.message}`); @@ -58,17 +58,17 @@ router.get('/model-versions/:className', (req, res) => { router.post('/model-versions', (req, res) => { try { const versionData = req.body; - const { productName } = req.query; if (!versionData || !versionData.ClassName) { return res.status(400).json({ error: '缺少必要的模型版本数据' }); } - // 如果请求中没有productName,则使用versionData中的ProductName - if (!productName && versionData.ProductName) { - versionData.ProductName = versionData.ProductName; - } else if (productName) { - versionData.ProductName = productName; + // 验证必填字段 + const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'PlaneName', 'ConfID']; + for (const field of requiredFields) { + if (!versionData[field]) { + return res.status(400).json({ error: `${field} 是必填字段` }); + } } const result = saveModelVersion(versionData); diff --git a/XNSimHtml/routes/qa.js b/XNSimHtml/routes/qa.js index 5b27af1..e7a9c68 100644 --- a/XNSimHtml/routes/qa.js +++ b/XNSimHtml/routes/qa.js @@ -6,7 +6,7 @@ const { addAnswer, deleteQuestion, deleteAnswer -} = require('../utils/db-utils'); +} = require('../utils/qa-utils'); // 获取所有问题 router.get('/questions', (req, res) => { diff --git a/XNSimHtml/routes/run-simulation.js b/XNSimHtml/routes/run-simulation.js index c176b77..32de16f 100644 --- a/XNSimHtml/routes/run-simulation.js +++ b/XNSimHtml/routes/run-simulation.js @@ -11,7 +11,7 @@ const { updateXNEngineProcessStatus, deleteXNEngineProcess, getLatestRunningXNEngineProcess -} = require('../utils/db-utils'); +} = require('../utils/xnengine-process-utils'); const { getXNCorePath } = require('../utils/file-utils'); // 存储正在运行的仿真进程 diff --git a/XNSimHtml/routes/service-dev.js b/XNSimHtml/routes/service-dev.js index afb880f..2a8b187 100644 --- a/XNSimHtml/routes/service-dev.js +++ b/XNSimHtml/routes/service-dev.js @@ -5,7 +5,7 @@ const { getServiceVersionsByClassName, saveServiceVersion, createService -} = require('../utils/db-utils'); +} = require('../utils/service-utils'); // 获取所有服务列表 router.get('/services', (req, res) => { diff --git a/XNSimHtml/routes/system-log.js b/XNSimHtml/routes/system-log.js index baef9f1..9b33dd9 100644 --- a/XNSimHtml/routes/system-log.js +++ b/XNSimHtml/routes/system-log.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { getSystemLogs, addSystemLog } = require('../utils/db-utils'); +const { getSystemLogs, addSystemLog } = require('../utils/system-log-utils'); // 获取所有系统日志 router.get('/logs', async (req, res) => { diff --git a/XNSimHtml/routes/todos.js b/XNSimHtml/routes/todos.js index 71147a6..e98daf5 100644 --- a/XNSimHtml/routes/todos.js +++ b/XNSimHtml/routes/todos.js @@ -1,6 +1,6 @@ const express = require('express'); const router = express.Router(); -const { getTodos, addTodo, updateTodoStatus, deleteTodo } = require('../utils/db-utils'); +const { getTodos, addTodo, updateTodoStatus, deleteTodo } = require('../utils/todo-utils'); // 获取所有待办事项 router.get('/', async (req, res) => { diff --git a/XNSimHtml/utils/configuration-utils.js b/XNSimHtml/utils/configuration-utils.js new file mode 100644 index 0000000..7cfb571 --- /dev/null +++ b/XNSimHtml/utils/configuration-utils.js @@ -0,0 +1,187 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取所有配置 +function getConfigurations() { + try { + const db = getDBConnection(true); + + const configs = db.prepare(` + SELECT * FROM Configuration + ORDER BY ConfID ASC + `).all(); + + return configs; + } catch (error) { + console.error('获取配置列表失败:', error); + throw error; + } +} + +// 根据ID获取配置 +function getConfigurationById(confId) { + try { + const db = getDBConnection(true); + + const config = db.prepare(` + SELECT * FROM Configuration + WHERE ConfID = ? + `).get(confId); + + return config; + } catch (error) { + console.error(`获取配置ID ${confId} 失败:`, error); + throw error; + } +} + +// 创建新配置 +function createConfiguration(configData) { + try { + // 验证必填字段 + const requiredFields = ['ConfName', 'WorkPath', 'DomainID']; + for (const field of requiredFields) { + if (!configData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + const result = db.prepare(` + INSERT INTO Configuration ( + PlaneName, ConfName, OSName, OSVersion, RTXVersion, + CPUAffinity, WorkPath, ModelsPath, ServicesPath, + DomainID, ConsoleDebug, ConsoleInfo, ConsoleWarning, + ConsoleError, LogDebug, LogInfo, LogWarning, LogError + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `).run( + configData.PlaneName || 'C909', + configData.ConfName, + configData.OSName || 'Debian 11', + configData.OSVersion || '5.10.0-32-rt-amd64', + configData.RTXVersion || 'preempt-rt', + configData.CPUAffinity || '0,1', + configData.WorkPath, + configData.ModelsPath || 'Models/', + configData.ServicesPath || 'Services/', + configData.DomainID, + configData.ConsoleDebug !== undefined ? configData.ConsoleDebug : 1, + configData.ConsoleInfo !== undefined ? configData.ConsoleInfo : 1, + configData.ConsoleWarning !== undefined ? configData.ConsoleWarning : 1, + configData.ConsoleError !== undefined ? configData.ConsoleError : 1, + configData.LogDebug !== undefined ? configData.LogDebug : 0, + configData.LogInfo !== undefined ? configData.LogInfo : 1, + configData.LogWarning !== undefined ? configData.LogWarning : 1, + configData.LogError !== undefined ? configData.LogError : 1 + ); + + return { + success: true, + confId: result.lastInsertRowid, + message: '配置创建成功' + }; + } catch (error) { + console.error('创建配置失败:', error); + throw error; + } +} + +// 更新配置 +function updateConfiguration(configData) { + try { + // 验证必填字段 + if (!configData.ConfID) { + throw new Error('ConfID 是必填字段'); + } + + const db = getDBConnection(); + + // 检查配置是否存在 + const existingConfig = db.prepare(` + SELECT COUNT(*) as count FROM Configuration + WHERE ConfID = ? + `).get(configData.ConfID); + + if (existingConfig.count === 0) { + throw new Error('要更新的配置不存在'); + } + + const result = db.prepare(` + UPDATE Configuration + SET PlaneName = ?, + ConfName = ?, + OSName = ?, + OSVersion = ?, + RTXVersion = ?, + CPUAffinity = ?, + WorkPath = ?, + ModelsPath = ?, + ServicesPath = ?, + DomainID = ?, + ConsoleDebug = ?, + ConsoleInfo = ?, + ConsoleWarning = ?, + ConsoleError = ?, + LogDebug = ?, + LogInfo = ?, + LogWarning = ?, + LogError = ? + WHERE ConfID = ? + `).run( + configData.PlaneName || 'C909', + configData.ConfName, + configData.OSName || 'Debian 11', + configData.OSVersion || '5.10.0-32-rt-amd64', + configData.RTXVersion || 'preempt-rt', + configData.CPUAffinity || '0,1', + configData.WorkPath, + configData.ModelsPath || 'Models/', + configData.ServicesPath || 'Services/', + configData.DomainID, + configData.ConsoleDebug !== undefined ? configData.ConsoleDebug : 1, + configData.ConsoleInfo !== undefined ? configData.ConsoleInfo : 1, + configData.ConsoleWarning !== undefined ? configData.ConsoleWarning : 1, + configData.ConsoleError !== undefined ? configData.ConsoleError : 1, + configData.LogDebug !== undefined ? configData.LogDebug : 0, + configData.LogInfo !== undefined ? configData.LogInfo : 1, + configData.LogWarning !== undefined ? configData.LogWarning : 1, + configData.LogError !== undefined ? configData.LogError : 1, + configData.ConfID + ); + + return { + success: true, + changes: result.changes, + message: '配置更新成功' + }; + } catch (error) { + console.error('更新配置失败:', error); + throw error; + } +} + +// 删除配置 +function deleteConfiguration(confId) { + try { + const db = getDBConnection(); + + const result = db.prepare('DELETE FROM Configuration WHERE ConfID = ?').run(confId); + + return { + success: true, + changes: result.changes, + message: result.changes > 0 ? '配置删除成功' : '配置不存在或已被删除' + }; + } catch (error) { + console.error('删除配置失败:', error); + throw error; + } +} + +module.exports = { + getConfigurations, + getConfigurationById, + createConfiguration, + updateConfiguration, + deleteConfiguration +}; \ No newline at end of file diff --git a/XNSimHtml/utils/data-interface-utils.js b/XNSimHtml/utils/data-interface-utils.js new file mode 100644 index 0000000..b0eacd0 --- /dev/null +++ b/XNSimHtml/utils/data-interface-utils.js @@ -0,0 +1,280 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取接口列表 +function getDataInterfaces(systemName = 'XNSim', confID) { + try { + if (!confID) { + throw new Error('ConfID 是必填字段'); + } + + const db = getDBConnection(true); + + const tableName = `DataInterface_${confID}`; + + // 查询所有接口 + const query = ` + SELECT SystemName, PlaneName, ATAName, ModelStructName, InterfaceName, + InterfaceType, InterfaceOption, InterfaceIsArray, + InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes + FROM '${tableName}' + WHERE SystemName = ? + ORDER BY PlaneName, ATAName, ModelStructName, InterfaceName + `; + + const interfaces = db.prepare(query).all(systemName); + + return interfaces; + } catch (error) { + console.error('获取接口列表数据失败:', error.message); + throw error; + } +} + +// 添加接口 +function addDataInterface(interfaceData) { + try { + // 验证必填字段 + const requiredFields = [ + 'SystemName', + 'PlaneName', + 'ATAName', + 'ModelStructName', + 'InterfaceName', + 'InterfaceType', + 'InterfaceOption', + 'InterfaceIsArray', + 'InterfaceArraySize_1', + 'InterfaceArraySize_2', + 'ConfID' + ]; + + for (const field of requiredFields) { + if (interfaceData[field] === undefined || interfaceData[field] === null || interfaceData[field] === '') { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + const tableName = `DataInterface_${interfaceData.ConfID}`; + + // 检查接口是否已存在 + const existingInterface = db.prepare(` + SELECT COUNT(*) as count FROM '${tableName}' + WHERE InterfaceName = ? + `).get(interfaceData.InterfaceName); + + if (existingInterface.count > 0) { + throw new Error('接口名称已存在'); + } + + // 插入新接口 + const insertResult = db.prepare(` + INSERT INTO '${tableName}' ( + SystemName, PlaneName, ATAName, ModelStructName, InterfaceName, + InterfaceType, InterfaceOption, InterfaceIsArray, + InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `).run( + interfaceData.SystemName, + interfaceData.PlaneName, + interfaceData.ATAName, + interfaceData.ModelStructName, + interfaceData.InterfaceName, + interfaceData.InterfaceType, + interfaceData.InterfaceOption, + interfaceData.InterfaceIsArray, + interfaceData.InterfaceArraySize_1, + interfaceData.InterfaceArraySize_2, + interfaceData.InterfaceNotes || null + ); + + return { + success: true, + id: insertResult.lastInsertRowid, + message: '接口添加成功' + }; + } catch (error) { + console.error('添加接口失败:', error); + throw error; + } +} + +// 更新接口 +function updateDataInterface(interfaceData) { + try { + // 验证必填字段 + const requiredFields = [ + 'SystemName', + 'PlaneName', + 'ATAName', + 'ModelStructName', + 'InterfaceName', + 'InterfaceType', + 'InterfaceOption', + 'InterfaceIsArray', + 'InterfaceArraySize_1', + 'InterfaceArraySize_2', + 'ConfID' + ]; + + // 检查数据结构 + if (!interfaceData.currentData || !interfaceData.originalData) { + throw new Error('数据格式错误:缺少 currentData 或 originalData'); + } + + // 验证 currentData 中的必填字段 + for (const field of requiredFields) { + if (interfaceData.currentData[field] === undefined || + interfaceData.currentData[field] === null || + interfaceData.currentData[field] === '') { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + const tableName = `DataInterface_${interfaceData.currentData.ConfID}`; + + // 首先检查记录是否存在 + const existingRecord = db.prepare(` + SELECT COUNT(*) as count FROM '${tableName}' + WHERE InterfaceName = ? + `).get(interfaceData.originalData.InterfaceName); + + if (existingRecord.count === 0) { + throw new Error('要更新的记录不存在'); + } + + // 更新接口,包括所有字段 + const updateResult = db.prepare(` + UPDATE '${tableName}' + SET SystemName = ?, + PlaneName = ?, + ATAName = ?, + ModelStructName = ?, + InterfaceName = ?, + InterfaceType = ?, + InterfaceOption = ?, + InterfaceIsArray = ?, + InterfaceArraySize_1 = ?, + InterfaceArraySize_2 = ?, + InterfaceNotes = ? + WHERE InterfaceName = ? + `).run( + interfaceData.currentData.SystemName, + interfaceData.currentData.PlaneName, + interfaceData.currentData.ATAName, + interfaceData.currentData.ModelStructName, + interfaceData.currentData.InterfaceName, + interfaceData.currentData.InterfaceType, + interfaceData.currentData.InterfaceOption, + interfaceData.currentData.InterfaceIsArray, + interfaceData.currentData.InterfaceArraySize_1, + interfaceData.currentData.InterfaceArraySize_2, + interfaceData.currentData.InterfaceNotes || null, + interfaceData.originalData.InterfaceName + ); + + if (updateResult.changes === 0) { + throw new Error('更新失败:没有记录被修改'); + } + + return { + success: true, + changes: updateResult.changes, + message: '接口更新成功' + }; + } catch (error) { + console.error('更新接口失败:', error); + throw error; + } +} + +// 删除接口 +function deleteDataInterface(interfaceName, confID) { + try { + if (!confID) { + throw new Error('ConfID 是必填字段'); + } + + if (!interfaceName) { + throw new Error('InterfaceName 是必填字段'); + } + + const db = getDBConnection(); + + const tableName = `DataInterface_${confID}`; + + // 删除接口 + const deleteResult = db.prepare(` + DELETE FROM '${tableName}' + WHERE InterfaceName = ? + `).run(interfaceName); + + return { + success: true, + changes: deleteResult.changes, + message: '接口删除成功' + }; + } catch (error) { + console.error('删除接口失败:', error); + throw error; + } +} + +// 获取接口结构体列表 +function getDataInterfaceStructs(systemName = 'XNSim', planeName, ataName, confID) { + try { + if (!confID) { + throw new Error('ConfID 是必填字段'); + } + + const db = getDBConnection(true); + + // 根据是否传入 planeName 构建不同的查询 + let query; + let params; + const tableName = `DataInterface_${confID}`; + + if (!planeName || planeName === '') { + query = ` + SELECT SystemName, PlaneName, ATAName, ModelStructName + FROM '${tableName}' + WHERE SystemName = ? + GROUP BY ModelStructName + ORDER BY PlaneName, ATAName, ModelStructName + `; + params = [systemName]; + } else { + query = ` + SELECT SystemName, PlaneName, ATAName, ModelStructName + FROM '${tableName}' + WHERE SystemName = ? AND PlaneName = ? + GROUP BY ModelStructName + ORDER BY ATAName, ModelStructName + `; + params = [systemName, planeName]; + } + + if (ataName) { + query = query.replace('GROUP BY', 'AND ATAName = ? GROUP BY'); + params.push(ataName); + } + + const structs = db.prepare(query).all(...params); + + return structs; + } catch (error) { + console.error('获取接口结构体列表数据失败:', error.message); + throw error; + } +} + +module.exports = { + getDataInterfaces, + addDataInterface, + updateDataInterface, + deleteDataInterface, + getDataInterfaceStructs +}; \ No newline at end of file diff --git a/XNSimHtml/utils/db-utils.js b/XNSimHtml/utils/db-utils.js index 9c413ac..b171fcd 100644 --- a/XNSimHtml/utils/db-utils.js +++ b/XNSimHtml/utils/db-utils.js @@ -1,1404 +1,20 @@ -const Database = require('better-sqlite3'); -const { getXNCorePath } = require('./file-utils'); +const { getDBConnection } = require('./file-utils'); -// 查询ATAChapters表 -function getATAChapters() { +// 查询Plane表中的所有飞机 +function getPlanes() { try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } + const db = getDBConnection(true); - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 直接使用ATAChapters表名查询 - const chapters = db.prepare("SELECT ID, Name, Name_CN FROM 'ATAChapters' ORDER BY ID").all(); - - db.close(); - - return chapters; - } catch (error) { - console.error('获取ATA章节数据失败:', error.message); - throw error; - } -} - -// 根据章节ID查询XNModels表中的模型 -function getModelsByChapterId(chapterId, productName) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 根据productName是否为空构建不同的查询 - let query; - let params; - - if (!productName || productName === '' || productName === 'undefined') { - query = ` - SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName - FROM 'XNModels' - WHERE Chapters_ID = ? - ORDER BY ModelName - `; - params = [chapterId]; - } else { - query = ` - SELECT ProductName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName - FROM 'XNModels' - WHERE Chapters_ID = ? AND ProductName = ? - ORDER BY ModelName - `; - params = [chapterId, productName]; - } - - const models = db.prepare(query).all(...params); - - db.close(); - - return models; - } catch (error) { - console.error(`获取章节${chapterId}的模型数据失败:`, error.message); - throw error; - } -} - -// 根据ClassName查询XNModelsVersion表中的模型版本 -function getModelVersionsByClassName(className, productName) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 根据productName是否为空构建不同的查询 - let query; - let params; - - if (!productName || productName === '') { - query = ` - SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description, - CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, - DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName - FROM 'XNModelsVersion' - WHERE ClassName = ? - ORDER BY Version DESC - `; - params = [className]; - } else { - query = ` - SELECT ProductName, ClassName, Name, Version, CodePath, Author, Description, - CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, - DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName - FROM 'XNModelsVersion' - WHERE ClassName = ? AND ProductName = ? - ORDER BY Version DESC - `; - params = [className, productName]; - } - - const versions = db.prepare(query).all(...params); - - db.close(); - - return versions; - } catch (error) { - console.error(`获取模型${className}的版本数据失败:`, error.message); - throw error; - } -} - -// 保存或更新模型版本信息 -function saveModelVersion(versionData) { - try { - // 验证必填字段 - const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'ProductName']; - for (const field of requiredFields) { - if (!versionData[field]) { - throw new Error(`${field} 是必填字段`); - } - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 检查是否为更新模式 - if (versionData.isUpdate) { - // 查询是否存在要更新的版本 - const existingVersion = db.prepare(` - SELECT COUNT(*) as count FROM 'XNModelsVersion' - WHERE ClassName = ? AND Version = ? AND ProductName = ? - `).get(versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.ProductName); - - if (existingVersion.count === 0) { - // 不存在要更新的版本,创建新版本 - return saveNewVersion(db, versionData); - } - - // 使用前端传来的修改时间,如果没有则生成当前时间 - let changeTime = versionData.ChangeTime; - if (!changeTime) { - // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } - - // 更新现有版本 - const updateResult = db.prepare(` - UPDATE 'XNModelsVersion' - SET - Name = ?, - Version = ?, - Author = ?, - Description = ?, - CodePath = ?, - ChangeTime = ?, - RunFreqGroup = ?, - RunNode = ?, - Priority = ?, - DataPackagePath = ?, - DataPackageHeaderPath = ?, - DataPackageEntryPoint = ?, - DataPackageInterfaceName = ?, - ProductName = ? - WHERE ClassName = ? AND Version = ? AND ProductName = ? - `).run( - versionData.Name, - versionData.Version, - versionData.Author, - versionData.Description || '', - versionData.CodePath || '', - changeTime, - versionData.RunFreqGroup || '', - versionData.RunNode || '', - versionData.Priority || '0', - versionData.DataPackagePath || '', - versionData.DataPackageHeaderPath || '', - versionData.DataPackageEntryPoint || '', - versionData.DataPackageInterfaceName || '', - versionData.ProductName, - versionData.ClassName, - versionData.originalVersion || versionData.Version, - versionData.ProductName - ); - - db.close(); - - return { - success: true, - isNew: false, - changes: updateResult.changes, - message: '模型版本更新成功' - }; - } else { - // 创建新版本 - return saveNewVersion(db, versionData); - } - } catch (error) { - console.error('保存模型版本时出错:', error); - throw error; - } -} - -// 内部函数:保存新版本 -function saveNewVersion(db, versionData) { - try { - // 检查版本是否已存在 - const existingVersion = db.prepare(` - SELECT COUNT(*) as count FROM 'XNModelsVersion' - WHERE ClassName = ? AND Version = ? AND ProductName = ? - `).get(versionData.ClassName, versionData.Version, versionData.ProductName); - - if (existingVersion.count > 0) { - db.close(); - throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); - } - - // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - - // 使用前端传来的时间或生成的时间 - const createTime = versionData.CreatTime || formattedDateTime; - const changeTime = versionData.ChangeTime || formattedDateTime; - - // 插入新版本 - const insertResult = db.prepare(` - INSERT INTO 'XNModelsVersion' ( - ProductName, ClassName, Name, Version, CodePath, Author, Description, - CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, - DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - `).run( - versionData.ProductName, - versionData.ClassName, - versionData.Name, - versionData.Version, - versionData.CodePath || '', - versionData.Author, - versionData.Description || '', - createTime, - changeTime, - versionData.RunFreqGroup || '', - versionData.RunNode || '', - versionData.Priority || '0', - versionData.DataPackagePath || '', - versionData.DataPackageHeaderPath || '', - versionData.DataPackageEntryPoint || '', - versionData.DataPackageInterfaceName || '' - ); - - db.close(); - - return { - success: true, - isNew: true, - id: insertResult.lastInsertRowid, - message: '模型版本创建成功' - }; - } catch (error) { - if (db) db.close(); - console.error('创建模型版本失败:', error); - throw error; - } -} - -// 查询XNServices表中的所有服务 -function getServices() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 查询所有服务 - const services = db.prepare(` - SELECT ServiceName, ServiceName_CN, Description, ClassName - FROM 'XNServices' - ORDER BY ServiceName + // 查询所有飞机 + const planes = db.prepare(` + SELECT PlaneName, Description + FROM 'Plane' + ORDER BY PlaneName `).all(); - db.close(); - - return services; + return planes; } catch (error) { - console.error('获取服务列表数据失败:', error.message); - throw error; - } -} - -// 根据ClassName查询XNServiceVersion表中的服务版本 -function getServiceVersionsByClassName(className) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 查询该类名下的所有版本 - const versions = db.prepare(` - SELECT ClassName, Name, Version, CodePath, Author, Description, - CreatTime, ChangeTime - FROM 'XNServiceVersion' - WHERE ClassName = ? - ORDER BY Version DESC - `).all(className); - - db.close(); - - return versions; - } catch (error) { - console.error(`获取服务${className}的版本数据失败:`, error.message); - throw error; - } -} - -// 保存或更新服务版本信息 -function saveServiceVersion(versionData) { - try { - // 验证必填字段 - const requiredFields = ['ClassName', 'Name', 'Version', 'Author']; - for (const field of requiredFields) { - if (!versionData[field]) { - throw new Error(`${field} 是必填字段`); - } - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 检查是否为更新模式 - if (versionData.isUpdate) { - // 查询是否存在要更新的版本 - const existingVersion = db.prepare(` - SELECT COUNT(*) as count FROM 'XNServiceVersion' - WHERE ClassName = ? AND Version = ? - `).get(versionData.ClassName, versionData.originalVersion || versionData.Version); - - if (existingVersion.count === 0) { - // 不存在要更新的版本,创建新版本 - return saveNewServiceVersion(db, versionData); - } - - // 使用前端传来的修改时间,如果没有则生成当前时间 - let changeTime = versionData.ChangeTime; - if (!changeTime) { - // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - } - - // 更新现有版本 - const updateResult = db.prepare(` - UPDATE 'XNServiceVersion' - SET - Name = ?, - Version = ?, - Author = ?, - Description = ?, - CodePath = ?, - ChangeTime = ? - WHERE ClassName = ? AND Version = ? - `).run( - versionData.Name, - versionData.Version, - versionData.Author, - versionData.Description || '', - versionData.CodePath || '', - changeTime, // 使用前端传来的时间或生成的当前时间 - versionData.ClassName, - versionData.originalVersion || versionData.Version - ); - - db.close(); - - return { - success: true, - isNew: false, - changes: updateResult.changes, - message: '服务版本更新成功' - }; - } else { - // 创建新版本 - return saveNewServiceVersion(db, versionData); - } - } catch (error) { - console.error('保存服务版本时出错:', error); - throw error; - } -} - -// 内部函数:保存新的服务版本 -function saveNewServiceVersion(db, versionData) { - try { - // 检查版本是否已存在 - const existingVersion = db.prepare(` - SELECT COUNT(*) as count FROM 'XNServiceVersion' - WHERE ClassName = ? AND Version = ? - `).get(versionData.ClassName, versionData.Version); - - if (existingVersion.count > 0) { - db.close(); - throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); - } - - // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - - // 使用前端传来的时间或生成的时间 - const createTime = versionData.CreatTime || formattedDateTime; - const changeTime = versionData.ChangeTime || formattedDateTime; - - // 插入新版本 - const insertResult = db.prepare(` - INSERT INTO 'XNServiceVersion' ( - ClassName, Name, Version, CodePath, Author, Description, - CreatTime, ChangeTime - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) - `).run( - versionData.ClassName, - versionData.Name, - versionData.Version, - versionData.CodePath || '', - versionData.Author, - versionData.Description || '', - createTime, // 使用前端传来的创建时间或生成的当前时间 - changeTime // 使用前端传来的修改时间或生成的当前时间 - ); - - db.close(); - - return { - success: true, - isNew: true, - id: insertResult.lastInsertRowid, - message: '服务版本创建成功' - }; - } catch (error) { - if (db) db.close(); - console.error('创建服务版本失败:', error); - throw error; - } -} - -// 创建新服务 -function createService(serviceData) { - try { - // 验证必填字段 - const requiredFields = ['ClassName', 'ServiceName', 'ServiceName_CN']; - for (const field of requiredFields) { - if (!serviceData[field]) { - throw new Error(`${field} 是必填字段`); - } - } - - // 验证类名是否以XN开头 - if (!serviceData.ClassName.startsWith('XN')) { - throw new Error('服务类名必须以XN开头'); - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 检查服务类名是否已存在 - const existingService = db.prepare(` - SELECT COUNT(*) as count FROM 'XNServices' - WHERE ClassName = ? - `).get(serviceData.ClassName); - - if (existingService.count > 0) { - db.close(); - throw new Error(`服务类名 ${serviceData.ClassName} 已存在,请使用其他类名`); - } - - // 检查服务名称是否已存在 - const existingServiceName = db.prepare(` - SELECT COUNT(*) as count FROM 'XNServices' - WHERE ServiceName = ? - `).get(serviceData.ServiceName); - - if (existingServiceName.count > 0) { - db.close(); - throw new Error(`服务名称 ${serviceData.ServiceName} 已存在,请使用其他名称`); - } - - // 插入新服务 - const insertResult = db.prepare(` - INSERT INTO 'XNServices' ( - ClassName, ServiceName, ServiceName_CN, Description - ) VALUES (?, ?, ?, ?) - `).run( - serviceData.ClassName, - serviceData.ServiceName, - serviceData.ServiceName_CN, - serviceData.Description || '' - ); - - db.close(); - - return { - success: true, - id: insertResult.lastInsertRowid, - message: '服务创建成功' - }; - } catch (error) { - console.error('创建服务失败:', error); - throw error; - } -} - -// 查询Products表中的所有产品 -function getProducts() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 查询所有产品 - const products = db.prepare(` - SELECT ProductName, Description - FROM 'Products' - ORDER BY ProductName - `).all(); - - db.close(); - - return products; - } catch (error) { - console.error('获取产品列表数据失败:', error.message); - throw error; - } -} - -// 获取接口列表 -function getDataInterfaces(systemName = 'XNSim', productName) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 根据是否传入 productName 构建不同的查询 - let query; - let params; - - if (!productName || productName === '') { - query = ` - SELECT SystemName, ProductName, ATAName, ModelStructName, InterfaceName, - InterfaceType, InterfaceOption, InterfaceIsArray, - InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes - FROM 'DataInterface' - WHERE SystemName = ? - ORDER BY ProductName, ATAName, ModelStructName, InterfaceName - `; - params = [systemName]; - } else { - query = ` - SELECT SystemName, ProductName, ATAName, ModelStructName, InterfaceName, - InterfaceType, InterfaceOption, InterfaceIsArray, - InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes - FROM 'DataInterface' - WHERE SystemName = ? AND ProductName = ? - ORDER BY ATAName, ModelStructName, InterfaceName - `; - params = [systemName, productName]; - } - - const interfaces = db.prepare(query).all(...params); - - db.close(); - - return interfaces; - } catch (error) { - console.error('获取接口列表数据失败:', error.message); - throw error; - } -} - -// 添加接口 -function addDataInterface(interfaceData) { - try { - // 验证必填字段 - const requiredFields = [ - 'SystemName', - 'ProductName', - 'ATAName', - 'ModelStructName', - 'InterfaceName', - 'InterfaceType', - 'InterfaceOption', - 'InterfaceIsArray', - 'InterfaceArraySize_1', - 'InterfaceArraySize_2' - ]; - - for (const field of requiredFields) { - if (interfaceData[field] === undefined || interfaceData[field] === null) { - throw new Error(`${field} 是必填字段`); - } - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 检查接口是否已存在 - const existingInterface = db.prepare(` - SELECT COUNT(*) as count FROM 'DataInterface' - WHERE SystemName = ? AND ProductName = ? AND ATAName = ? - AND ModelStructName = ? AND InterfaceName = ? - `).get( - interfaceData.SystemName, - interfaceData.ProductName, - interfaceData.ATAName, - interfaceData.ModelStructName, - interfaceData.InterfaceName - ); - - if (existingInterface.count > 0) { - db.close(); - throw new Error('接口已存在'); - } - - // 插入新接口 - const insertResult = db.prepare(` - INSERT INTO 'DataInterface' ( - SystemName, ProductName, ATAName, ModelStructName, InterfaceName, - InterfaceType, InterfaceOption, InterfaceIsArray, - InterfaceArraySize_1, InterfaceArraySize_2, InterfaceNotes - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) - `).run( - interfaceData.SystemName, - interfaceData.ProductName, - interfaceData.ATAName, - interfaceData.ModelStructName, - interfaceData.InterfaceName, - interfaceData.InterfaceType, - interfaceData.InterfaceOption, - interfaceData.InterfaceIsArray, - interfaceData.InterfaceArraySize_1, - interfaceData.InterfaceArraySize_2, - interfaceData.InterfaceNotes || null - ); - - db.close(); - - return { - success: true, - id: insertResult.lastInsertRowid, - message: '接口添加成功' - }; - } catch (error) { - console.error('添加接口失败:', error); - throw error; - } -} - -// 更新接口 -function updateDataInterface(interfaceData) { - try { - // 验证必填字段 - const requiredFields = [ - 'SystemName', - 'ProductName', - 'ATAName', - 'ModelStructName', - 'InterfaceName', - 'InterfaceType', - 'InterfaceOption', - 'InterfaceIsArray', - 'InterfaceArraySize_1', - 'InterfaceArraySize_2' - ]; - - // 检查数据结构 - if (!interfaceData.currentData || !interfaceData.originalData) { - throw new Error('数据格式错误:缺少 currentData 或 originalData'); - } - - // 验证 currentData 中的必填字段 - for (const field of requiredFields) { - if (interfaceData.currentData[field] === undefined || interfaceData.currentData[field] === null) { - throw new Error(`${field} 是必填字段`); - } - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 首先检查记录是否存在 - const existingRecord = db.prepare(` - SELECT COUNT(*) as count FROM 'DataInterface' - WHERE SystemName = ? AND ProductName = ? AND ATAName = ? - AND ModelStructName = ? AND InterfaceName = ? - `).get( - interfaceData.originalData.SystemName, - interfaceData.originalData.ProductName, - interfaceData.originalData.ATAName, - interfaceData.originalData.ModelStructName, - interfaceData.originalData.InterfaceName - ); - - if (existingRecord.count === 0) { - db.close(); - throw new Error('要更新的记录不存在'); - } - - // 更新接口,包括所有字段 - const updateResult = db.prepare(` - UPDATE 'DataInterface' - SET SystemName = ?, - ProductName = ?, - ATAName = ?, - ModelStructName = ?, - InterfaceName = ?, - InterfaceType = ?, - InterfaceOption = ?, - InterfaceIsArray = ?, - InterfaceArraySize_1 = ?, - InterfaceArraySize_2 = ?, - InterfaceNotes = ? - WHERE SystemName = ? AND ProductName = ? AND ATAName = ? - AND ModelStructName = ? AND InterfaceName = ? - `).run( - interfaceData.currentData.SystemName, - interfaceData.currentData.ProductName, - interfaceData.currentData.ATAName, - interfaceData.currentData.ModelStructName, - interfaceData.currentData.InterfaceName, - interfaceData.currentData.InterfaceType, - interfaceData.currentData.InterfaceOption, - interfaceData.currentData.InterfaceIsArray, - interfaceData.currentData.InterfaceArraySize_1, - interfaceData.currentData.InterfaceArraySize_2, - interfaceData.currentData.InterfaceNotes || null, - interfaceData.originalData.SystemName, - interfaceData.originalData.ProductName, - interfaceData.originalData.ATAName, - interfaceData.originalData.ModelStructName, - interfaceData.originalData.InterfaceName - ); - - db.close(); - - if (updateResult.changes === 0) { - throw new Error('更新失败:没有记录被修改'); - } - - return { - success: true, - changes: updateResult.changes, - message: '接口更新成功' - }; - } catch (error) { - console.error('更新接口失败:', error); - throw error; - } -} - -// 删除接口 -function deleteDataInterface(systemName, productName, ataName, modelStructName, interfaceName) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 删除接口 - const deleteResult = db.prepare(` - DELETE FROM 'DataInterface' - WHERE SystemName = ? AND ProductName = ? AND ATAName = ? - AND ModelStructName = ? AND InterfaceName = ? - `).run( - systemName || 'XNSim', - productName || 'C909', - ataName, - modelStructName, - interfaceName - ); - - db.close(); - - return { - success: true, - changes: deleteResult.changes, - message: '接口删除成功' - }; - } catch (error) { - console.error('删除接口失败:', error); - throw error; - } -} - -// 获取接口结构体列表 -function getDataInterfaceStructs(systemName = 'XNSim', productName, ataName) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 根据是否传入 productName 构建不同的查询 - let query; - let params; - - if (!productName || productName === '') { - query = ` - SELECT SystemName, ProductName, ATAName, ModelStructName - FROM 'DataInterface' - WHERE SystemName = ? - GROUP BY ModelStructName - ORDER BY ProductName, ATAName, ModelStructName - `; - params = [systemName]; - } else { - query = ` - SELECT SystemName, ProductName, ATAName, ModelStructName - FROM 'DataInterface' - WHERE SystemName = ? AND ProductName = ? - GROUP BY ModelStructName - ORDER BY ATAName, ModelStructName - `; - params = [systemName, productName]; - } - - if (ataName) { - query = query.replace('GROUP BY', 'AND ATAName = ? GROUP BY'); - params.push(ataName); - } - - const structs = db.prepare(query).all(...params); - - db.close(); - - return structs; - } catch (error) { - console.error('获取接口结构体列表数据失败:', error.message); - throw error; - } -} - -// 获取所有问题 -function getQuestions() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - const questions = db.prepare(` - SELECT q.*, - COUNT(a.id) as answer_count, - MAX(a.created_at) as last_answer_time - FROM questions q - LEFT JOIN answers a ON q.id = a.question_id - GROUP BY q.id - ORDER BY q.created_at DESC - `).all(); - - // 获取每个问题的回答 - questions.forEach(question => { - question.answers = db.prepare(` - SELECT * FROM answers - WHERE question_id = ? - ORDER BY created_at ASC - `).all(question.id); - }); - - db.close(); - return questions; - } catch (error) { - console.error('获取问题列表失败:', error); - throw error; - } -} - -// 创建新问题 -function createQuestion(title, content, author) { - try { - if (!title || !content) { - throw new Error('标题和内容不能为空'); - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare(` - INSERT INTO questions (title, content, author) - VALUES (?, ?, ?) - `).run(title, content, author || '匿名用户'); - - db.close(); - - if (result.changes > 0) { - return { - success: true, - questionId: result.lastInsertRowid, - message: '问题创建成功' - }; - } else { - throw new Error('问题创建失败'); - } - } catch (error) { - console.error('创建问题失败:', error); - throw error; - } -} - -// 添加回答 -function addAnswer(questionId, content, author) { - try { - if (!content) { - throw new Error('回答内容不能为空'); - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 检查问题是否存在 - const question = db.prepare('SELECT id FROM questions WHERE id = ?').get(questionId); - if (!question) { - db.close(); - throw new Error('问题不存在'); - } - - const result = db.prepare(` - INSERT INTO answers (question_id, content, author) - VALUES (?, ?, ?) - `).run(questionId, content, author || '匿名用户'); - - db.close(); - - if (result.changes > 0) { - return { - success: true, - answerId: result.lastInsertRowid, - message: '回答添加成功' - }; - } else { - throw new Error('回答添加失败'); - } - } catch (error) { - console.error('添加回答失败:', error); - throw error; - } -} - -// 删除问题 -function deleteQuestion(questionId) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare('DELETE FROM questions WHERE id = ?').run(questionId); - db.close(); - - if (result.changes > 0) { - return { - success: true, - message: '问题删除成功' - }; - } else { - throw new Error('问题不存在'); - } - } catch (error) { - console.error('删除问题失败:', error); - throw error; - } -} - -// 删除回答 -function deleteAnswer(answerId) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare('DELETE FROM answers WHERE id = ?').run(answerId); - db.close(); - - if (result.changes > 0) { - return { - success: true, - message: '回答删除成功' - }; - } else { - throw new Error('回答不存在'); - } - } catch (error) { - console.error('删除回答失败:', error); - throw error; - } -} - -// 获取所有待办事项 -function getTodos() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 创建todos表(如果不存在) - db.prepare(` - CREATE TABLE IF NOT EXISTS todos ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - project TEXT NOT NULL DEFAULT '其它', - subproject TEXT NOT NULL DEFAULT '其它', - title TEXT NOT NULL, - text TEXT, - adduser TEXT NOT NULL, - exeuser TEXT, - completed BOOLEAN DEFAULT 0, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - sche_time DATETIME DEFAULT CURRENT_TIMESTAMP, - complete_time DATETIME DEFAULT CURRENT_TIMESTAMP - ) - `).run(); - - const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all(); - db.close(); - - return todos; - } catch (error) { - console.error('获取待办事项失败:', error); - throw error; - } -} - -// 添加待办事项 -function addTodo(todoData) { - try { - if (!todoData.title) { - throw new Error('待办事项标题不能为空'); - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 获取当前本地时间 - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - - // 处理计划时间 - let scheTime = todoData.sche_time; - if (scheTime) { - // 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式 - if (scheTime.includes('T')) { - const [datePart, timePart] = scheTime.split('T'); - scheTime = `${datePart} ${timePart}:00`; - } - } else { - scheTime = localDateTime; - } - - const result = db.prepare(` - INSERT INTO todos ( - project, subproject, title, text, adduser, - exeuser, completed, created_at, sche_time - ) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?) - `).run( - todoData.project || '其它', - todoData.subproject || '其它', - todoData.title, - todoData.text || '', - todoData.adduser || '系统', - todoData.exeuser || null, - localDateTime, - scheTime - ); - - db.close(); - - if (result.changes > 0) { - return { - success: true, - id: result.lastInsertRowid, - message: '待办事项添加成功' - }; - } else { - throw new Error('待办事项添加失败'); - } - } catch (error) { - console.error('添加待办事项失败:', error); - throw error; - } -} - -// 更新待办事项状态 -function updateTodoStatus(id, completed, exeuser, title, text, sche_time) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 获取当前本地时间 - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - - // 处理计划时间 - let scheTime = sche_time; - if (scheTime) { - // 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式 - if (scheTime.includes('T')) { - const [datePart, timePart] = scheTime.split('T'); - scheTime = `${datePart} ${timePart}`; - } - } - - const result = db.prepare(` - UPDATE todos - SET completed = ?, - exeuser = ?, - title = ?, - text = ?, - sche_time = ?, - complete_time = CASE WHEN ? = 1 THEN ? ELSE complete_time END - WHERE id = ? - `).run( - completed ? 1 : 0, - exeuser || null, - title, - text || '', - scheTime || null, - completed ? 1 : 0, - completed ? localDateTime : null, - id - ); - - db.close(); - - if (result.changes > 0) { - return { - success: true, - message: '待办事项更新成功' - }; - } else { - throw new Error('待办事项不存在'); - } - } catch (error) { - console.error('更新待办事项失败:', error); - throw error; - } -} - -// 删除待办事项 -function deleteTodo(id) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare('DELETE FROM todos WHERE id = ?').run(id); - db.close(); - - return { - success: true, - message: result.changes > 0 ? '待办事项删除成功' : '待办事项不存在或已被删除' - }; - } catch (error) { - console.error('删除待办事项失败:', error); + console.error('获取飞机列表数据失败:', error.message); throw error; } } @@ -1406,18 +22,7 @@ function deleteTodo(id) { // 获取所有用户信息 function getUsers() { try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); + const db = getDBConnection(true); const users = db.prepare(` SELECT @@ -1434,8 +39,6 @@ function getUsers() { ORDER BY id ASC `).all(); - db.close(); - return users; } catch (error) { console.error('获取用户信息失败:', error); @@ -1443,311 +46,7 @@ function getUsers() { } } -// 获取所有系统日志 -function getSystemLogs() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - const logs = db.prepare(` - SELECT id, time, level, user, source, log - FROM SystemLog - ORDER BY time DESC - `).all(); - - db.close(); - - return logs; - } catch (error) { - console.error('获取系统日志失败:', error); - throw error; - } -} - -// 添加系统日志 -function addSystemLog(logData) { - try { - // 验证必填字段 - if (!logData.level || !logData.source) { - throw new Error('日志级别和来源是必填字段'); - } - - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 获取当前本地时间 - const now = new Date(); - const year = now.getFullYear(); - const month = String(now.getMonth() + 1).padStart(2, '0'); - const day = String(now.getDate()).padStart(2, '0'); - const hours = String(now.getHours()).padStart(2, '0'); - const minutes = String(now.getMinutes()).padStart(2, '0'); - const seconds = String(now.getSeconds()).padStart(2, '0'); - const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; - - // 在插入日志时添加时间 - const result = db.prepare(` - INSERT INTO SystemLog (level, user, source, log, time) - VALUES (?, ?, ?, ?, ?) - `).run( - logData.level, - logData.user || null, - logData.source, - logData.log || null, - localDateTime - ); - - db.close(); - - if (result.changes > 0) { - return { - success: true, - id: result.lastInsertRowid, - message: '系统日志添加成功' - }; - } else { - throw new Error('系统日志添加失败'); - } - } catch (error) { - console.error('添加系统日志失败:', error); - throw error; - } -} - -// 获取运行中的XNEngine进程 -function getRunningXNEngineProcess(pid) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - // 创建进程表(如果不存在) - db.prepare(` - CREATE TABLE IF NOT EXISTS xnengine_processes ( - pid INTEGER PRIMARY KEY, - log_file TEXT, - start_time TEXT, - cmd TEXT, - status TEXT DEFAULT 'running', - scenario_file TEXT - ) - `).run(); - - const process = db.prepare('SELECT * FROM xnengine_processes WHERE pid = ?').get(pid); - db.close(); - - return process; - } catch (error) { - console.error('获取XNEngine进程信息失败:', error); - throw error; - } -} - -// 保存XNEngine进程信息 -function saveXNEngineProcess(processData) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - // 创建进程表(如果不存在) - db.prepare(` - CREATE TABLE IF NOT EXISTS xnengine_processes ( - pid INTEGER PRIMARY KEY, - log_file TEXT, - start_time TEXT, - cmd TEXT, - status TEXT DEFAULT 'running', - scenario_file TEXT - ) - `).run(); - - const result = db.prepare(` - INSERT INTO xnengine_processes (pid, log_file, start_time, cmd, scenario_file) - VALUES (?, ?, ?, ?, ?) - `).run( - processData.pid, - processData.log_file, - processData.start_time, - processData.cmd, - processData.scenario_file || null - ); - - db.close(); - - return { - success: true, - message: 'XNEngine进程信息保存成功' - }; - } catch (error) { - console.error('保存XNEngine进程信息失败:', error); - throw error; - } -} - -// 更新XNEngine进程状态 -function updateXNEngineProcessStatus(pid, status) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare(` - UPDATE xnengine_processes - SET status = ? - WHERE pid = ? - `).run(status, pid); - - db.close(); - - return { - success: true, - message: 'XNEngine进程状态更新成功' - }; - } catch (error) { - console.error('更新XNEngine进程状态失败:', error); - throw error; - } -} - -// 删除XNEngine进程信息 -function deleteXNEngineProcess(pid) { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath); - - const result = db.prepare('DELETE FROM xnengine_processes WHERE pid = ?').run(pid); - db.close(); - - return { - success: true, - message: 'XNEngine进程信息删除成功' - }; - } catch (error) { - console.error('删除XNEngine进程信息失败:', error); - throw error; - } -} - -// 获取最新的运行中XNEngine进程 -function getLatestRunningXNEngineProcess() { - try { - const xnCorePath = getXNCorePath(); - if (!xnCorePath) { - throw new Error('XNCore环境变量未设置,无法获取数据库路径'); - } - - const dbPath = xnCorePath + '/database/XNSim.db'; - if (!dbPath) { - throw new Error('无法找到数据库文件'); - } - - // 打开数据库连接 - const db = new Database(dbPath, { readonly: true }); - - const process = db.prepare(` - SELECT * FROM xnengine_processes - WHERE status = ? - ORDER BY start_time DESC - LIMIT 1 - `).get('running'); - - db.close(); - - return process; - } catch (error) { - console.error('获取最新XNEngine进程信息失败:', error); - throw error; - } -} - module.exports = { - getATAChapters, - getModelsByChapterId, - getModelVersionsByClassName, - saveModelVersion, - getServices, - getServiceVersionsByClassName, - saveServiceVersion, - createService, - getProducts, - getDataInterfaces, - addDataInterface, - updateDataInterface, - deleteDataInterface, - getDataInterfaceStructs, - getQuestions, - createQuestion, - addAnswer, - deleteQuestion, - deleteAnswer, - getTodos, - addTodo, - updateTodoStatus, - deleteTodo, - getUsers, - getSystemLogs, - addSystemLog, - getRunningXNEngineProcess, - saveXNEngineProcess, - updateXNEngineProcessStatus, - deleteXNEngineProcess, - getLatestRunningXNEngineProcess + getPlanes, + getUsers }; \ No newline at end of file diff --git a/XNSimHtml/utils/file-utils.js b/XNSimHtml/utils/file-utils.js index 3489873..006b56a 100644 --- a/XNSimHtml/utils/file-utils.js +++ b/XNSimHtml/utils/file-utils.js @@ -1,5 +1,43 @@ const path = require('path'); const fs = require('fs').promises; +const Database = require('better-sqlite3'); + +// 数据库连接管理 +let dbConnection = null; + +// 获取数据库连接 +function getDBConnection(readonly = false) { + try { + if (dbConnection) { + return dbConnection; + } + + const xnCorePath = getXNCorePath(); + if (!xnCorePath) { + throw new Error('XNCore环境变量未设置,无法获取数据库路径'); + } + + const dbPath = path.join(xnCorePath, 'database', 'XNSim.db'); + if (!dbPath) { + throw new Error('无法找到数据库文件'); + } + + // 打开数据库连接 + dbConnection = new Database(dbPath, { readonly }); + return dbConnection; + } catch (error) { + console.error('数据库连接失败:', error); + throw error; + } +} + +// 关闭数据库连接 +function closeDBConnection() { + if (dbConnection) { + dbConnection.close(); + dbConnection = null; + } +} // 获取XNCore路径 function getXNCorePath() { @@ -112,5 +150,7 @@ module.exports = { getActualLogPath, isPathSafe, ensureDirectoryExists, - validateXml + validateXml, + getDBConnection, + closeDBConnection }; \ No newline at end of file diff --git a/XNSimHtml/utils/model-utils.js b/XNSimHtml/utils/model-utils.js new file mode 100644 index 0000000..266bbbc --- /dev/null +++ b/XNSimHtml/utils/model-utils.js @@ -0,0 +1,271 @@ +const { getDBConnection } = require('./file-utils'); + +// 查询ATAChapters表 +function getATAChapters() { + try { + const db = getDBConnection(true); + + // 直接使用ATAChapters表名查询 + const chapters = db.prepare("SELECT ID, Name, Name_CN FROM 'ATAChapters' ORDER BY ID").all(); + + return chapters; + } catch (error) { + console.error('获取ATA章节数据失败:', error.message); + throw error; + } +} + +// 根据章节ID查询XNModels表中的模型 +function getModelsByChapterId(chapterId, planeName) { + try { + const db = getDBConnection(true); + + // 根据planeName是否为空构建不同的查询 + let query; + let params; + + if (!planeName || planeName === '' || planeName === 'undefined') { + query = ` + SELECT PlaneName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName + FROM 'XNModels' + WHERE Chapters_ID = ? + ORDER BY ModelName + `; + params = [chapterId]; + } else { + query = ` + SELECT PlaneName, Chapters_ID, ModelName, ModelName_CN, Description, ClassName + FROM 'XNModels' + WHERE Chapters_ID = ? AND PlaneName = ? + ORDER BY ModelName + `; + params = [chapterId, planeName]; + } + + const models = db.prepare(query).all(...params); + + return models; + } catch (error) { + console.error(`获取章节${chapterId}的模型数据失败:`, error.message); + throw error; + } +} + +// 根据ClassName查询XNModelsVersion表中的模型版本 +function getModelVersionsByClassName(className, planeName) { + try { + const db = getDBConnection(true); + + // 根据planeName是否为空构建不同的查询 + let query; + let params; + + if (!planeName || planeName === '') { + query = ` + SELECT + PlaneName, ClassName, Name, Version, CodePath, Author, Description, + CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, + DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName, + ConfID + FROM 'XNModelsVersion' + WHERE ClassName = ? + ORDER BY Version DESC + `; + params = [className]; + } else { + query = ` + SELECT + PlaneName, ClassName, Name, Version, CodePath, Author, Description, + CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, + DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName, + ConfID + FROM 'XNModelsVersion' + WHERE ClassName = ? AND PlaneName = ? + ORDER BY Version DESC + `; + params = [className, planeName]; + } + + const versions = db.prepare(query).all(...params); + + return versions; + } catch (error) { + console.error(`获取模型${className}的版本数据失败:`, error.message); + throw error; + } +} + +// 保存或更新模型版本信息 +function saveModelVersion(versionData) { + try { + // 验证必填字段 + const requiredFields = ['ClassName', 'Name', 'Version', 'Author', 'PlaneName', 'ConfID']; + for (const field of requiredFields) { + if (!versionData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查是否为更新模式 + if (versionData.isUpdate) { + // 查询是否存在要更新的版本 + const existingVersion = db.prepare(` + SELECT COUNT(*) as count FROM 'XNModelsVersion' + WHERE ClassName = ? AND Version = ? AND PlaneName = ? + `).get(versionData.ClassName, versionData.originalVersion || versionData.Version, versionData.PlaneName); + + if (existingVersion.count === 0) { + // 不存在要更新的版本,创建新版本 + return saveNewVersion(db, versionData); + } + + // 使用前端传来的修改时间,如果没有则生成当前时间 + let changeTime = versionData.ChangeTime; + if (!changeTime) { + // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } + + // 更新现有版本 + const updateResult = db.prepare(` + UPDATE 'XNModelsVersion' + SET + PlaneName = ?, + ClassName = ?, + Name = ?, + Version = ?, + CodePath = ?, + Author = ?, + Description = ?, + CreatTime = ?, + ChangeTime = ?, + RunFreqGroup = ?, + RunNode = ?, + Priority = ?, + DataPackagePath = ?, + DataPackageHeaderPath = ?, + DataPackageEntryPoint = ?, + DataPackageInterfaceName = ?, + ConfID = ? + WHERE ClassName = ? AND Version = ? AND PlaneName = ? + `).run( + versionData.PlaneName, + versionData.ClassName, + versionData.Name, + versionData.Version, + versionData.CodePath || '', + versionData.Author, + versionData.Description || '', + versionData.CreatTime || changeTime, + changeTime, + versionData.RunFreqGroup || '', + versionData.RunNode || '', + versionData.Priority || '0', + versionData.DataPackagePath || '', + versionData.DataPackageHeaderPath || '', + versionData.DataPackageEntryPoint || '', + versionData.DataPackageInterfaceName || '', + versionData.ConfID, + versionData.ClassName, + versionData.originalVersion || versionData.Version, + versionData.PlaneName + ); + + return { + success: true, + isNew: false, + changes: updateResult.changes, + message: '模型版本更新成功' + }; + } else { + // 创建新版本 + return saveNewVersion(db, versionData); + } + } catch (error) { + console.error('保存模型版本时出错:', error); + throw error; + } +} + +// 内部函数:保存新版本 +function saveNewVersion(db, versionData) { + try { + // 检查版本是否已存在 + const existingVersion = db.prepare(` + SELECT COUNT(*) as count FROM 'XNModelsVersion' + WHERE ClassName = ? AND Version = ? AND PlaneName = ? + `).get(versionData.ClassName, versionData.Version, versionData.PlaneName); + + if (existingVersion.count > 0) { + throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); + } + + // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + + // 使用前端传来的时间或生成的时间 + const createTime = versionData.CreatTime || formattedDateTime; + const changeTime = versionData.ChangeTime || formattedDateTime; + + // 插入新版本 + const insertResult = db.prepare(` + INSERT INTO 'XNModelsVersion' ( + PlaneName, ClassName, Name, Version, CodePath, Author, Description, + CreatTime, ChangeTime, RunFreqGroup, RunNode, Priority, + DataPackagePath, DataPackageHeaderPath, DataPackageEntryPoint, DataPackageInterfaceName, + ConfID + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + `).run( + versionData.PlaneName, + versionData.ClassName, + versionData.Name, + versionData.Version, + versionData.CodePath || '', + versionData.Author, + versionData.Description || '', + createTime, + changeTime, + versionData.RunFreqGroup || '', + versionData.RunNode || '', + versionData.Priority || '0', + versionData.DataPackagePath || '', + versionData.DataPackageHeaderPath || '', + versionData.DataPackageEntryPoint || '', + versionData.DataPackageInterfaceName || '', + versionData.ConfID + ); + + return { + success: true, + isNew: true, + id: insertResult.lastInsertRowid, + message: '模型版本创建成功' + }; + } catch (error) { + console.error('创建模型版本失败:', error); + throw error; + } +} + +module.exports = { + getATAChapters, + getModelsByChapterId, + getModelVersionsByClassName, + saveModelVersion +}; \ No newline at end of file diff --git a/XNSimHtml/utils/qa-utils.js b/XNSimHtml/utils/qa-utils.js new file mode 100644 index 0000000..b43b678 --- /dev/null +++ b/XNSimHtml/utils/qa-utils.js @@ -0,0 +1,146 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取所有问题 +function getQuestions() { + try { + const db = getDBConnection(true); + + const questions = db.prepare(` + SELECT q.*, + COUNT(a.id) as answer_count, + MAX(a.created_at) as last_answer_time + FROM questions q + LEFT JOIN answers a ON q.id = a.question_id + GROUP BY q.id + ORDER BY q.created_at DESC + `).all(); + + // 获取每个问题的回答 + questions.forEach(question => { + question.answers = db.prepare(` + SELECT * FROM answers + WHERE question_id = ? + ORDER BY created_at ASC + `).all(question.id); + }); + + return questions; + } catch (error) { + console.error('获取问题列表失败:', error); + throw error; + } +} + +// 创建新问题 +function createQuestion(title, content, author) { + try { + if (!title || !content) { + throw new Error('标题和内容不能为空'); + } + + const db = getDBConnection(); + + const result = db.prepare(` + INSERT INTO questions (title, content, author) + VALUES (?, ?, ?) + `).run(title, content, author || '匿名用户'); + + if (result.changes > 0) { + return { + success: true, + questionId: result.lastInsertRowid, + message: '问题创建成功' + }; + } else { + throw new Error('问题创建失败'); + } + } catch (error) { + console.error('创建问题失败:', error); + throw error; + } +} + +// 添加回答 +function addAnswer(questionId, content, author) { + try { + if (!content) { + throw new Error('回答内容不能为空'); + } + + const db = getDBConnection(); + + // 检查问题是否存在 + const question = db.prepare('SELECT id FROM questions WHERE id = ?').get(questionId); + if (!question) { + throw new Error('问题不存在'); + } + + const result = db.prepare(` + INSERT INTO answers (question_id, content, author) + VALUES (?, ?, ?) + `).run(questionId, content, author || '匿名用户'); + + if (result.changes > 0) { + return { + success: true, + answerId: result.lastInsertRowid, + message: '回答添加成功' + }; + } else { + throw new Error('回答添加失败'); + } + } catch (error) { + console.error('添加回答失败:', error); + throw error; + } +} + +// 删除问题 +function deleteQuestion(questionId) { + try { + const db = getDBConnection(); + + const result = db.prepare('DELETE FROM questions WHERE id = ?').run(questionId); + + if (result.changes > 0) { + return { + success: true, + message: '问题删除成功' + }; + } else { + throw new Error('问题不存在'); + } + } catch (error) { + console.error('删除问题失败:', error); + throw error; + } +} + +// 删除回答 +function deleteAnswer(answerId) { + try { + const db = getDBConnection(); + + const result = db.prepare('DELETE FROM answers WHERE id = ?').run(answerId); + + if (result.changes > 0) { + return { + success: true, + message: '回答删除成功' + }; + } else { + throw new Error('回答不存在'); + } + } catch (error) { + console.error('删除回答失败:', error); + throw error; + } +} + +module.exports = { + getQuestions, + createQuestion, + addAnswer, + deleteQuestion, + deleteAnswer +}; \ No newline at end of file diff --git a/XNSimHtml/utils/service-utils.js b/XNSimHtml/utils/service-utils.js new file mode 100644 index 0000000..111f310 --- /dev/null +++ b/XNSimHtml/utils/service-utils.js @@ -0,0 +1,243 @@ +const { getDBConnection } = require('./file-utils'); + +// 查询XNServices表中的所有服务 +function getServices() { + try { + const db = getDBConnection(true); + + // 查询所有服务 + const services = db.prepare(` + SELECT ServiceName, ServiceName_CN, Description, ClassName + FROM 'XNServices' + ORDER BY ServiceName + `).all(); + + return services; + } catch (error) { + console.error('获取服务列表数据失败:', error.message); + throw error; + } +} + +// 根据ClassName查询XNServiceVersion表中的服务版本 +function getServiceVersionsByClassName(className) { + try { + const db = getDBConnection(true); + + // 查询该类名下的所有版本 + const versions = db.prepare(` + SELECT ClassName, Name, Version, CodePath, Author, Description, + CreatTime, ChangeTime + FROM 'XNServiceVersion' + WHERE ClassName = ? + ORDER BY Version DESC + `).all(className); + + return versions; + } catch (error) { + console.error(`获取服务${className}的版本数据失败:`, error.message); + throw error; + } +} + +// 保存或更新服务版本信息 +function saveServiceVersion(versionData) { + try { + // 验证必填字段 + const requiredFields = ['ClassName', 'Name', 'Version', 'Author']; + for (const field of requiredFields) { + if (!versionData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + const db = getDBConnection(); + + // 检查是否为更新模式 + if (versionData.isUpdate) { + // 查询是否存在要更新的版本 + const existingVersion = db.prepare(` + SELECT COUNT(*) as count FROM 'XNServiceVersion' + WHERE ClassName = ? AND Version = ? + `).get(versionData.ClassName, versionData.originalVersion || versionData.Version); + + if (existingVersion.count === 0) { + // 不存在要更新的版本,创建新版本 + return saveNewServiceVersion(db, versionData); + } + + // 使用前端传来的修改时间,如果没有则生成当前时间 + let changeTime = versionData.ChangeTime; + if (!changeTime) { + // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + changeTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + } + + // 更新现有版本 + const updateResult = db.prepare(` + UPDATE 'XNServiceVersion' + SET + Name = ?, + Version = ?, + Author = ?, + Description = ?, + CodePath = ?, + ChangeTime = ? + WHERE ClassName = ? AND Version = ? + `).run( + versionData.Name, + versionData.Version, + versionData.Author, + versionData.Description || '', + versionData.CodePath || '', + changeTime, // 使用前端传来的时间或生成的当前时间 + versionData.ClassName, + versionData.originalVersion || versionData.Version + ); + + return { + success: true, + isNew: false, + changes: updateResult.changes, + message: '服务版本更新成功' + }; + } else { + // 创建新版本 + return saveNewServiceVersion(db, versionData); + } + } catch (error) { + console.error('保存服务版本时出错:', error); + throw error; + } +} + +// 内部函数:保存新的服务版本 +function saveNewServiceVersion(db, versionData) { + try { + // 检查版本是否已存在 + const existingVersion = db.prepare(` + SELECT COUNT(*) as count FROM 'XNServiceVersion' + WHERE ClassName = ? AND Version = ? + `).get(versionData.ClassName, versionData.Version); + + if (existingVersion.count > 0) { + throw new Error(`版本 ${versionData.Version} 已存在,请使用其他版本号`); + } + + // 生成当前时间,格式为YYYY-MM-DD HH:MM:SS + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + + // 使用前端传来的时间或生成的时间 + const createTime = versionData.CreatTime || formattedDateTime; + const changeTime = versionData.ChangeTime || formattedDateTime; + + // 插入新版本 + const insertResult = db.prepare(` + INSERT INTO 'XNServiceVersion' ( + ClassName, Name, Version, CodePath, Author, Description, + CreatTime, ChangeTime + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + `).run( + versionData.ClassName, + versionData.Name, + versionData.Version, + versionData.CodePath || '', + versionData.Author, + versionData.Description || '', + createTime, // 使用前端传来的创建时间或生成的当前时间 + changeTime // 使用前端传来的修改时间或生成的当前时间 + ); + + return { + success: true, + isNew: true, + id: insertResult.lastInsertRowid, + message: '服务版本创建成功' + }; + } catch (error) { + console.error('创建服务版本失败:', error); + throw error; + } +} + +// 创建新服务 +function createService(serviceData) { + try { + // 验证必填字段 + const requiredFields = ['ClassName', 'ServiceName', 'ServiceName_CN']; + for (const field of requiredFields) { + if (!serviceData[field]) { + throw new Error(`${field} 是必填字段`); + } + } + + // 验证类名是否以XN开头 + if (!serviceData.ClassName.startsWith('XN')) { + throw new Error('服务类名必须以XN开头'); + } + + const db = getDBConnection(); + + // 检查服务类名是否已存在 + const existingService = db.prepare(` + SELECT COUNT(*) as count FROM 'XNServices' + WHERE ClassName = ? + `).get(serviceData.ClassName); + + if (existingService.count > 0) { + throw new Error(`服务类名 ${serviceData.ClassName} 已存在,请使用其他类名`); + } + + // 检查服务名称是否已存在 + const existingServiceName = db.prepare(` + SELECT COUNT(*) as count FROM 'XNServices' + WHERE ServiceName = ? + `).get(serviceData.ServiceName); + + if (existingServiceName.count > 0) { + throw new Error(`服务名称 ${serviceData.ServiceName} 已存在,请使用其他名称`); + } + + // 插入新服务 + const insertResult = db.prepare(` + INSERT INTO 'XNServices' ( + ClassName, ServiceName, ServiceName_CN, Description + ) VALUES (?, ?, ?, ?) + `).run( + serviceData.ClassName, + serviceData.ServiceName, + serviceData.ServiceName_CN, + serviceData.Description || '' + ); + + return { + success: true, + id: insertResult.lastInsertRowid, + message: '服务创建成功' + }; + } catch (error) { + console.error('创建服务失败:', error); + throw error; + } +} + +module.exports = { + getServices, + getServiceVersionsByClassName, + saveServiceVersion, + createService +}; \ No newline at end of file diff --git a/XNSimHtml/utils/system-log-utils.js b/XNSimHtml/utils/system-log-utils.js new file mode 100644 index 0000000..ac98fe4 --- /dev/null +++ b/XNSimHtml/utils/system-log-utils.js @@ -0,0 +1,71 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取所有系统日志 +function getSystemLogs() { + try { + const db = getDBConnection(true); + + const logs = db.prepare(` + SELECT id, time, level, user, source, log + FROM SystemLog + ORDER BY time DESC + `).all(); + + return logs; + } catch (error) { + console.error('获取系统日志失败:', error); + throw error; + } +} + +// 添加系统日志 +function addSystemLog(logData) { + try { + // 验证必填字段 + if (!logData.level || !logData.source) { + throw new Error('日志级别和来源是必填字段'); + } + + const db = getDBConnection(); + + // 获取当前本地时间 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + + // 在插入日志时添加时间 + const result = db.prepare(` + INSERT INTO SystemLog (level, user, source, log, time) + VALUES (?, ?, ?, ?, ?) + `).run( + logData.level, + logData.user || null, + logData.source, + logData.log || null, + localDateTime + ); + + if (result.changes > 0) { + return { + success: true, + id: result.lastInsertRowid, + message: '系统日志添加成功' + }; + } else { + throw new Error('系统日志添加失败'); + } + } catch (error) { + console.error('添加系统日志失败:', error); + throw error; + } +} + +module.exports = { + getSystemLogs, + addSystemLog +}; \ No newline at end of file diff --git a/XNSimHtml/utils/todo-utils.js b/XNSimHtml/utils/todo-utils.js new file mode 100644 index 0000000..16b4ff6 --- /dev/null +++ b/XNSimHtml/utils/todo-utils.js @@ -0,0 +1,177 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取所有待办事项 +function getTodos() { + try { + const db = getDBConnection(true); + + // 创建todos表(如果不存在) + db.prepare(` + CREATE TABLE IF NOT EXISTS todos ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + project TEXT NOT NULL DEFAULT '其它', + subproject TEXT NOT NULL DEFAULT '其它', + title TEXT NOT NULL, + text TEXT, + adduser TEXT NOT NULL, + exeuser TEXT, + completed BOOLEAN DEFAULT 0, + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + sche_time DATETIME DEFAULT CURRENT_TIMESTAMP, + complete_time DATETIME DEFAULT CURRENT_TIMESTAMP + ) + `).run(); + + const todos = db.prepare('SELECT * FROM todos ORDER BY created_at DESC').all(); + + return todos; + } catch (error) { + console.error('获取待办事项失败:', error); + throw error; + } +} + +// 添加待办事项 +function addTodo(todoData) { + try { + if (!todoData.title) { + throw new Error('待办事项标题不能为空'); + } + + const db = getDBConnection(); + + // 获取当前本地时间 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + + // 处理计划时间 + let scheTime = todoData.sche_time; + if (scheTime) { + // 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式 + if (scheTime.includes('T')) { + const [datePart, timePart] = scheTime.split('T'); + scheTime = `${datePart} ${timePart}:00`; + } + } else { + scheTime = localDateTime; + } + + const result = db.prepare(` + INSERT INTO todos ( + project, subproject, title, text, adduser, + exeuser, completed, created_at, sche_time + ) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?) + `).run( + todoData.project || '其它', + todoData.subproject || '其它', + todoData.title, + todoData.text || '', + todoData.adduser || '系统', + todoData.exeuser || null, + localDateTime, + scheTime + ); + + if (result.changes > 0) { + return { + success: true, + id: result.lastInsertRowid, + message: '待办事项添加成功' + }; + } else { + throw new Error('待办事项添加失败'); + } + } catch (error) { + console.error('添加待办事项失败:', error); + throw error; + } +} + +// 更新待办事项状态 +function updateTodoStatus(id, completed, exeuser, title, text, sche_time) { + try { + const db = getDBConnection(); + + // 获取当前本地时间 + const now = new Date(); + const year = now.getFullYear(); + const month = String(now.getMonth() + 1).padStart(2, '0'); + const day = String(now.getDate()).padStart(2, '0'); + const hours = String(now.getHours()).padStart(2, '0'); + const minutes = String(now.getMinutes()).padStart(2, '0'); + const seconds = String(now.getSeconds()).padStart(2, '0'); + const localDateTime = `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; + + // 处理计划时间 + let scheTime = sche_time; + if (scheTime) { + // 如果sche_time是datetime-local格式(YYYY-MM-DDTHH:mm),转换为数据库格式 + if (scheTime.includes('T')) { + const [datePart, timePart] = scheTime.split('T'); + scheTime = `${datePart} ${timePart}`; + } + } + + const result = db.prepare(` + UPDATE todos + SET completed = ?, + exeuser = ?, + title = ?, + text = ?, + sche_time = ?, + complete_time = CASE WHEN ? = 1 THEN ? ELSE complete_time END + WHERE id = ? + `).run( + completed ? 1 : 0, + exeuser || null, + title, + text || '', + scheTime || null, + completed ? 1 : 0, + completed ? localDateTime : null, + id + ); + + if (result.changes > 0) { + return { + success: true, + message: '待办事项更新成功' + }; + } else { + throw new Error('待办事项不存在'); + } + } catch (error) { + console.error('更新待办事项失败:', error); + throw error; + } +} + +// 删除待办事项 +function deleteTodo(id) { + try { + const db = getDBConnection(); + + const result = db.prepare('DELETE FROM todos WHERE id = ?').run(id); + + return { + success: true, + message: result.changes > 0 ? '待办事项删除成功' : '待办事项不存在或已被删除' + }; + } catch (error) { + console.error('删除待办事项失败:', error); + throw error; + } +} + +module.exports = { + getTodos, + addTodo, + updateTodoStatus, + deleteTodo +}; \ No newline at end of file diff --git a/XNSimHtml/utils/xnengine-process-utils.js b/XNSimHtml/utils/xnengine-process-utils.js new file mode 100644 index 0000000..731110b --- /dev/null +++ b/XNSimHtml/utils/xnengine-process-utils.js @@ -0,0 +1,130 @@ +const { getDBConnection } = require('./file-utils'); + +// 获取运行中的XNEngine进程 +function getRunningXNEngineProcess(pid) { + try { + const db = getDBConnection(true); + + // 创建进程表(如果不存在) + db.prepare(` + CREATE TABLE IF NOT EXISTS xnengine_processes ( + pid INTEGER PRIMARY KEY, + log_file TEXT, + start_time TEXT, + cmd TEXT, + status TEXT DEFAULT 'running', + scenario_file TEXT + ) + `).run(); + + const process = db.prepare('SELECT * FROM xnengine_processes WHERE pid = ?').get(pid); + + return process; + } catch (error) { + console.error('获取XNEngine进程信息失败:', error); + throw error; + } +} + +// 保存XNEngine进程信息 +function saveXNEngineProcess(processData) { + try { + const db = getDBConnection(); + + // 创建进程表(如果不存在) + db.prepare(` + CREATE TABLE IF NOT EXISTS xnengine_processes ( + pid INTEGER PRIMARY KEY, + log_file TEXT, + start_time TEXT, + cmd TEXT, + status TEXT DEFAULT 'running', + scenario_file TEXT + ) + `).run(); + + const result = db.prepare(` + INSERT INTO xnengine_processes (pid, log_file, start_time, cmd, scenario_file) + VALUES (?, ?, ?, ?, ?) + `).run( + processData.pid, + processData.log_file, + processData.start_time, + processData.cmd, + processData.scenario_file || null + ); + + return { + success: true, + message: 'XNEngine进程信息保存成功' + }; + } catch (error) { + console.error('保存XNEngine进程信息失败:', error); + throw error; + } +} + +// 更新XNEngine进程状态 +function updateXNEngineProcessStatus(pid, status) { + try { + const db = getDBConnection(); + + const result = db.prepare(` + UPDATE xnengine_processes + SET status = ? + WHERE pid = ? + `).run(status, pid); + + return { + success: true, + message: 'XNEngine进程状态更新成功' + }; + } catch (error) { + console.error('更新XNEngine进程状态失败:', error); + throw error; + } +} + +// 删除XNEngine进程信息 +function deleteXNEngineProcess(pid) { + try { + const db = getDBConnection(); + + const result = db.prepare('DELETE FROM xnengine_processes WHERE pid = ?').run(pid); + + return { + success: true, + message: 'XNEngine进程信息删除成功' + }; + } catch (error) { + console.error('删除XNEngine进程信息失败:', error); + throw error; + } +} + +// 获取最新的运行中XNEngine进程 +function getLatestRunningXNEngineProcess() { + try { + const db = getDBConnection(true); + + const process = db.prepare(` + SELECT * FROM xnengine_processes + WHERE status = ? + ORDER BY start_time DESC + LIMIT 1 + `).get('running'); + + return process; + } catch (error) { + console.error('获取最新XNEngine进程信息失败:', error); + throw error; + } +} + +module.exports = { + getRunningXNEngineProcess, + saveXNEngineProcess, + updateXNEngineProcessStatus, + deleteXNEngineProcess, + getLatestRunningXNEngineProcess +}; \ No newline at end of file