Добавьте файлы проекта.

This commit is contained in:
KP9lK 2024-09-11 23:15:31 +03:00
parent 442776dc21
commit 6c009c6aff
42 changed files with 1151 additions and 0 deletions

25
ServiceApp.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.11.35222.181
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ServiceApp", "ServiceApp\ServiceApp.csproj", "{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2BD7127-5A3B-4AF1-89E4-C60B70EB2E6B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A812EF99-15E4-4DD1-A3AD-370E1AB49A94}
EndGlobalSection
EndGlobal

15
ServiceApp/App.axaml Normal file
View File

@ -0,0 +1,15 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ServiceApp.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme />
</Application.Styles>
<Application.Resources>
<SolidColorBrush x:Key="PrimaryColor" Color="#ffffff"/>
<SolidColorBrush x:Key="SecondaryColor" Color="#ffffe1"/>
<SolidColorBrush x:Key="AccentColor" Color="#ff9c1a"/>
</Application.Resources>
</Application>

24
ServiceApp/App.axaml.cs Normal file
View File

@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace ServiceApp
{
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted();
}
}
}

BIN
ServiceApp/Assets/diz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Client
{
public int Id { get; set; }
public string Firstname { get; set; } = null!;
public string Lastname { get; set; } = null!;
public string? Patronymic { get; set; }
public DateOnly? Birthday { get; set; }
public DateTime Registrationdate { get; set; }
public string? Email { get; set; }
public string Phone { get; set; } = null!;
public int Gendercode { get; set; }
public string? Photopath { get; set; }
public virtual ICollection<Clientservice> Clientservices { get; set; } = new List<Clientservice>();
public virtual Gender GendercodeNavigation { get; set; } = null!;
public virtual ICollection<Tag> Tags { get; set; } = new List<Tag>();
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Clientservice
{
public int Id { get; set; }
public int Clientid { get; set; }
public int Serviceid { get; set; }
public DateTime Starttime { get; set; }
public string? Comment { get; set; }
public virtual Client Client { get; set; } = null!;
public virtual ICollection<Documentbyservice> Documentbyservices { get; set; } = new List<Documentbyservice>();
public virtual ICollection<Productsale> Productsales { get; set; } = new List<Productsale>();
public virtual Service Service { get; set; } = null!;
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Documentbyservice
{
public int Id { get; set; }
public int Clientserviceid { get; set; }
public string Documentpath { get; set; } = null!;
public virtual Clientservice Clientservice { get; set; } = null!;
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Gender
{
public int Code { get; set; }
public string? Name { get; set; }
public virtual ICollection<Client> Clients { get; set; } = new List<Client>();
}

View File

@ -0,0 +1,334 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace ServiceApp.EnityModels;
public partial class IsajkinContext : DbContext
{
public IsajkinContext()
{
}
public IsajkinContext(DbContextOptions<IsajkinContext> options)
: base(options)
{
}
public virtual DbSet<Client> Clients { get; set; }
public virtual DbSet<Clientservice> Clientservices { get; set; }
public virtual DbSet<Documentbyservice> Documentbyservices { get; set; }
public virtual DbSet<Gender> Genders { get; set; }
public virtual DbSet<Manufacturer> Manufacturers { get; set; }
public virtual DbSet<Product> Products { get; set; }
public virtual DbSet<Productphoto> Productphotos { get; set; }
public virtual DbSet<Productsale> Productsales { get; set; }
public virtual DbSet<Service> Services { get; set; }
public virtual DbSet<Servicephoto> Servicephotos { get; set; }
public virtual DbSet<Tag> Tags { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see https://go.microsoft.com/fwlink/?LinkId=723263.
=> optionsBuilder.UseNpgsql("Host=45.67.56.214;Port=5454;Username=isajkin;Password=hqD9f9EZ");
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Client>(entity =>
{
entity.HasKey(e => e.Id).HasName("client_pkey");
entity.ToTable("client");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Birthday).HasColumnName("birthday");
entity.Property(e => e.Email)
.HasMaxLength(255)
.HasColumnName("email");
entity.Property(e => e.Firstname)
.HasMaxLength(50)
.HasColumnName("firstname");
entity.Property(e => e.Gendercode).HasColumnName("gendercode");
entity.Property(e => e.Lastname)
.HasMaxLength(50)
.HasColumnName("lastname");
entity.Property(e => e.Patronymic)
.HasMaxLength(50)
.HasColumnName("patronymic");
entity.Property(e => e.Phone)
.HasMaxLength(20)
.HasColumnName("phone");
entity.Property(e => e.Photopath)
.HasMaxLength(1000)
.HasColumnName("photopath");
entity.Property(e => e.Registrationdate)
.HasColumnType("timestamp(6) without time zone")
.HasColumnName("registrationdate");
entity.HasOne(d => d.GendercodeNavigation).WithMany(p => p.Clients)
.HasForeignKey(d => d.Gendercode)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_client_gender");
entity.HasMany(d => d.Tags).WithMany(p => p.Clients)
.UsingEntity<Dictionary<string, object>>(
"Tagofclient",
r => r.HasOne<Tag>().WithMany()
.HasForeignKey("Tagid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_tagofclient_tag"),
l => l.HasOne<Client>().WithMany()
.HasForeignKey("Clientid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_tagofclient_client"),
j =>
{
j.HasKey("Clientid", "Tagid").HasName("tagofclient_pkey");
j.ToTable("tagofclient");
j.IndexerProperty<int>("Clientid").HasColumnName("clientid");
j.IndexerProperty<int>("Tagid").HasColumnName("tagid");
});
});
modelBuilder.Entity<Clientservice>(entity =>
{
entity.HasKey(e => e.Id).HasName("clientservice_pkey");
entity.ToTable("clientservice");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Clientid).HasColumnName("clientid");
entity.Property(e => e.Comment).HasColumnName("comment");
entity.Property(e => e.Serviceid).HasColumnName("serviceid");
entity.Property(e => e.Starttime)
.HasColumnType("timestamp(6) without time zone")
.HasColumnName("starttime");
entity.HasOne(d => d.Client).WithMany(p => p.Clientservices)
.HasForeignKey(d => d.Clientid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_clientservice_client");
entity.HasOne(d => d.Service).WithMany(p => p.Clientservices)
.HasForeignKey(d => d.Serviceid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_clientservice_service");
});
modelBuilder.Entity<Documentbyservice>(entity =>
{
entity.HasKey(e => e.Id).HasName("documentbyservice_pkey");
entity.ToTable("documentbyservice");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Clientserviceid).HasColumnName("clientserviceid");
entity.Property(e => e.Documentpath)
.HasMaxLength(1000)
.HasColumnName("documentpath");
entity.HasOne(d => d.Clientservice).WithMany(p => p.Documentbyservices)
.HasForeignKey(d => d.Clientserviceid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_documentbyservice_clientservice");
});
modelBuilder.Entity<Gender>(entity =>
{
entity.HasKey(e => e.Code).HasName("gender_pkey");
entity.ToTable("gender");
entity.Property(e => e.Code).HasColumnName("code");
entity.Property(e => e.Name)
.HasMaxLength(10)
.HasColumnName("name");
});
modelBuilder.Entity<Manufacturer>(entity =>
{
entity.HasKey(e => e.Id).HasName("manufacturer_pkey");
entity.ToTable("manufacturer");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Name)
.HasMaxLength(100)
.HasColumnName("name");
entity.Property(e => e.Startdate).HasColumnName("startdate");
});
modelBuilder.Entity<Product>(entity =>
{
entity.HasKey(e => e.Id).HasName("product_pkey");
entity.ToTable("product");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Cost)
.HasPrecision(19, 4)
.HasColumnName("cost");
entity.Property(e => e.Description).HasColumnName("description");
entity.Property(e => e.Isactive).HasColumnName("isactive");
entity.Property(e => e.Mainimagepath)
.HasMaxLength(1000)
.HasColumnName("mainimagepath");
entity.Property(e => e.Manufacturerid).HasColumnName("manufacturerid");
entity.Property(e => e.Title)
.HasMaxLength(100)
.HasColumnName("title");
entity.HasOne(d => d.Manufacturer).WithMany(p => p.Products)
.HasForeignKey(d => d.Manufacturerid)
.HasConstraintName("fk_product_manufacturer");
entity.HasMany(d => d.Attachedproducts).WithMany(p => p.Mainproducts)
.UsingEntity<Dictionary<string, object>>(
"Attachedproduct",
r => r.HasOne<Product>().WithMany()
.HasForeignKey("Attachedproductid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_attachedproduct_product1"),
l => l.HasOne<Product>().WithMany()
.HasForeignKey("Mainproductid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_attachedproduct_product"),
j =>
{
j.HasKey("Mainproductid", "Attachedproductid").HasName("attachedproduct_pkey");
j.ToTable("attachedproduct");
j.IndexerProperty<int>("Mainproductid").HasColumnName("mainproductid");
j.IndexerProperty<int>("Attachedproductid").HasColumnName("attachedproductid");
});
entity.HasMany(d => d.Mainproducts).WithMany(p => p.Attachedproducts)
.UsingEntity<Dictionary<string, object>>(
"Attachedproduct",
r => r.HasOne<Product>().WithMany()
.HasForeignKey("Mainproductid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_attachedproduct_product"),
l => l.HasOne<Product>().WithMany()
.HasForeignKey("Attachedproductid")
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_attachedproduct_product1"),
j =>
{
j.HasKey("Mainproductid", "Attachedproductid").HasName("attachedproduct_pkey");
j.ToTable("attachedproduct");
j.IndexerProperty<int>("Mainproductid").HasColumnName("mainproductid");
j.IndexerProperty<int>("Attachedproductid").HasColumnName("attachedproductid");
});
});
modelBuilder.Entity<Productphoto>(entity =>
{
entity.HasKey(e => e.Id).HasName("productphoto_pkey");
entity.ToTable("productphoto");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Photopath)
.HasMaxLength(1000)
.HasColumnName("photopath");
entity.Property(e => e.Productid).HasColumnName("productid");
entity.HasOne(d => d.Product).WithMany(p => p.Productphotos)
.HasForeignKey(d => d.Productid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_productphoto_product");
});
modelBuilder.Entity<Productsale>(entity =>
{
entity.HasKey(e => e.Id).HasName("productsale_pkey");
entity.ToTable("productsale");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Clientserviceid).HasColumnName("clientserviceid");
entity.Property(e => e.Productid).HasColumnName("productid");
entity.Property(e => e.Quantity).HasColumnName("quantity");
entity.Property(e => e.Saledate)
.HasColumnType("timestamp(6) without time zone")
.HasColumnName("saledate");
entity.HasOne(d => d.Clientservice).WithMany(p => p.Productsales)
.HasForeignKey(d => d.Clientserviceid)
.HasConstraintName("fk_productsale_clientservice");
entity.HasOne(d => d.Product).WithMany(p => p.Productsales)
.HasForeignKey(d => d.Productid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_productsale_product");
});
modelBuilder.Entity<Service>(entity =>
{
entity.HasKey(e => e.Id).HasName("service_pkey");
entity.ToTable("service");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Cost)
.HasPrecision(19, 4)
.HasColumnName("cost");
entity.Property(e => e.Description).HasColumnName("description");
entity.Property(e => e.Discount).HasColumnName("discount");
entity.Property(e => e.Durationinminutes).HasColumnName("durationinminutes");
entity.Property(e => e.Mainimagepath)
.HasMaxLength(1000)
.HasColumnName("mainimagepath");
entity.Property(e => e.Title)
.HasMaxLength(100)
.HasColumnName("title");
});
modelBuilder.Entity<Servicephoto>(entity =>
{
entity.HasKey(e => e.Id).HasName("servicephoto_pkey");
entity.ToTable("servicephoto");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Photopath)
.HasMaxLength(1000)
.HasColumnName("photopath");
entity.Property(e => e.Serviceid).HasColumnName("serviceid");
entity.HasOne(d => d.Service).WithMany(p => p.Servicephotos)
.HasForeignKey(d => d.Serviceid)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("fk_servicephoto_service");
});
modelBuilder.Entity<Tag>(entity =>
{
entity.HasKey(e => e.Id).HasName("tag_pkey");
entity.ToTable("tag");
entity.Property(e => e.Id).HasColumnName("id");
entity.Property(e => e.Color)
.HasMaxLength(6)
.IsFixedLength()
.HasColumnName("color");
entity.Property(e => e.Title)
.HasMaxLength(30)
.HasColumnName("title");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Manufacturer
{
public int Id { get; set; }
public string Name { get; set; } = null!;
public DateOnly? Startdate { get; set; }
public virtual ICollection<Product> Products { get; set; } = new List<Product>();
}

View File

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Product
{
public int Id { get; set; }
public string Title { get; set; } = null!;
public decimal Cost { get; set; }
public string? Description { get; set; }
public string? Mainimagepath { get; set; }
public int Isactive { get; set; }
public int? Manufacturerid { get; set; }
public virtual Manufacturer? Manufacturer { get; set; }
public virtual ICollection<Productphoto> Productphotos { get; set; } = new List<Productphoto>();
public virtual ICollection<Productsale> Productsales { get; set; } = new List<Productsale>();
public virtual ICollection<Product> Attachedproducts { get; set; } = new List<Product>();
public virtual ICollection<Product> Mainproducts { get; set; } = new List<Product>();
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Productphoto
{
public int Id { get; set; }
public int Productid { get; set; }
public string Photopath { get; set; } = null!;
public virtual Product Product { get; set; } = null!;
}

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Productsale
{
public int Id { get; set; }
public DateTime Saledate { get; set; }
public int Productid { get; set; }
public int Quantity { get; set; }
public int? Clientserviceid { get; set; }
public virtual Clientservice? Clientservice { get; set; }
public virtual Product Product { get; set; } = null!;
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Service
{
public int Id { get; set; }
public string Title { get; set; } = null!;
public decimal Cost { get; set; }
public int Durationinminutes { get; set; }
public string? Description { get; set; }
public double? Discount { get; set; }
public string? Mainimagepath { get; set; }
public virtual ICollection<Clientservice> Clientservices { get; set; } = new List<Clientservice>();
public virtual ICollection<Servicephoto> Servicephotos { get; set; } = new List<Servicephoto>();
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Servicephoto
{
public int Id { get; set; }
public int Serviceid { get; set; }
public string Photopath { get; set; } = null!;
public virtual Service Service { get; set; } = null!;
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
namespace ServiceApp.EnityModels;
public partial class Tag
{
public int Id { get; set; }
public string Title { get; set; } = null!;
public string Color { get; set; } = null!;
public virtual ICollection<Client> Clients { get; set; } = new List<Client>();
}

View File

@ -0,0 +1,30 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ServiceApp.MainWindow"
x:CompileBindings="False"
Title="ServiceApp">
<StackPanel
Spacing="20"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Vertical">
<TextBlock>Введите код для перехода в режим авдминистратора</TextBlock>
<TextBox Name="CodeTextBox" Width="150"/>
<StackPanel
Spacing="10"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button
Click="LoginAdminButton_Click"
Name="LoginAdminButton"
>Войти</Button>
<Button
Click="LoginClientButton_Click"
Name="LoginClientButton"
>Режим клиента</Button>
</StackPanel>
</StackPanel>
</Window>

View File

@ -0,0 +1,27 @@
using Avalonia.Controls;
namespace ServiceApp
{
public partial class MainWindow : Window
{
private string _secretCode = "0000";
public MainWindow()
{
InitializeComponent();
}
private void LoginClientButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
new ServiceWindow().Show();
this.Close();
}
private void LoginAdminButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
if (CodeTextBox.Text == _secretCode) {
new ServiceAdminWindow().Show();
this.Close();
}
}
}
}

22
ServiceApp/Program.cs Normal file
View File

@ -0,0 +1,22 @@
using Avalonia;
using System;
namespace ServiceApp
{
internal class Program
{
// Initialization code. Don't use any Avalonia, third-party APIs or any
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
// yet and stuff might break.
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
}
}

View File

@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<None Remove="Assets\download.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="11.1.0" />
<PackageReference Include="Avalonia.Desktop" Version="11.1.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.0" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.1.0" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="ServiceWindowAdmin.axaml.cs">
<DependentUpon>ServiceWindowAdmin.axaml</DependentUpon>
</Compile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,62 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:CompileBindings="False"
x:Class="ServiceApp.ServiceWindow"
Title="ServiceWindow">
<DockPanel>
<Border
DockPanel.Dock="Top"
Name="SearchPanel">
<StackPanel
HorizontalAlignment="Center"
Orientation="Horizontal"
Spacing="20">
<TextBox
Name="SearchTextBox"
Width="200"
TextChanged="SearchTextBox_TextChanged"
/>
<ComboBox
Width="150"
Name="SortingComboBox"
SelectionChanged="SortingComboBox_SelectionChanged"/>
<ComboBox
Width="150"
SelectionChanged="FilteringComboBox_SelectionChanged"
Name="FilteringComboBox"/>
</StackPanel>
</Border>
<Border
DockPanel.Dock="Bottom"
Name="StatisticPanel">
<StackPanel
HorizontalAlignment="Center"
Orientation="Horizontal"
>
<TextBlock Name="StatisticTextBlock">Статистика</TextBlock>
</StackPanel>
</Border>
<Border Name="MainPanel">
<ListBox Name="ServiceListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Spacing="20">
<Image Source="{Binding ServiceImage}" Width="100" Height="100"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ServiceName}"/>
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="{Binding OldCost}" TextDecorations="Strikethrough"/>
<TextBlock Text="{Binding SeviceCostPerSeconds}" />
</StackPanel>
<TextBlock Text="{Binding ServiceDiscount}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Window>

View File

@ -0,0 +1,132 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System.Linq;
using ServiceApp.EnityModels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SkiaSharp;
using Microsoft.EntityFrameworkCore.Storage.Json;
using System;
using Npgsql.TypeMapping;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace ServiceApp;
public partial class ServiceWindow : Window
{
public List<ServicePresenter> sourceList { get; set; }
public ObservableCollection<ServicePresenter> displayList { get; }
private string _searchWord = string.Empty;
private string[] _sortingSource = new string[3] { "îòñóò.", "ïî âîçðàñò.", "ïî óáûâ." };
private Dictionary<string, (int, int)> _dicountFilter = new Dictionary<string, (int, int)> {
{"âñå", (0, 0) },
{ "0-5", (0,5)},
{ "15-30", (5,15)},
{ "30-70", (30,70)},
{ "70-100", (70,100)},
};
public ServiceWindow()
{
InitializeComponent();
using (var dbContext = new IsajkinContext())
{
sourceList = dbContext.Services.Select(service =>
new ServicePresenter
{
Title = service.Title,
Discount = service.Discount,
Durationinminutes = service.Durationinminutes,
Id = service.Id,
Cost = service.Cost,
Mainimagepath = service.Mainimagepath,
}
).ToList();
}
displayList = new ObservableCollection<ServicePresenter>(sourceList);
SortingComboBox.ItemsSource = _sortingSource;
ServiceListBox.ItemsSource = displayList;
FilteringComboBox.ItemsSource = _dicountFilter.Keys;
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayList.Count, sourceList.Count);
}
private void DisplayService() {
var displayServiceList = sourceList;
if (FilteringComboBox.SelectedIndex > 0) displayServiceList = displayServiceList.Where(service =>
FilterByDiscount(service, FilteringComboBox.SelectionBoxItem.ToString())).ToList();
if(!String.IsNullOrEmpty(_searchWord)) displayServiceList = displayServiceList.Where(service => SearchByWord(service, _searchWord)).ToList();
if(SortingComboBox.SelectedIndex > 0) displayServiceList = SortingComboBox.SelectedIndex == 1?
displayServiceList.OrderBy(service => service.Cost).ToList() :
displayServiceList.OrderByDescending(service => service.Cost).ToList();
displayList.Clear();
foreach (var service in displayServiceList) { displayList.Add(service); }
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayServiceList.Count, sourceList.Count);
}
private bool SearchByWord(ServicePresenter service, string word) {
if (service.Title.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
if (String.IsNullOrEmpty(service.Description)) return false;
if (service.Description.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
return false;
}
private bool FilterByDiscount(ServicePresenter servicePresenter, string key) {
(int left, int right) = _dicountFilter[key];
double discount = servicePresenter.Discount != null? Convert.ToDouble(servicePresenter.Discount) * 100 : 0;
return left <= discount && discount < right;
}
private void SearchTextBox_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
{
_searchWord = SearchTextBox.Text.ToString();
DisplayService();
}
private void FilteringComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
{
DisplayService();
}
private void SortingComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
{
DisplayService();
}
}
public class ServicePresenter() : Service
{
public int ServiceID { get => this.Id; }
public string ServiceName { get => this.Title; }
public string SeviceCostPerSeconds { get =>
(this.Discount != 0 ?
String.Format("{0:0.00} ðóáëåé çà {1} ìèíóò", this.Cost - this.Cost * Convert.ToDecimal(this.Discount), this.Durationinminutes)
:
String.Format("{0:0.00} ðóáëåé çà {1} ìèíóò", this.Cost, this.Durationinminutes)
);
}
public Bitmap ServiceImage { get => GetBitmap(this.Mainimagepath); }
public decimal? OldCost { get => (this.Discount != 0 ? this.Cost : null); }
public string? ServiceDiscount { get =>
(this.Discount != 0 ?
String.Format("* ñêèäêà {0}%", Discount * 100)
: String.Empty
); }
private Bitmap GetBitmap(string fileName) {
try {
return new Bitmap($"Assets\\{fileName}");
}
catch (Exception ex) {
return new Bitmap("Assets\\download.png");
}
}
}

View File

@ -0,0 +1,66 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:CompileBindings="False"
x:Class="ServiceApp.ServiceAdminWindow"
Title="ServiceAdminWindow">
<DockPanel>
<Border
DockPanel.Dock="Top"
Name="SearchPanel">
<StackPanel
HorizontalAlignment="Center"
Orientation="Horizontal"
Spacing="20">
<TextBox
Name="SearchTextBox"
Width="200"
TextChanged="SearchTextBox_TextChanged"
/>
<ComboBox
Width="150"
Name="SortingComboBox"
SelectionChanged="SortingComboBox_SelectionChanged"/>
<ComboBox
Width="150"
SelectionChanged="FilteringComboBox_SelectionChanged"
Name="FilteringComboBox"/>
</StackPanel>
</Border>
<Border
DockPanel.Dock="Bottom"
Name="StatisticPanel">
<StackPanel
HorizontalAlignment="Center"
Orientation="Horizontal"
>
<TextBlock Name="StatisticTextBlock">Статистика</TextBlock>
</StackPanel>
</Border>
<Border Name="MainPanel">
<ListBox Name="ServiceListBox">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Spacing="20">
<Image Source="{Binding ServiceImage}" Width="100" Height="100"/>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding ServiceName}"/>
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="{Binding OldCost}" TextDecorations="Strikethrough"/>
<TextBlock Text="{Binding SeviceCostPerSeconds}" />
</StackPanel>
<TextBlock Text="{Binding ServiceDiscount}"/>
<StackPanel Orientation="Horizontal">
<Button Name="EditButton" Click="EditButton_Click" Tag="{Binding ServiceID}">Редактировать</Button>
<Button Name="RemoveButton" Click="RemoveButton_Click" Tag="{Binding ServiceID}">Удалить</Button>
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Window>

View File

@ -0,0 +1,134 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using System.Linq;
using ServiceApp.EnityModels;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SkiaSharp;
using Microsoft.EntityFrameworkCore.Storage.Json;
using System;
using Npgsql.TypeMapping;
using Avalonia.Media.Imaging;
using Avalonia.Platform;
namespace ServiceApp;
public partial class ServiceAdminWindow : Window
{
public List<ServicePresenter> sourceList { get; set; }
public ObservableCollection<ServicePresenter> displayList { get; }
private string _searchWord = string.Empty;
private string[] _sortingSource = new string[3] { "îòñóò.", "ïî âîçðàñò.", "ïî óáûâ." };
private Dictionary<string, (int, int)> _dicountFilter = new Dictionary<string, (int, int)> {
{"âñå", (0, 0) },
{ "0-5", (0,5)},
{ "15-30", (5,15)},
{ "30-70", (30,70)},
{ "70-100", (70,100)},
};
public ServiceAdminWindow()
{
InitializeComponent();
using (var dbContext = new IsajkinContext())
{
sourceList = dbContext.Services.Select(service =>
new ServicePresenter
{
Title = service.Title,
Discount = service.Discount,
Durationinminutes = service.Durationinminutes,
Id = service.Id,
Cost = service.Cost,
Mainimagepath = service.Mainimagepath,
}
).ToList();
}
displayList = new ObservableCollection<ServicePresenter>(sourceList);
SortingComboBox.ItemsSource = _sortingSource;
ServiceListBox.ItemsSource = displayList;
FilteringComboBox.ItemsSource = _dicountFilter.Keys;
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayList.Count, sourceList.Count);
}
private void DisplayService() {
var displayServiceList = sourceList;
if (FilteringComboBox.SelectedIndex > 0) displayServiceList = displayServiceList.Where(service =>
FilterByDiscount(service, FilteringComboBox.SelectionBoxItem.ToString())).ToList();
if(!String.IsNullOrEmpty(_searchWord)) displayServiceList = displayServiceList.Where(service => SearchByWord(service, _searchWord)).ToList();
if(SortingComboBox.SelectedIndex > 0) displayServiceList = SortingComboBox.SelectedIndex == 1?
displayServiceList.OrderBy(service => service.Cost).ToList() :
displayServiceList.OrderByDescending(service => service.Cost).ToList();
displayList.Clear();
foreach (var service in displayServiceList) { displayList.Add(service); }
StatisticTextBlock.Text = String.Format("{0} èç {1}", displayServiceList.Count, sourceList.Count);
}
private bool SearchByWord(ServicePresenter service, string word) {
if (service.Title.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
if (String.IsNullOrEmpty(service.Description)) return false;
if (service.Description.Contains(word, StringComparison.CurrentCultureIgnoreCase)) return true;
return false;
}
private bool FilterByDiscount(ServicePresenter servicePresenter, string key) {
(int left, int right) = _dicountFilter[key];
double discount = servicePresenter.Discount != null? Convert.ToDouble(servicePresenter.Discount) * 100 : 0;
return left <= discount && discount < right;
}
private void SearchTextBox_TextChanged(object? sender, Avalonia.Controls.TextChangedEventArgs e)
{
_searchWord = SearchTextBox.Text.ToString();
DisplayService();
}
private void FilteringComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
{
DisplayService();
}
private void SortingComboBox_SelectionChanged(object? sender, Avalonia.Controls.SelectionChangedEventArgs e)
{
DisplayService();
}
private void EditButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
}
private void RemoveButton_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
var serviceID = Convert.ToInt32((sender as Button).Tag);
using (var dbContext = new IsajkinContext()) {
var service = dbContext.Services.First(service => service.Id == serviceID);
var serviceLocal = displayList.First(service => service.Id == serviceID);
if (service == null) return;
if (dbContext.Clientservices.Where(item => item.Serviceid == serviceID).Count() > 0) return;
using var transaction = dbContext.Database.BeginTransaction();
try
{
if (dbContext.Servicephotos.Where(item => item.Serviceid == serviceID).Count() > 0)
{
dbContext.RemoveRange(dbContext.Servicephotos.Where(item => item.Serviceid == serviceID));
}
dbContext.Services.Remove(service);
displayList.Remove(serviceLocal);
dbContext.SaveChanges();
transaction.Commit();
}
catch (Exception ex) {
}
} ;
}
}

18
ServiceApp/app.manifest Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<!-- This manifest is used on Windows only.
Don't remove it as it might cause problems with window transparency and embedded controls.
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
<assemblyIdentity version="1.0.0.0" name="ServiceApp.Desktop"/>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on
and is designed to work with. Uncomment the appropriate elements
and Windows will automatically select the most compatible environment. -->
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
</assembly>