������� �� Avalonia 2.0 (�����-���������, ����������, �������� ��������) #1

Merged
Exest merged 18 commits from feature/avalonia-ui into master 2026-08-11 09:41:09 +03:00
6 changed files with 77 additions and 31 deletions
Showing only changes of commit a4880d7c50 - Show all commits

View File

@ -32,6 +32,6 @@ using System.Runtime.InteropServices;
// пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ // пїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅ пїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ
// пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ "*", пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ: // пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ "*", пїЅпїЅпїЅ пїЅпїЅпїЅпїЅпїЅпїЅпїЅпїЅ пїЅпїЅпїЅпїЅ:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.28.0")] [assembly: AssemblyVersion("1.0.29.0")]
[assembly: AssemblyFileVersion("1.0.28.0")] [assembly: AssemblyFileVersion("1.0.29.0")]

View File

@ -30,52 +30,66 @@ namespace Электронная_Фармация.UserControls
private readonly Button _btnAi; private readonly Button _btnAi;
private List<BuyerReportLineDto> _lines = new List<BuyerReportLineDto>(); private List<BuyerReportLineDto> _lines = new List<BuyerReportLineDto>();
// Палитра под общий стиль приложения (бирюза шапки #0F766E).
private static readonly Color Accent = Color.FromArgb(15, 118, 110);
private static readonly Color AccentHover = Color.FromArgb(13, 148, 136);
private static readonly Color TextMain = Color.FromArgb(31, 41, 55);
private static readonly Color TextMuted = Color.FromArgb(120, 128, 134);
private static readonly Color RowAlt = Color.FromArgb(247, 250, 250);
private static readonly Color SelBack = Color.FromArgb(178, 240, 230);
private static readonly Color GridLine = Color.FromArgb(230, 234, 236);
private static void StylePrimaryButton(Button b)
{
b.FlatStyle = FlatStyle.Flat;
b.FlatAppearance.BorderSize = 0;
b.FlatAppearance.MouseOverBackColor = AccentHover;
b.FlatAppearance.MouseDownBackColor = AccentHover;
b.BackColor = Accent;
b.ForeColor = Color.White;
b.Cursor = Cursors.Hand;
b.Font = new Font("Segoe UI", 9F, FontStyle.Regular);
}
public UCReports() public UCReports()
{ {
Dock = DockStyle.Fill; Dock = DockStyle.Fill;
var top = new Panel { Dock = DockStyle.Top, Height = 96 }; var uiFont = new Font("Segoe UI", 9F);
var top = new Panel { Dock = DockStyle.Top, Height = 100, BackColor = Color.White };
var lblFrom = new Label { Text = "С", AutoSize = true, Left = 10, Top = 15 }; // --- строка 1: период + готовый отчёт по данным ---
_dtFrom = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 110, Left = 30, Top = 11, Value = DateTime.Today.AddMonths(-1) }; var lblFrom = new Label { Text = "С", AutoSize = true, Left = 12, Top = 17, ForeColor = TextMain, Font = uiFont };
var lblTo = new Label { Text = "по", AutoSize = true, Left = 146, Top = 15 }; _dtFrom = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 112, Left = 32, Top = 13, Value = DateTime.Today.AddMonths(-1), Font = uiFont };
_dtTo = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 110, Left = 172, Top = 11, Value = DateTime.Today }; var lblTo = new Label { Text = "по", AutoSize = true, Left = 150, Top = 17, ForeColor = TextMain, Font = uiFont };
_cboReport = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 190, Left = 292, Top = 11 }; _dtTo = new DateTimePicker { Format = DateTimePickerFormat.Short, Width = 112, Left = 176, Top = 13, Value = DateTime.Today, Font = uiFont };
_cboReport = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Width = 190, Left = 298, Top = 13, Font = uiFont, FlatStyle = FlatStyle.Flat };
_cboReport.Items.AddRange(new object[] { "Мои заказы", "По поставщикам", "По товарам", "По аптекам" }); _cboReport.Items.AddRange(new object[] { "Мои заказы", "По поставщикам", "По товарам", "По аптекам" });
_cboReport.SelectedIndex = 0; _cboReport.SelectedIndex = 0;
_btnBuild = new Button { Text = "Сформировать", Left = 492, Top = 10, Width = 120, Height = 26 }; _btnBuild = new Button { Text = "Сформировать", Left = 498, Top = 12, Width = 140, Height = 28 };
_lblTotals = new Label { AutoSize = true, Left = 624, Top = 15, Text = "" }; _lblTotals = new Label { AutoSize = true, Left = 654, Top = 17, Text = "", ForeColor = Accent, Font = new Font("Segoe UI", 9F, FontStyle.Bold) };
top.Controls.AddRange(new Control[] { lblFrom, _dtFrom, lblTo, _dtTo, _cboReport, _btnBuild, _lblTotals }); top.Controls.AddRange(new Control[] { lblFrom, _dtFrom, lblTo, _dtTo, _cboReport, _btnBuild, _lblTotals });
// Вторая строка — свободный запрос к ИИ: клиент пишет что хочет, ИИ отдаёт Word/Excel. // --- строка 2: свободный запрос к ИИ (клиент пишет словами -> Word/Excel) ---
var lblAi = new Label { Text = "Запрос ИИ:", AutoSize = true, Left = 10, Top = 57 }; var lblAi = new Label { Text = "Запрос ИИ:", AutoSize = true, Left = 12, Top = 61, ForeColor = TextMain, Font = uiFont };
_txtPrompt = new TextBox { Left = 88, Top = 53, Width = 360 }; _txtPrompt = new TextBox { Left = 92, Top = 57, Width = 470, Font = uiFont, BorderStyle = BorderStyle.FixedSingle };
_cboFormat = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Top = 53, Width = 90 }; _cboFormat = new ComboBox { DropDownStyle = ComboBoxStyle.DropDownList, Left = 574, Top = 57, Width = 92, Font = uiFont, FlatStyle = FlatStyle.Flat };
_cboFormat.Items.AddRange(new object[] { "Word", "Excel" }); _cboFormat.Items.AddRange(new object[] { "Word", "Excel" });
_cboFormat.SelectedIndex = 0; _cboFormat.SelectedIndex = 0;
_btnAi = new Button { Text = "🤖 Сформировать ИИ", Top = 52, Width = 176, Height = 26 }; _btnAi = new Button { Text = "🤖 Сформировать ИИ", Left = 676, Top = 56, Width = 170, Height = 28 };
var lblHint = new Label { AutoSize = true, Left = 88, Top = 78, ForeColor = Color.Gray, _btnAi.Text = "Сформировать ИИ"; // без эмодзи (криво рендерился в кнопке)
var lblHint = new Label { AutoSize = true, Left = 92, Top = 83, ForeColor = TextMuted, Font = new Font("Segoe UI", 8F),
Text = "Напр.: «закупки по поставщикам за июль», «топ товаров за 3 месяца», «заказы у Farmsnab»" }; Text = "Напр.: «закупки по поставщикам за июль», «топ товаров за 3 месяца», «заказы у Farmsnab»" };
StylePrimaryButton(_btnBuild);
StylePrimaryButton(_btnAi);
var tip = new ToolTip(); var tip = new ToolTip();
tip.SetToolTip(_txtPrompt, "Опишите нужный отчёт словами — ИИ подберёт тип, период и соберёт документ."); tip.SetToolTip(_txtPrompt, "Опишите нужный отчёт словами — ИИ подберёт тип, период и соберёт документ.");
top.Controls.AddRange(new Control[] { lblAi, _txtPrompt, _cboFormat, _btnAi, lblHint }); top.Controls.AddRange(new Control[] { lblAi, _txtPrompt, _cboFormat, _btnAi, lblHint });
// Правые контролы пиннуем вручную (надёжнее якорей — не наезжают при любой ширине):
// кнопка и формат прижаты к правому краю, поле запроса тянется до них.
void LayoutToolbar()
{
const int pad = 12, gap = 8;
int w = top.ClientSize.Width;
_btnAi.Left = Math.Max(_txtPrompt.Left + 180, w - pad - _btnAi.Width);
_cboFormat.Left = _btnAi.Left - gap - _cboFormat.Width;
_txtPrompt.Width = Math.Max(160, _cboFormat.Left - gap - _txtPrompt.Left);
}
top.Resize += (_, __) => LayoutToolbar();
LayoutToolbar();
_grid = new DataGridView _grid = new DataGridView
{ {
Dock = DockStyle.Fill, Dock = DockStyle.Fill,
@ -86,8 +100,28 @@ namespace Электронная_Фармация.UserControls
RowHeadersVisible = false, RowHeadersVisible = false,
SelectionMode = DataGridViewSelectionMode.FullRowSelect, SelectionMode = DataGridViewSelectionMode.FullRowSelect,
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill, AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,
BorderStyle = BorderStyle.None BorderStyle = BorderStyle.None,
BackgroundColor = Color.White,
EnableHeadersVisualStyles = false,
ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.None,
ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing,
ColumnHeadersHeight = 34,
CellBorderStyle = DataGridViewCellBorderStyle.SingleHorizontal,
GridColor = GridLine,
RowHeadersBorderStyle = DataGridViewHeaderBorderStyle.None
}; };
_grid.ColumnHeadersDefaultCellStyle.BackColor = Accent;
_grid.ColumnHeadersDefaultCellStyle.ForeColor = Color.White;
_grid.ColumnHeadersDefaultCellStyle.Font = new Font("Segoe UI", 9.5F, FontStyle.Bold);
_grid.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft;
_grid.ColumnHeadersDefaultCellStyle.Padding = new Padding(6, 0, 0, 0);
_grid.DefaultCellStyle.Font = new Font("Segoe UI", 9.5F);
_grid.DefaultCellStyle.ForeColor = TextMain;
_grid.DefaultCellStyle.SelectionBackColor = SelBack;
_grid.DefaultCellStyle.SelectionForeColor = TextMain;
_grid.DefaultCellStyle.Padding = new Padding(6, 0, 6, 0);
_grid.AlternatingRowsDefaultCellStyle.BackColor = RowAlt;
_grid.RowTemplate.Height = 30;
Controls.Add(_grid); Controls.Add(_grid);
Controls.Add(top); Controls.Add(top);
@ -259,9 +293,21 @@ namespace Электронная_Фармация.UserControls
_grid.DataSource = dt; _grid.DataSource = dt;
foreach (DataGridViewColumn c in _grid.Columns) foreach (DataGridViewColumn c in _grid.Columns)
{ {
bool numeric = c.Name == "Сумма" || c.Name == "Кол-во" || c.Name == "Позиций" || c.Name == "Заказов";
if (c.Name == "Сумма") c.DefaultCellStyle.Format = "N2"; if (c.Name == "Сумма") c.DefaultCellStyle.Format = "N2";
if (c.Name == "Кол-во") c.DefaultCellStyle.Format = "N3"; if (c.Name == "Кол-во") c.DefaultCellStyle.Format = "N3";
if (c.Name == "Позиций" || c.Name == "Заказов") c.Width = 80; if (numeric)
{
c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
c.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight;
c.HeaderCell.Style.Padding = new Padding(0, 0, 6, 0);
}
// Узкие числовые колонки, широкие — текстовые (Fill распределит по весу).
if (c.Name == "Позиций" || c.Name == "Заказов") c.FillWeight = 45;
else if (c.Name == "Сумма" || c.Name == "Кол-во") c.FillWeight = 70;
else if (c.Name == "Дата" || c.Name == "Статус" || c.Name == "Код") c.FillWeight = 75;
else if (c.Name == "Номер") c.FillWeight = 90;
else c.FillWeight = 150; // Поставщик / Товар / Аптека
} }
int orders = _lines.Select(l => l.OrderID).Distinct().Count(); int orders = _lines.Select(l => l.OrderID).Distinct().Count();