Загрузка данных
Да. Ниже — такой же компактный гайд, но уже под задание с картинки.
Сделаем по приоритету:
1. SQL-скрипт БД в 3НФ
2. Окно авторизации
3. Основное окно:
• показывает роль пользователя
• показывает пациентов
• показывает результаты исследований
• позволяет вносить новые данные о проведённом исследовании
⸻
Что будет
Приложение для учета лабораторных анализов:
• авторизация лаборанта
• просмотр списка пациентов
• просмотр внесенных исследований
• добавление результата исследования
• отображение имени пользователя и его роли
⸻
Структура БД
Таблицы:
• Roles
• Users
• Patients
• AnalysisTypes
• LabTests
Это 3НФ, потому что:
• роли вынесены отдельно
• типы анализов вынесены отдельно
• пользователи не дублируют названия ролей
• записи исследований хранят только ссылки на пациента, тип анализа и лаборанта
⸻
ERD
Связи такие:
• Roles (1) -> (M) Users
• Users (1) -> (M) LabTests
• Patients (1) -> (M) LabTests
• AnalysisTypes (1) -> (M) LabTests
⸻
Файлы проекта
• App.xaml
• LoginWindow.xaml
• LoginWindow.xaml.cs
• MainWindow.xaml
• MainWindow.xaml.cs
Пакет:
• MySqlConnector
⸻
1. Создай проект
В Visual Studio:
• Create a new project
• WPF App (.NET)
• имя: LabApp
⸻
2. Установи пакет
Через NuGet:
MySqlConnector
⸻
3. Сначала база данных
SQL-скрипт создания БД
Создай БД, например в MySQL Workbench, и выполни:
drop database if exists lab_accounting_db;
create database lab_accounting_db character set utf8mb4 collate utf8mb4_unicode_ci;
use lab_accounting_db;
create table Roles
(
RoleID int primary key auto_increment,
RoleName varchar(50) not null unique
);
create table Users
(
UserID int primary key auto_increment,
Login varchar(50) not null unique,
PasswordHash varchar(100) not null,
FullName varchar(100) not null,
RoleID int not null,
foreign key (RoleID) references Roles(RoleID)
);
create table Patients
(
PatientID int primary key auto_increment,
LastName varchar(50) not null,
FirstName varchar(50) not null,
MiddleName varchar(50) null,
BirthDate date not null,
Gender enum('М','Ж') not null,
Phone varchar(20) null
);
create table AnalysisTypes
(
AnalysisTypeID int primary key auto_increment,
AnalysisName varchar(100) not null unique,
Unit varchar(20) not null,
ReferenceRange varchar(50) not null
);
create table LabTests
(
LabTestID int primary key auto_increment,
PatientID int not null,
AnalysisTypeID int not null,
UserID int not null,
TestDate datetime not null default current_timestamp,
ResultValue decimal(10,2) not null,
CommentText varchar(255) null,
foreign key (PatientID) references Patients(PatientID),
foreign key (AnalysisTypeID) references AnalysisTypes(AnalysisTypeID),
foreign key (UserID) references Users(UserID)
);
⸻
Тестовые данные
Не менее 3 тестовых данных есть. Здесь даже больше.
use lab_accounting_db;
insert into Roles (RoleName) values
('Администратор'),
('Лаборант'),
('Врач');
insert into Users (Login, PasswordHash, FullName, RoleID) values
('admin', '1234', 'Иванов Иван Сергеевич', 1),
('lab1', '1234', 'Петрова Анна Викторовна', 2),
('doctor1', '1234', 'Сидоров Алексей Павлович', 3);
insert into Patients (LastName, FirstName, MiddleName, BirthDate, Gender, Phone) values
('Смирнов', 'Олег', 'Игоревич', '1990-04-12', 'М', '+79990000001'),
('Кузнецова', 'Мария', 'Андреевна', '1985-11-03', 'Ж', '+79990000002'),
('Васильев', 'Денис', 'Олегович', '2001-07-21', 'М', '+79990000003');
insert into AnalysisTypes (AnalysisName, Unit, ReferenceRange) values
('Гемоглобин', 'г/л', '120-160'),
('Глюкоза', 'ммоль/л', '3.9-5.5'),
('Лейкоциты', '10^9/л', '4.0-9.0');
insert into LabTests (PatientID, AnalysisTypeID, UserID, TestDate, ResultValue, CommentText) values
(1, 1, 2, '2025-09-01 09:30:00', 145.00, 'Норма'),
(2, 2, 2, '2025-09-01 10:00:00', 6.10, 'Незначительное повышение'),
(3, 3, 2, '2025-09-01 10:30:00', 7.20, 'Норма');
⸻
4. Логика окон
Будет 2 окна:
• LoginWindow — авторизация
• MainWindow — основная работа
После успешного входа:
• открывается основное окно
• показывается ФИО
• показывается роль
• загружаются пациенты и исследования
⸻
5. App.xaml
Замени StartupUri, чтобы сначала открывалось окно логина:
<Application x:Class="LabApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
</Application.Resources>
</Application>
⸻
6. Создай окно LoginWindow
Через:
• Add
• New Item
• Window (WPF)
Имя:
LoginWindow.xaml
⸻
7. LoginWindow.xaml
Замени весь файл:
<Window x:Class="LabApp.LoginWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Авторизация" Height="280" Width="420" WindowStartupLocation="CenterScreen">
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Логин"/>
<TextBox x:Name="tbLogin" Margin="0,25,0,10" Height="30"/>
<TextBlock Grid.Row="1" Text="Пароль"/>
<PasswordBox x:Name="pbPassword" Grid.Row="1" Margin="0,25,0,10" Height="30"/>
<Button Grid.Row="2" Content="Войти" Height="35" Margin="0,10,0,0" Click="LoginClick"/>
<TextBlock x:Name="tbMsg" Grid.Row="3" Margin="0,15,0,0"/>
</Grid>
</Window>
⸻
8. LoginWindow.xaml.cs
Замени весь файл:
using System;
using System.Data;
using System.Windows;
using MySqlConnector;
namespace LabApp
{
public partial class LoginWindow : Window
{
string cs = "Server=localhost;Port=3306;Database=lab_accounting_db;Uid=root;Pwd=12345;";
public LoginWindow()
{
InitializeComponent();
}
DataTable Q(string sql, params MySqlParameter[] p)
{
using var c = new MySqlConnection(cs);
using var m = new MySqlCommand(sql, c);
if (p.Length > 0) m.Parameters.AddRange(p);
using var a = new MySqlDataAdapter(m);
var t = new DataTable();
a.Fill(t);
return t;
}
void LoginClick(object s, RoutedEventArgs e)
{
if (string.IsNullOrWhiteSpace(tbLogin.Text) || string.IsNullOrWhiteSpace(pbPassword.Password))
{
tbMsg.Text = "Введите логин и пароль";
return;
}
try
{
var t = Q(@"
select u.UserID,u.FullName,r.RoleName
from Users u
join Roles r on r.RoleID=u.RoleID
where u.Login=@l and u.PasswordHash=@p",
new("@l", tbLogin.Text.Trim()),
new("@p", pbPassword.Password.Trim()));
if (t.Rows.Count == 0)
{
tbMsg.Text = "Неверный логин или пароль";
return;
}
var row = t.Rows[0];
int userId = Convert.ToInt32(row["UserID"]);
string fullName = row["FullName"].ToString();
string roleName = row["RoleName"].ToString();
var w = new MainWindow(userId, fullName, roleName);
w.Show();
Close();
}
catch (Exception ex)
{
tbMsg.Text = ex.Message;
}
}
}
}
⸻
9. Чтобы приложение стартовало с логина
Открой App.xaml.cs и сделай так:
using System.Windows;
namespace LabApp
{
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
new LoginWindow().Show();
}
}
}
⸻
10. MainWindow.xaml
Замени весь файл:
<Window x:Class="LabApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Учет лабораторных анализов" Height="680" Width="1150" WindowStartupLocation="CenterScreen">
<Grid Margin="15">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border BorderThickness="1" Padding="10" Margin="0,0,0,10">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Польз