This commit is contained in:
2026-04-29 17:19:25 +05:00
parent d5f0b2a532
commit 2bb648a137
5 changed files with 101 additions and 159 deletions

View File

@@ -156,7 +156,6 @@
<DependentUpon>Model1.tt</DependentUpon>
</Compile>
<Compile Include="Services\AuthService.cs" />
<Compile Include="Services\DelegateCommand.cs" />
<Compile Include="Services\InverseBooleanConverter.cs" />
<Compile Include="Services\InverseBoolToVisConverter.cs" />
<Compile Include="Services\NullToVisibilityConverter.cs" />

View File

@@ -1,29 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace Labaratory.Services
{
public class RelayCommand<T> : ICommand
{
private readonly Action<T> _execute;
private readonly Predicate<T> _canExecute;
public RelayCommand(Action<T> execute, Predicate<T> canExecute = null)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute == null || _canExecute((T)parameter);
public void Execute(object parameter) => _execute((T)parameter);
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
}
}

View File

@@ -48,7 +48,7 @@ namespace Labaratory.ViewModels
get
{
if (_updatePhotoCommand == null)
_updatePhotoCommand = new Services.RelayCommand<object>(obj => AuthService.UpdatePhoto("Admin.png"));
_updatePhotoCommand = new RelayCommand<object>(obj => AuthService.UpdatePhoto("Admin.png"));
return _updatePhotoCommand;
}
}
@@ -97,7 +97,7 @@ namespace Labaratory.ViewModels
{
if (_saveUserCommand == null)
{
_saveUserCommand = new Services.RelayCommand<object>(obj => SaveUser());
_saveUserCommand = new RelayCommand<object>(obj => SaveUser());
}
return _saveUserCommand;
}

View File

@@ -2,92 +2,53 @@
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Labaratory.Models;
using Labaratory.Services;
using Wpf.Ui.Input;
namespace Labaratory.ViewModels
{
public class LaborantExplorer : BaseViewModel
{
private LaboratoryDBEntities _db = new LaboratoryDBEntities(); // Ваш контекст Entity Framework
private Analyzer _selectedAnalyzer;
public Models.User CurrentUser { get; set; }
// Список доступных анализаторов
private LaboratoryDBEntities _db = new LaboratoryDBEntities();
public ObservableCollection<Service> Services { get; set; }
public ObservableCollection<Analyzer> Analyzers { get; set; }
// Список услуг для выбранного анализатора
public ObservableCollection<Service> PendingServices { get; set; }
// Свойства для привязки выбора
public Service SelectedService { get; set; }
public Analyzer SelectedAnalyzer { get; set; }
public Analyzer SelectedAnalyzer
{
get => _selectedAnalyzer;
set
{
_selectedAnalyzer = value;
OnPropertyChanged();
LoadServices(); // Загружаем услуги при выборе прибора
}
}
// Свойства для прогресса
private double _progress;
public double Progress { get => _progress; set { _progress = value; OnPropertyChanged(); } }
public LaborantExplorer(Models.User user)
{
CurrentUser = user;
LoadInitialData();
}
private bool _isBusy;
public bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged(); } }
private void LoadInitialData()
public LaborantExplorer(User user)
{
// Загрузка анализаторов из БД
Services = new ObservableCollection<Service>(_db.Services.ToList());
Analyzers = new ObservableCollection<Analyzer>(_db.Analyzers.ToList());
StartCommand = new RelayCommand<object>(async (p) => await RunTimer());
}
private void LoadServices()
{
var services = _db.Services.ToList();
public ICommand StartCommand { get; }
PendingServices = new ObservableCollection<Service>(services);
OnPropertyChanged(nameof(PendingServices));
}
public ICommand SendToResearchCommand => new DelegateCommand<Service>(async (service) =>
private async Task RunTimer()
{
if (SelectedAnalyzer.IsBusy)
if (SelectedService == null || SelectedAnalyzer == null || IsBusy) return;
IsBusy = true;
for (int i = 0; i <= 100; i++)
{
MessageBox.Show("Анализатор занят!");
return;
Progress = i;
await Task.Delay(600);
}
IsBusy = false;
service.IsProcessing = true;
SelectedAnalyzer.IsBusy = true;
await Task.Run(async () =>
{
Random rng = new Random();
for (int i = 0; i <= 100; i += 10)
{
service.Progress = i;
await Task.Delay(500);
}
// Имитация получения результата
double resultValue = rng.NextDouble() * 100;
service.ResultValue = resultValue.ToString("F2");
// Логика проверки на сбой (отклонение в 3 раза от среднего)
double average = 20.0; // В реальности берем из БД
if (resultValue > average * 3 || resultValue < average / 3)
{
Application.Current.Dispatcher.Invoke(() =>
MessageBox.Show("Внимание: возможен сбой или некачественный биоматериал!"));
}
service.IsProcessing = false;
SelectedAnalyzer.IsBusy = false;
});
});
System.Windows.MessageBox.Show("Готово!");
}
}
}

View File

@@ -13,6 +13,25 @@
</Window.Resources>
<Grid>
<TabControl>
<TabItem Header="Профиль">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center">
<ui:Card Padding="30">
<StackPanel>
<Ellipse Width="150" Height="150" Stroke="{ui:ThemeResource SystemAccentColorPrimaryBrush}" StrokeThickness="2">
<Ellipse.Fill>
<ImageBrush
ImageSource="/Images/LaborantExplorer.png"
Stretch="UniformToFill"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock Text="{Binding CurrentUser.FirstName}" FontSize="20" HorizontalAlignment="Center" Margin="0,15,0,0"/>
<TextBlock Text="{Binding CurrentUser.Surname}" FontSize="24" HorizontalAlignment="Center" FontWeight="Bold"/>
<TextBlock Text="{Binding RoleName}" Foreground="Gray" HorizontalAlignment="Center" Margin="0,5,0,0"/>
</StackPanel>
</ui:Card>
</Grid>
</TabItem>
<TabItem Header="Анализатор">
<Grid Margin="20">
<Grid.ColumnDefinitions>
@@ -20,70 +39,62 @@
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column ="0" Margin="0,0,10,0">
<TextBlock Text="Доступные анализаторы" FontSize="18" Margin="0,0,0,10"/>
<ListBox ItemsSource="{Binding Analyzers}" SelectedItem="{Binding SelectedAnalyzer}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="DeveloperBoard24"/>
<TextBlock Text="{Binding Name}" Margin="10,0"/>
<ui:Badge Appearance="Success" Visibility="{Binding IsBusy, Converter={StaticResource InverseBoolToVis}}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<StackPanel Grid.Column="0">
<TextBlock Text="Выберите анализатор" Margin="10,10,10,0"/>
<ComboBox Margin="10"
ItemsSource="{Binding Analyzers}"
SelectedItem="{Binding SelectedAnalyzer}"
DisplayMemberPath="AnalyzerName"/>
<TextBlock Text="Выберите образец" Margin="10,10,10,0"/>
<ListView Height="120" Margin="10"
ItemsSource="{Binding Services}"
SelectedItem="{Binding SelectedService}"
DisplayMemberPath="ServiceName"/>
<Button Content="Начать исследование"
Command="{Binding StartCommand}"
Margin="10"
Width="220"
HorizontalAlignment="Center">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="IsEnabled" Value="True"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="True">
<Setter Property="IsEnabled" Value="False"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</StackPanel>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<StackPanel Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}">
<ui:ProgressRing Progress="{Binding Progress}"
IsIndeterminate="False"
Width="100" Height="100"/>
<TextBlock Text="{Binding Progress, StringFormat={}{0}%}"
HorizontalAlignment="Center"
FontSize="20" Margin="10"/>
</StackPanel>
<ui:Card Grid.Column="1" VerticalAlignment="Stretch">
<DataGrid ItemsSource="{Binding PendingServices}" AutoGenerateColumns="False" CanUserAddRows="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Услуга" Binding="{Binding Name}" Width="*"/>
<DataGridTemplateColumn Header="Статус/Прогресс" Width="150">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<ui:ProgressRing IsIndeterminate="False"
Progress="{Binding Progress}"
Visibility="{Binding IsProcessing, Converter={StaticResource BooleanToVisibilityConverter}}"
Width="30"
Height="30"/>
<TextBlock Text="Ожидание"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Visibility="{Binding IsProcessing, Converter={StaticResource InverseBoolToVis}}"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Результат" Binding="{Binding ResultValue}" Width="80"/>
<DataGridTemplateColumn Header="Действия" Width="200">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ui:Button Content="Отправить"
Command="{Binding DataContext.SendToResearchCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"
CommandParameter="{Binding}"
Appearance="Primary"
IsEnabled="{Binding IsProcessing, Converter={StaticResource InverseBooleanConverter}}"/>
<StackPanel Orientation="Horizontal" Visibility="{Binding ResultValue, Converter={StaticResource NullToVisibilityConverter}}">
<ui:Button Icon="Checkmark24" Appearance="Success" Margin="5,0"
Command="{Binding DataContext.ApproveCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
<ui:Button Icon="Dismiss24" Appearance="Danger"
Command="{Binding DataContext.RejectCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</ui:Card>
<TextBlock Text="Анализатор свободен"
HorizontalAlignment="Center"
FontSize="16" Foreground="Gray">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding IsBusy}" Value="False">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</StackPanel>
</Grid>
</TabItem>
</TabControl>