Compare commits

...

2 Commits

Author SHA1 Message Date
Mikan
32a16c9954 update 2025-05-22 21:15:36 +03:00
Mikan
004e3901f2 base auth 2025-05-22 20:26:15 +03:00
21 changed files with 1006 additions and 17 deletions

View File

@@ -4,6 +4,31 @@
xmlns:local="clr-namespace:OfficeFlow" xmlns:local="clr-namespace:OfficeFlow"
StartupUri="MainWindow.xaml"> StartupUri="MainWindow.xaml">
<Application.Resources> <Application.Resources>
<ResourceDictionary>
<!-- Определение стиля для кнопки -->
<Style x:Key="AccentButtonStyle" TargetType="Button">
<Setter Property="Background" Value="#4CAF50" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Padding" Value="10,5" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="5"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#43A047" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>

View File

@@ -1,17 +1,8 @@
using System; using OfficeFlow.Pages;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation; using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow namespace OfficeFlow
{ {
@@ -28,6 +19,10 @@ namespace OfficeFlow
{ {
MainFrame.Navigate(new Pages.StartupPages.InitializeDataPage()); MainFrame.Navigate(new Pages.StartupPages.InitializeDataPage());
} }
else
{
MainFrame.Navigate(new MainPage());
}
} }

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OfficeFlow.Models
{
public partial class User
{
public Role Role {
get
{
return this.User_Role.FirstOrDefault()?.Role;
}
set
{
var userRole = this.User_Role.FirstOrDefault();
if (userRole == null)
{
userRole = new User_Role {
User = this,
};
App.Entities.User_Role.Add(userRole);
}
userRole.Role = value;
}
}
}
}

View File

@@ -64,6 +64,26 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Models\Utils\User.cs" />
<Compile Include="Pages\EmployeePages\EmployeesPage.xaml.cs">
<DependentUpon>EmployeesPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\EmployeePages\EmployeesPositionsPage.xaml.cs">
<DependentUpon>EmployeesPositionsPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\EmployeePages\NewEmployeePage.xaml.cs">
<DependentUpon>NewEmployeePage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\EmployeePages\NewUserPage.xaml.cs">
<DependentUpon>NewUserPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\LoginPage.xaml.cs">
<DependentUpon>LoginPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>
<Compile Include="Utils\Session.cs" />
<Page Include="MainWindow.xaml"> <Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@@ -76,6 +96,30 @@
<DependentUpon>MainWindow.xaml</DependentUpon> <DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Page Include="Pages\EmployeePages\EmployeesPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\EmployeePages\EmployeesPositionsPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\EmployeePages\NewEmployeePage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\EmployeePages\NewUserPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\LoginPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\MainPage.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Pages\StartupPages\CreateAdministratorPage.xaml"> <Page Include="Pages\StartupPages\CreateAdministratorPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@@ -0,0 +1,14 @@
<Page x:Class="OfficeFlow.Pages.EmployeePages.EmployeesPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages.EmployeePages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="EmployeesPage">
<Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages.EmployeePages
{
/// <summary>
/// Interaction logic for EmployeesPage.xaml
/// </summary>
public partial class EmployeesPage : Page
{
public EmployeesPage()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,14 @@
<Page x:Class="OfficeFlow.Pages.EmployeePages.EmployeesPositionsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages.EmployeePages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="EmployeesPositionsPage">
<Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages.EmployeePages
{
/// <summary>
/// Interaction logic for EmployeesPositionsPage.xaml
/// </summary>
public partial class EmployeesPositionsPage : Page
{
public EmployeesPositionsPage()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,14 @@
<Page x:Class="OfficeFlow.Pages.EmployeePages.NewEmployeePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages.EmployeePages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="NewEmployeePage">
<Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages.EmployeePages
{
/// <summary>
/// Interaction logic for NewEmployeePage.xaml
/// </summary>
public partial class NewEmployeePage : Page
{
public NewEmployeePage()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,14 @@
<Page x:Class="OfficeFlow.Pages.EmployeePages.NewUserPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages.EmployeePages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="NewUserPage">
<Grid>
</Grid>
</Page>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages.EmployeePages
{
/// <summary>
/// Interaction logic for NewUserPage.xaml
/// </summary>
public partial class NewUserPage : Page
{
public NewUserPage()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,46 @@
<Page x:Class="OfficeFlow.Pages.LoginPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="Вход в систему">
<Grid Margin="10">
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Заголовок -->
<TextBlock Text="Вход в систему" FontSize="20" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,0,0,20"/>
<!-- Логин -->
<StackPanel Grid.Row="1" Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="Логин:" FontSize="14" Margin="0,0,0,5"/>
<TextBox x:Name="LoginTextBox" Height="30" VerticalContentAlignment="Center" Margin="0,0,0,10"/>
</StackPanel>
<!-- Пароль -->
<StackPanel Grid.Row="2" Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="Пароль:" FontSize="14" Margin="0,0,0,5"/>
<PasswordBox x:Name="PasswordBox" Height="30" VerticalContentAlignment="Center" Margin="0,0,0,10"/>
</StackPanel>
<!-- Кнопка входа -->
<Button Grid.Row="3" Content="Войти" Width="100" Height="35" Click="LoginButton_Click" Background="#4CAF50" Foreground="White" HorizontalAlignment="Center"/>
<!-- Текст ошибки -->
<TextBlock x:Name="ErrorMessage" Grid.Row="4" Text="" Foreground="Red" FontSize="12" HorizontalAlignment="Center" Margin="0,10,0,0" Visibility="Collapsed"/>
</Grid>
</StackPanel>
</Grid>
</Page>

View File

@@ -0,0 +1,68 @@
using OfficeFlow.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages
{
/// <summary>
/// Interaction logic for LoginPage.xaml
/// </summary>
public partial class LoginPage : Page
{
public LoginPage()
{
InitializeComponent();
}
private void LoginButton_Click(object sender, RoutedEventArgs e)
{
try
{
Session.Authenticate(App.Entities.Users.FirstOrDefault());
}
finally
{
NavigationService.Navigate(new MainPage());
}
string login = LoginTextBox.Text.Trim();
string password = PasswordBox.Password;
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))
{
ErrorMessage.Text = "Заполните все поля.";
ErrorMessage.Visibility = Visibility.Visible;
return;
}
try
{
Session.Authenticate(login, password);
NavigationService.Navigate(new MainPage());
}
catch (Exception)
{
ErrorMessage.Text = "Неверный логин или пароль.";
ErrorMessage.Visibility = Visibility.Visible;
}
}
}
}

View File

@@ -0,0 +1,55 @@
<Page x:Class="OfficeFlow.Pages.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:OfficeFlow.Pages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="Главная" Loaded="Page_Loaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Header Section -->
<DockPanel Background="#2d3436" Height="60">
<StackPanel>
<Menu FontSize="14" x:Name="MainMenu">
<MenuItem Header="Справка">
<MenuItem Header="О программе" x:Name="MenuItemAbout" Click="MenuItemAbout_Click"/>
</MenuItem>
</Menu>
<TextBlock Text="OfficeFlow - Главная" Foreground="White" FontSize="20"
VerticalAlignment="Center" Margin="20,0,0,0"/>
</StackPanel>
</DockPanel>
<!-- Main Content -->
<StackPanel Grid.Row="1" Margin="20">
<TextBlock Text="Добро пожаловать в OfficeFlow!" FontSize="24" FontWeight="Bold" Margin="0,0,0,10"/>
<TextBlock Text="Здесь вы можете управлять данными об аренде, клиентах и услугах." FontSize="16" Margin="0,0,0,20"/>
<!-- Quick Access Buttons -->
<WrapPanel Orientation="Horizontal" HorizontalAlignment="Left" Margin="0,0,0,20">
<Button Content="Управление клиентами" Width="150" Height="40" Margin="5" Style="{StaticResource AccentButtonStyle}"/>
<Button Content="Управление помещениями" Width="150" Height="40" Margin="5" Style="{StaticResource AccentButtonStyle}"/>
<Button Content="Платежи и счета" Width="150" Height="40" Margin="5" Style="{StaticResource AccentButtonStyle}"/>
</WrapPanel>
<!-- Statistics Section -->
<GroupBox Header="Статистика" Margin="0,0,0,20">
<StackPanel>
<TextBlock Text="Занятых помещений: " FontSize="14" Margin="0,0,0,5"/>
<TextBlock Text="Общая выручка за месяц: " FontSize="14" Margin="0,0,0,5"/>
<TextBlock Text="Количество активных клиентов: " FontSize="14"/>
</StackPanel>
</GroupBox>
</StackPanel>
</Grid>
</Page>

View File

@@ -0,0 +1,154 @@
using OfficeFlow.Pages.EmployeePages;
using OfficeFlow.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace OfficeFlow.Pages
{
/// <summary>
/// Interaction logic for MainPage.xaml
/// </summary>
public partial class MainPage : Page
{
public MainPage()
{
InitializeComponent();
}
public void ReloadMenu()
{
MainMenu.Items.Clear();
string roleName = Session.CurrentUser.Role.RoleName;
if (roleName == "Администратор")
{
MainMenu.Items.Add(CreateAdminMenu());
}
var aboutMenuItem = new MenuItem
{
Header = "Справка",
};
aboutMenuItem.Click += MenuItemAbout_Click;
MainMenu.Items.Add(
aboutMenuItem
);
}
private MenuItem CreateAdminMenu()
{
MenuItem adminMenuItem = new MenuItem
{
Name = "MenuItemAdmin",
Header = "Администрирование"
};
var empl = new MenuItem
{
Header = "Сотрудники",
};
empl.Click += (object sender, RoutedEventArgs e) => NavigationService.Navigate(new EmployeesPage());
adminMenuItem.Items.Add(empl);
var emplPositions = new MenuItem
{
Header = "Должности",
};
emplPositions.Click += (object sender, RoutedEventArgs e) => NavigationService.Navigate(new EmployeesPositionsPage());
adminMenuItem.Items.Add(emplPositions);
var users = new MenuItem
{
Header = "Учётные записи",
};
users.Click += (object sender, RoutedEventArgs e) => throw new NotImplementedException();
adminMenuItem.Items.Add(users);
var tmp = new MenuItem
{
Header = "Кабинеты",
};
tmp.Click += (object sender, RoutedEventArgs e) => throw new NotImplementedException();
adminMenuItem.Items.Add(tmp);
tmp = new MenuItem
{
Header = "Услуги",
};
tmp.Click += (object sender, RoutedEventArgs e) => throw new NotImplementedException();
adminMenuItem.Items.Add(tmp);
tmp = new MenuItem
{
Header = "Виды условий оплат",
};
tmp.Click += (object sender, RoutedEventArgs e) => throw new NotImplementedException();
adminMenuItem.Items.Add(tmp);
tmp = new MenuItem
{
Header = "Единицы измерений для услуг",
};
tmp.Click += (object sender, RoutedEventArgs e) => throw new NotImplementedException();
adminMenuItem.Items.Add(tmp);
return adminMenuItem;
}
public void ClearHistory()
{
while (NavigationService.CanGoBack)
{
NavigationService.RemoveBackEntry();
}
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
ClearHistory();
if (Session.CurrentUser == null)
{
NavigationService.Navigate(new LoginPage());
}
else
{
ReloadMenu();
}
}
private void MenuItemAbout_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Программа была сделана в рамках дипломной работы " +
"специальности \"Информационные системы и программирование\".");
}
}
}

View File

@@ -6,9 +6,51 @@
xmlns:local="clr-namespace:OfficeFlow.Pages.StartupPages" xmlns:local="clr-namespace:OfficeFlow.Pages.StartupPages"
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
Title="CreateAdministrator"> Title="Создание главного администратора">
<Grid> <Grid Background="#F5F5F5">
<!-- Основной контейнер -->
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Width="400">
<!-- Заголовок -->
<TextBlock Text="Теперь создадим первого пользователя"
FontSize="20" FontWeight="Bold"
TextAlignment="Center" Margin="0,0,0,20"/>
<!-- Поле для ввода логина -->
<StackPanel Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="Логин:" FontSize="14" FontWeight="SemiBold"/>
<TextBox x:Name="LoginTextBox" Height="30" FontSize="14" Padding="5"/>
</StackPanel>
<!-- Поле для ввода пароля -->
<StackPanel Orientation="Vertical" Margin="0,0,0,10">
<TextBlock Text="Пароль:" FontSize="14" FontWeight="SemiBold"/>
<PasswordBox x:Name="PasswordBox" Height="30" FontSize="14" Padding="5"/>
</StackPanel>
<!-- Поле для ввода email -->
<StackPanel Orientation="Vertical" Margin="0,0,0,20">
<TextBlock Text="Email:" FontSize="14" FontWeight="SemiBold"/>
<TextBox x:Name="EmailTextBox" Height="30" FontSize="14" Padding="5"/>
</StackPanel>
<Button Content="Создать администратора"
Background="#4CAF50" Foreground="White"
FontSize="16" Height="40"
Click="CreateAdministrator_Click"
Cursor="Hand"
x:Name="BCreate"
/>
<!-- Сообщение об ошибке или успехе -->
<TextBlock x:Name="StatusMessage"
Text=""
FontSize="14"
Foreground="Red"
TextAlignment="Center"
Margin="0,10,0,0"
Visibility="Collapsed"/>
</StackPanel>
</Grid> </Grid>
</Page> </Page>

View File

@@ -1,4 +1,6 @@
using System; using OfficeFlow.Models;
using OfficeFlow.Utils;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -24,5 +26,102 @@ namespace OfficeFlow.Pages.StartupPages
{ {
InitializeComponent(); InitializeComponent();
} }
private void CreateAdministrator_Click(object sender, RoutedEventArgs e)
{
// Получаем значения из полей
string login = LoginTextBox.Text.Trim();
string password = PasswordBox.Password.Trim();
string email = EmailTextBox.Text.Trim();
// Проверяем, что все поля заполнены
if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(email))
{
ShowStatusMessage("Ошибка: заполните все поля.", true);
return;
}
// Простая валидация email
if (!IsValidEmail(email))
{
ShowStatusMessage("Ошибка: введите корректный email.", true);
return;
}
bool success = false;
using (var transaction = App.Entities.Database.BeginTransaction())
{
// Логика создания администратора (например, сохранение в базу данных)
try
{
var newUser = Session.CreateUser(login, password, App.Entities.Roles.Where((r) => r.RoleName == "Администратор").First(), email);
App.Entities.SaveChanges();
// Фиксируем транзакцию
transaction.Commit();
ShowStatusMessage("Администратор успешно создан!", false);
ClearFields();
Session.Authenticate(newUser);
success = true;
}
catch (Exception ex)
{
transaction.Rollback();
ShowStatusMessage($"Ошибка: {ex.Message}", true);
}
}
if (success)
{
NavigationService.Navigate(new MainPage());
}
}
private bool IsValidEmail(string email)
{
if (string.IsNullOrEmpty(email))
{
return true;
}
try
{
var addr = new System.Net.Mail.MailAddress(email);
return addr.Address == email;
}
catch
{
return false;
}
}
private void ShowStatusMessage(string message, bool isError)
{
StatusMessage.Text = message;
StatusMessage.Foreground = isError ? Brushes.Red : Brushes.Green;
StatusMessage.Visibility = Visibility.Visible;
}
private void ClearFields()
{
LoginTextBox.Clear();
PasswordBox.Clear();
EmailTextBox.Clear();
}
} }
} }

View File

@@ -17,7 +17,9 @@
<TextBlock Text="Нажмите кнопку ниже, чтобы создать стартовые данные." <TextBlock Text="Нажмите кнопку ниже, чтобы создать стартовые данные."
FontSize="14" Margin="0,0,0,20" /> FontSize="14" Margin="0,0,0,20" />
<Button Content="Инициализировать стартовые данные" <Button Content="Инициализировать стартовые данные"
Width="250" Height="40" Click="Button_Click"/> Width="250" Height="40" Click="Button_Click"
Background="#4CAF50" Foreground="White"
/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Page> </Page>

View File

@@ -32,6 +32,12 @@ namespace OfficeFlow.Pages.StartupPages
var needAccountStatuses = App.Entities.AccountStatuses.Count() == 0; var needAccountStatuses = App.Entities.AccountStatuses.Count() == 0;
var needEmployeeStatuses = App.Entities.EmployeeStatuses.Count() == 0; var needEmployeeStatuses = App.Entities.EmployeeStatuses.Count() == 0;
var needPaymentTerms = App.Entities.PaymentTerms.Count() == 0;
var needPaymentStatuses = App.Entities.PaymentStatuses.Count() == 0;
var needTenantStatuses = App.Entities.TenantStatuses.Count() == 0;
var needRentalStatuses = App.Entities.RentalStatuses.Count() == 0;
var needRoomStatuses = App.Entities.RoomStatuses.Count() == 0;
using (var transaction = App.Entities.Database.BeginTransaction()) using (var transaction = App.Entities.Database.BeginTransaction())
{ {
@@ -131,6 +137,133 @@ namespace OfficeFlow.Pages.StartupPages
}); });
} }
// Заполнение условий оплаты
if (needPaymentTerms)
{
App.Entities.PaymentTerms.Add(new PaymentTerm()
{
TermName = "Ежемесячно",
TermDescription = "Оплата производится один раз в месяц."
});
App.Entities.PaymentTerms.Add(new PaymentTerm()
{
TermName = "Ежеквартально",
TermDescription = "Оплата производится один раз в квартал (3 месяца)."
});
App.Entities.PaymentTerms.Add(new PaymentTerm()
{
TermName = "Ежегодно",
TermDescription = "Оплата производится один раз в год."
});
App.Entities.PaymentTerms.Add(new PaymentTerm()
{
TermName = "По факту",
TermDescription = "Оплата производится после предоставления услуги."
});
}
// Заполнение статусов платежей
if (needPaymentStatuses)
{
App.Entities.PaymentStatuses.Add(new PaymentStatus()
{
StatusName = "Оплачен",
StatusDescription = "Платеж успешно проведен."
});
App.Entities.PaymentStatuses.Add(new PaymentStatus()
{
StatusName = "Не оплачен",
StatusDescription = "Платеж ожидает оплаты."
});
App.Entities.PaymentStatuses.Add(new PaymentStatus()
{
StatusName = "Частично оплачен",
StatusDescription = "Платеж частично покрыт."
});
App.Entities.PaymentStatuses.Add(new PaymentStatus()
{
StatusName = "Отменен",
StatusDescription = "Платеж отменен."
});
}
// Заполнение статусов арендаторов
if (needTenantStatuses)
{
App.Entities.TenantStatuses.Add(new TenantStatus()
{
StatusName = "Активен",
StatusDescription = "Арендатор активно пользуется услугами."
});
App.Entities.TenantStatuses.Add(new TenantStatus()
{
StatusName = "Неактивен",
StatusDescription = "Арендатор временно не использует услуги."
});
App.Entities.TenantStatuses.Add(new TenantStatus()
{
StatusName = "Заблокирован",
StatusDescription = "Арендатор заблокирован из-за нарушений."
});
App.Entities.TenantStatuses.Add(new TenantStatus()
{
StatusName = "Ожидает подтверждения",
StatusDescription = "Арендатор зарегистрирован, но его статус ожидает подтверждения."
});
}
// Заполнение статусов аренды
if (needRentalStatuses)
{
App.Entities.RentalStatuses.Add(new RentalStatus()
{
StatusName = "Активна",
StatusDescription = "Аренда действует и оплачивается."
});
App.Entities.RentalStatuses.Add(new RentalStatus()
{
StatusName = "Завершена",
StatusDescription = "Аренда завершена и больше не действует."
});
App.Entities.RentalStatuses.Add(new RentalStatus()
{
StatusName = "Просрочена",
StatusDescription = "Аренда просрочена и требует оплаты."
});
App.Entities.RentalStatuses.Add(new RentalStatus()
{
StatusName = "Резерв",
StatusDescription = "Помещение зарезервировано, но аренда еще не началась."
});
}
// Заполнение статусов помещений
if (needRoomStatuses)
{
App.Entities.RoomStatuses.Add(new RoomStatus()
{
StatusName = "Свободно",
StatusDescription = "Помещение свободно для аренды."
});
App.Entities.RoomStatuses.Add(new RoomStatus()
{
StatusName = "Занято",
StatusDescription = "Помещение занято арендатором."
});
App.Entities.RoomStatuses.Add(new RoomStatus()
{
StatusName = "В ремонте",
StatusDescription = "Помещение находится в ремонте и недоступно для аренды."
});
App.Entities.RoomStatuses.Add(new RoomStatus()
{
StatusName = "Резерв",
StatusDescription = "Помещение зарезервировано, но аренда еще не началась."
});
}
App.Entities.SaveChanges(); App.Entities.SaveChanges();
transaction.Commit(); transaction.Commit();

121
OfficeFlow/Utils/Session.cs Normal file
View File

@@ -0,0 +1,121 @@
using OfficeFlow.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace OfficeFlow.Utils
{
public static class Session
{
// Текущий авторизованный пользователь
public static User CurrentUser { get; private set; }
/// <summary>
/// Авторизация пользователя по логину и паролю
/// </summary>
/// <param name="login">Логин пользователя</param>
/// <param name="password">Пароль пользователя</param>
/// <returns>True, если авторизация успешна</returns>
public static bool Authenticate(string login, string password)
{
try
{
// Находим пользователя по логину
var user = App.Entities.Users.FirstOrDefault(u => u.Login == login);
if (user == null)
{
throw new Exception("Пользователь с таким логином не найден.");
}
// Проверяем пароль
if (!String.Equals(HashPassword(password), user.PasswordHash))//!BCrypt.Verify(password, user.PasswordHash))
{
throw new Exception("Неверный пароль.");
}
// Устанавливаем текущего пользователя
CurrentUser = user;
return true;
}
catch (Exception ex)
{
throw new Exception($"Ошибка авторизации: {ex.Message}");
}
}
/// <summary>
/// Создание нового пользователя
/// </summary>
/// <param name="login">Логин</param>
/// <param name="password">Пароль</param>
/// <param name="email">Email</param>
/// <returns>Созданный пользователь</returns>
public static User CreateUser(string login, string password, Role role, string email=null)
{
try
{
// Проверяем уникальность логина и email
if (App.Entities.Users.Any(u => u.Login == login))
{
throw new Exception("Пользователь с таким логином уже существует.");
}
if (App.Entities.Users.Any(u => u.Email == email))
{
throw new Exception("Пользователь с таким email уже существует.");
}
// Создаем нового пользователя
var newUser = new User
{
Login = login,
PasswordHash = HashPassword(password), // Хэшируем пароль
Email = email,
AccountStatusID = App.Entities.AccountStatuses.Where((acs) => acs.StatusName == "Активен").First().StatusID
};
App.Entities.Users.Add(newUser);
App.Entities.User_Role.Add(
new User_Role
{
Role = role,
User = newUser
}
);
// Возвращаем созданного пользователя
return newUser;
}
catch (Exception ex)
{
throw new Exception($"Ошибка при создании пользователя: {ex.Message}");
}
}
/// <summary>
/// Хэширование пароля
/// </summary>
/// <param name="password">Пароль</param>
/// <returns>Хэшированный пароль</returns>
private static string HashPassword(string password)
{
return password.GetHashCode().ToString();
}
/// <summary>
/// Выход из системы (очистка текущего пользователя)
/// </summary>
public static void Logout()
{
CurrentUser = null;
}
public static bool Authenticate(User user)
{
CurrentUser = user;
return true;
}
}
}