Final
This commit is contained in:
@@ -156,7 +156,6 @@
|
|||||||
<DependentUpon>Model1.tt</DependentUpon>
|
<DependentUpon>Model1.tt</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Services\AuthService.cs" />
|
<Compile Include="Services\AuthService.cs" />
|
||||||
<Compile Include="Services\DelegateCommand.cs" />
|
|
||||||
<Compile Include="Services\InverseBooleanConverter.cs" />
|
<Compile Include="Services\InverseBooleanConverter.cs" />
|
||||||
<Compile Include="Services\InverseBoolToVisConverter.cs" />
|
<Compile Include="Services\InverseBoolToVisConverter.cs" />
|
||||||
<Compile Include="Services\NullToVisibilityConverter.cs" />
|
<Compile Include="Services\NullToVisibilityConverter.cs" />
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -48,7 +48,7 @@ namespace Labaratory.ViewModels
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_updatePhotoCommand == null)
|
if (_updatePhotoCommand == null)
|
||||||
_updatePhotoCommand = new Services.RelayCommand<object>(obj => AuthService.UpdatePhoto("Admin.png"));
|
_updatePhotoCommand = new RelayCommand<object>(obj => AuthService.UpdatePhoto("Admin.png"));
|
||||||
return _updatePhotoCommand;
|
return _updatePhotoCommand;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,7 +97,7 @@ namespace Labaratory.ViewModels
|
|||||||
{
|
{
|
||||||
if (_saveUserCommand == null)
|
if (_saveUserCommand == null)
|
||||||
{
|
{
|
||||||
_saveUserCommand = new Services.RelayCommand<object>(obj => SaveUser());
|
_saveUserCommand = new RelayCommand<object>(obj => SaveUser());
|
||||||
}
|
}
|
||||||
return _saveUserCommand;
|
return _saveUserCommand;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,92 +2,53 @@
|
|||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Labaratory.Models;
|
using Labaratory.Models;
|
||||||
using Labaratory.Services;
|
using Labaratory.Services;
|
||||||
|
using Wpf.Ui.Input;
|
||||||
|
|
||||||
namespace Labaratory.ViewModels
|
namespace Labaratory.ViewModels
|
||||||
{
|
{
|
||||||
public class LaborantExplorer : BaseViewModel
|
public class LaborantExplorer : BaseViewModel
|
||||||
{
|
{
|
||||||
private LaboratoryDBEntities _db = new LaboratoryDBEntities(); // Ваш контекст Entity Framework
|
private LaboratoryDBEntities _db = new LaboratoryDBEntities();
|
||||||
private Analyzer _selectedAnalyzer;
|
public ObservableCollection<Service> Services { get; set; }
|
||||||
|
|
||||||
public Models.User CurrentUser { get; set; }
|
|
||||||
|
|
||||||
// Список доступных анализаторов
|
|
||||||
public ObservableCollection<Analyzer> Analyzers { 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
|
// Свойства для прогресса
|
||||||
{
|
private double _progress;
|
||||||
get => _selectedAnalyzer;
|
public double Progress { get => _progress; set { _progress = value; OnPropertyChanged(); } }
|
||||||
set
|
|
||||||
{
|
|
||||||
_selectedAnalyzer = value;
|
|
||||||
OnPropertyChanged();
|
|
||||||
LoadServices(); // Загружаем услуги при выборе прибора
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public LaborantExplorer(Models.User user)
|
private bool _isBusy;
|
||||||
{
|
public bool IsBusy { get => _isBusy; set { _isBusy = value; OnPropertyChanged(); } }
|
||||||
CurrentUser = user;
|
|
||||||
LoadInitialData();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LoadInitialData()
|
public LaborantExplorer(User user)
|
||||||
{
|
{
|
||||||
// Загрузка анализаторов из БД
|
Services = new ObservableCollection<Service>(_db.Services.ToList());
|
||||||
Analyzers = new ObservableCollection<Analyzer>(_db.Analyzers.ToList());
|
Analyzers = new ObservableCollection<Analyzer>(_db.Analyzers.ToList());
|
||||||
|
|
||||||
|
StartCommand = new RelayCommand<object>(async (p) => await RunTimer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LoadServices()
|
public ICommand StartCommand { get; }
|
||||||
|
|
||||||
|
private async Task RunTimer()
|
||||||
{
|
{
|
||||||
var services = _db.Services.ToList();
|
if (SelectedService == null || SelectedAnalyzer == null || IsBusy) return;
|
||||||
|
|
||||||
PendingServices = new ObservableCollection<Service>(services);
|
IsBusy = true;
|
||||||
OnPropertyChanged(nameof(PendingServices));
|
for (int i = 0; i <= 100; i++)
|
||||||
}
|
|
||||||
|
|
||||||
public ICommand SendToResearchCommand => new DelegateCommand<Service>(async (service) =>
|
|
||||||
{
|
{
|
||||||
if (SelectedAnalyzer.IsBusy)
|
Progress = i;
|
||||||
{
|
await Task.Delay(600);
|
||||||
MessageBox.Show("Анализатор занят!");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
IsBusy = false;
|
||||||
|
|
||||||
service.IsProcessing = true;
|
System.Windows.MessageBox.Show("Готово!");
|
||||||
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;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,25 @@
|
|||||||
</Window.Resources>
|
</Window.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<TabControl>
|
<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="Анализатор">
|
<TabItem Header="Анализатор">
|
||||||
<Grid Margin="20">
|
<Grid Margin="20">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
@@ -20,70 +39,62 @@
|
|||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<StackPanel Grid.Column ="0" Margin="0,0,10,0">
|
<StackPanel Grid.Column="0">
|
||||||
<TextBlock Text="Доступные анализаторы" FontSize="18" Margin="0,0,0,10"/>
|
<TextBlock Text="Выберите анализатор" Margin="10,10,10,0"/>
|
||||||
<ListBox ItemsSource="{Binding Analyzers}" SelectedItem="{Binding SelectedAnalyzer}">
|
<ComboBox Margin="10"
|
||||||
<ListBox.ItemTemplate>
|
ItemsSource="{Binding Analyzers}"
|
||||||
<DataTemplate>
|
SelectedItem="{Binding SelectedAnalyzer}"
|
||||||
<StackPanel Orientation="Horizontal">
|
DisplayMemberPath="AnalyzerName"/>
|
||||||
<ui:SymbolIcon Symbol="DeveloperBoard24"/>
|
|
||||||
<TextBlock Text="{Binding Name}" Margin="10,0"/>
|
<TextBlock Text="Выберите образец" Margin="10,10,10,0"/>
|
||||||
<ui:Badge Appearance="Success" Visibility="{Binding IsBusy, Converter={StaticResource InverseBoolToVis}}"/>
|
<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>
|
||||||
</DataTemplate>
|
<StackPanel Grid.Column="1" VerticalAlignment="Center">
|
||||||
</ListBox.ItemTemplate>
|
<StackPanel Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityConverter}}">
|
||||||
</ListBox>
|
<ui:ProgressRing Progress="{Binding Progress}"
|
||||||
</StackPanel>
|
IsIndeterminate="False"
|
||||||
|
Width="100" Height="100"/>
|
||||||
<ui:Card Grid.Column="1" VerticalAlignment="Stretch">
|
<TextBlock Text="{Binding Progress, StringFormat={}{0}%}"
|
||||||
<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"
|
HorizontalAlignment="Center"
|
||||||
Visibility="{Binding IsProcessing, Converter={StaticResource InverseBoolToVis}}"/>
|
FontSize="20" Margin="10"/>
|
||||||
</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>
|
||||||
|
|
||||||
|
|
||||||
|
<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>
|
</StackPanel>
|
||||||
</DataTemplate>
|
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
|
||||||
</DataGridTemplateColumn>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</ui:Card>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
</TabControl>
|
</TabControl>
|
||||||
|
|||||||
Reference in New Issue
Block a user