190 lines
6.8 KiB
C#
190 lines
6.8 KiB
C#
using Microsoft.Extensions.Configuration;
|
||
using Microsoft.Data.Sqlite;
|
||
using OfficeOpenXml;
|
||
using System;
|
||
using System.IO;
|
||
using System.Windows;
|
||
using TabletTester2025.Data;
|
||
using TabletTester2025.Models;
|
||
using TabletTester2025.Services;
|
||
using TabletTester2025.ViewModels;
|
||
|
||
namespace TabletTester2025
|
||
{
|
||
public partial class App : Application
|
||
{
|
||
public static IPlcService PlcService { get; private set; }
|
||
public static PlcConfiguration PlcConfig { get; private set; }
|
||
public static PharmaParameters CurrentPharmaParams { get; set; } = new PharmaParameters();
|
||
|
||
protected override async void OnStartup(StartupEventArgs e)
|
||
{
|
||
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
base.OnStartup(e);
|
||
|
||
// 读取配置
|
||
var builder = new ConfigurationBuilder()
|
||
.SetBasePath(Directory.GetCurrentDirectory())
|
||
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
|
||
var configuration = builder.Build();
|
||
|
||
// 数据库初始化(手动建表)
|
||
var connectionString = configuration.GetConnectionString("DefaultConnection") ?? "Data Source=TabletTests.db";
|
||
using (var connection = new Microsoft.Data.Sqlite.SqliteConnection(connectionString))
|
||
{
|
||
connection.Open();
|
||
var cmd = connection.CreateCommand();
|
||
cmd.CommandText = @"
|
||
CREATE TABLE IF NOT EXISTS TestBatches (
|
||
Id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||
TestTime TEXT NOT NULL,
|
||
StationId INTEGER NOT NULL,
|
||
SampleName TEXT,
|
||
|
||
-- 硬度
|
||
HardnessAvg REAL,
|
||
HardnessRSD REAL,
|
||
HardnessMax REAL,
|
||
HardnessMin REAL,
|
||
HardnessTestCount INTEGER,
|
||
|
||
-- 脆碎度
|
||
FriabilityLoss REAL,
|
||
FriabilityTargetRpm REAL,
|
||
FriabilityTargetTimeSec INTEGER,
|
||
FriabilityClockwise INTEGER, -- bool 存储为 0/1
|
||
FriabilityRemainingRounds INTEGER,
|
||
WeightBefore REAL,
|
||
WeightAfter REAL,
|
||
|
||
-- 崩解
|
||
DisintegrationTimeSec REAL,
|
||
RemainingTubesAtEnd INTEGER,
|
||
DisintegrationTargetFreq REAL,
|
||
DisintegrationTemp REAL,
|
||
|
||
-- 溶出
|
||
DissolutionChannel TEXT,
|
||
DissolutionRate30Min REAL,
|
||
DissolutionTargetRpm REAL,
|
||
DissolutionRSquared REAL,
|
||
DissolutionSampleInterval INTEGER,
|
||
DissolutionUpDownFreq REAL,
|
||
|
||
-- 综合
|
||
IsQualified INTEGER,
|
||
|
||
-- 各项目单独合格标志
|
||
HardnessPass INTEGER,
|
||
FriabilityPass INTEGER,
|
||
DisintegrationPass INTEGER,
|
||
DissolutionPass INTEGER,
|
||
|
||
-- 测试类型(用于区分报表)
|
||
TestType TEXT
|
||
);
|
||
";
|
||
cmd.ExecuteNonQuery();
|
||
}
|
||
EnsureColumnsExist(connectionString);
|
||
|
||
// 绑定药典参数
|
||
configuration.GetSection("PharmaStandard").Bind(CurrentPharmaParams);
|
||
|
||
// PLC配置
|
||
PlcConfig = configuration.GetSection("Plc").Get<PlcConfiguration>();
|
||
if (PlcConfig == null)
|
||
throw new InvalidOperationException("PLC配置缺失");
|
||
|
||
// 创建PLC服务(真实或模拟)
|
||
if (configuration["Plc:Type"] == "ModbusTcp")
|
||
PlcService = new ModbusTcpPlcService(PlcConfig);
|
||
else
|
||
PlcService = new PlcSimulator();
|
||
|
||
try
|
||
{
|
||
await PlcService.ConnectAsync();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show($"PLC连接失败,将使用模拟模式。\n{ex.Message}", "警告", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||
PlcService = new PlcSimulator();
|
||
await PlcService.ConnectAsync();
|
||
}
|
||
|
||
// 业务服务
|
||
var dbService = new DatabaseService(connectionString);
|
||
var excelService = new ExcelExportService();
|
||
var alarmService = new AlarmService();
|
||
|
||
// 主窗口
|
||
var mainWindow = new MainWindow();
|
||
mainWindow.DataContext = new MainViewModel(PlcService, dbService, excelService, alarmService, PlcConfig);
|
||
MainWindow = mainWindow;
|
||
mainWindow.Show();
|
||
}
|
||
|
||
private void EnsureColumnsExist(string connectionString)
|
||
{
|
||
var requiredColumns = new[]
|
||
{
|
||
("TestBatches", "HardnessMax", "REAL", "0"),
|
||
("TestBatches", "HardnessMin", "REAL", "0"),
|
||
("TestBatches", "HardnessTestCount", "INTEGER", "6"),
|
||
("TestBatches", "FriabilityTargetRpm", "REAL", "25"),
|
||
("TestBatches", "FriabilityTargetTimeSec", "INTEGER", "240"),
|
||
("TestBatches", "FriabilityClockwise", "INTEGER", "1"),
|
||
("TestBatches", "FriabilityRemainingRounds", "INTEGER", "100"),
|
||
("TestBatches", "WeightBefore", "REAL", "0"),
|
||
("TestBatches", "WeightAfter", "REAL", "0"),
|
||
("TestBatches", "DisintegrationTargetFreq", "REAL", "31"),
|
||
("TestBatches", "DisintegrationTemp", "REAL", "37"),
|
||
("TestBatches", "DissolutionChannel", "TEXT", "''"),
|
||
("TestBatches", "DissolutionTargetRpm", "REAL", "50"),
|
||
("TestBatches", "DissolutionRSquared", "REAL", "0"),
|
||
("TestBatches", "DissolutionSampleInterval", "INTEGER", "5"),
|
||
("TestBatches", "DissolutionUpDownFreq", "REAL", "32"),
|
||
("TestBatches", "HardnessRSD", "REAL", "0"), // 已存在但确保
|
||
("TestBatches", "RemainingTubesAtEnd", "INTEGER", "0"),
|
||
// 新增合格列
|
||
("TestBatches", "HardnessPass", "INTEGER", "0"),
|
||
("TestBatches", "FriabilityPass", "INTEGER", "0"),
|
||
("TestBatches", "DisintegrationPass", "INTEGER", "0"),
|
||
("TestBatches", "DissolutionPass", "INTEGER", "0"),
|
||
|
||
("TestBatches", "TestType", "TEXT", "")
|
||
};
|
||
|
||
using var connection = new SqliteConnection(connectionString);
|
||
connection.Open();
|
||
|
||
foreach (var (table, column, colType, defaultValue) in requiredColumns)
|
||
{
|
||
// 检查列是否存在
|
||
var pragmaCmd = connection.CreateCommand();
|
||
pragmaCmd.CommandText = $"PRAGMA table_info({table})";
|
||
using var reader = pragmaCmd.ExecuteReader();
|
||
bool columnExists = false;
|
||
while (reader.Read())
|
||
{
|
||
if (reader.GetString(1) == column)
|
||
{
|
||
columnExists = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!columnExists)
|
||
{
|
||
// 添加缺失的列
|
||
var alterCmd = connection.CreateCommand();
|
||
alterCmd.CommandText = $"ALTER TABLE {table} ADD COLUMN {column} {colType} DEFAULT {defaultValue}";
|
||
alterCmd.ExecuteNonQuery();
|
||
System.Diagnostics.Debug.WriteLine($"已添加缺失的列: {table}.{column}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|