Загрузка данных
DB.CS
using MySql.Data.MySqlClient;
using System;
using System.Data;
namespace demo
{
public static class Db
{
public static string ConnStr = "server=localhost;user=root;password=;database=demo;charset=utf8;";
public static DataTable Select(string sql, params MySqlParameter[] parameters)
{
MySqlConnection conn = new MySqlConnection(ConnStr);
MySqlDataAdapter adapter = new MySqlDataAdapter(sql, conn);
foreach (MySqlParameter p in parameters)
adapter.SelectCommand.Parameters.Add(p);
DataTable table = new DataTable();
adapter.Fill(table);
return table;
}
public static int Execute(string sql, params MySqlParameter[] parameters)
{
MySqlConnection conn = new MySqlConnection(ConnStr);
MySqlCommand cmd = new MySqlCommand(sql, conn);
foreach (MySqlParameter p in parameters)
cmd.Parameters.Add(p);
conn.Open();
int result = cmd.ExecuteNonQuery();
conn.Close();
return result;
}
public static object Scalar(string sql)
{
MySqlConnection conn = new MySqlConnection(ConnStr);
MySqlCommand cmd = new MySqlCommand(sql, conn);
conn.Open();
object result = cmd.ExecuteScalar();
conn.Close();
return result;
}
public static MySqlParameter P(string name, object value)
{
return new MySqlParameter(name, value ?? DBNull.Value);
}
}
}
FORM1.CS
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace demo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Text = Program.AppTitle;
Label lblTitle = new Label
{
Text = Program.AppTitle,
Font = new Font("Segoe UI", 24, FontStyle.Bold),
ForeColor = Color.DarkBlue,
AutoSize = true,
Location = new Point(50, 30)
};
this.Controls.Add(lblTitle);
// ---- НАСТРОЙКА ЦВЕТОВ (закомментировано) ----
// this.BackColor = Color.FromArgb(240, 248, 255); // #F0F8FF (AliceBlue)
// lblTitle.ForeColor = Color.FromArgb(25, 25, 112); // #191970 (MidnightBlue)
// btnLogin.BackColor = Color.FromArgb(255, 215, 0); // #FFD700 (Gold)
// -------------------------------------------
Button btnGuest = new Button
{
Text = "Войти как гость",
Location = new Point(btnLogin.Location.X, btnLogin.Location.Y + btnLogin.Height + 10),
Size = btnLogin.Size,
BackColor = Color.LightGray,
FlatStyle = FlatStyle.Flat
};
btnGuest.Click += BtnGuest_Click;
this.Controls.Add(btnGuest);
// btnGuest.BackColor = Color.FromArgb(189, 042, 171); // #D3D3D3 (LightGray)
AcceptButton = btnLogin;
}
private void BtnGuest_Click(object sender, EventArgs e)
{
string role = "Client";
string fio = "Гость";
MainForm f = new MainForm(role, fio);
f.FormClosed += delegate { Close(); };
f.Show();
Hide();
}
private void btnLogin_Click(object sender, EventArgs e)
{
if (txtLogin.Text == "" || txtPassword.Text == "")
{
MessageBox.Show("Введите логин и пароль");
return;
}
try
{
string sql = "SELECT `Роль` AS role_id, `ФИО` AS fio FROM import_users " +
"WHERE `Логин`=@login AND `Пароль`=@pass LIMIT 1";
DataTable users = Db.Select(sql,
Db.P("@login", txtLogin.Text.Trim()),
Db.P("@pass", txtPassword.Text.Trim()));
if (users.Rows.Count == 0)
{
MessageBox.Show("Неверный логин или пароль");
return;
}
string role = users.Rows[0]["role_id"].ToString();
string fio = users.Rows[0]["fio"].ToString();
MainForm f = new MainForm(role, fio);
f.FormClosed += delegate { Close(); };
f.Show();
Hide();
}
catch (Exception ex)
{
MessageBox.Show("Ошибка подключения к базе:\n" + ex.Message);
}
}
private void Form1_Load(object sender, EventArgs e) { }
}
}
MAINFORM.CS
using MySql.Data.MySqlClient;
using System;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
namespace demo
{
public partial class MainForm : Form
{
string role;
string fio;
string mode = "products";
public MainForm(string userRole, string userFio)
{
InitializeComponent();
this.Text = Program.AppTitle;
role = userRole;
fio = userFio;
lblUser.Text = fio + " (" + role + ")";
Label lblMainTitle = new Label
{
Text = Program.AppTitle,
Font = new Font("Segoe UI", 18, FontStyle.Bold),
ForeColor = Color.DarkGreen,
AutoSize = true,
Location = new Point(10, 5)
};
topPanel.Controls.Add(lblMainTitle);
lblUser.Location = new Point(this.Width - lblUser.Width - 20, 5);
lblUser.Anchor = AnchorStyles.Top | AnchorStyles.Right;
// ---- НАСТРОЙКА ЦВЕТОВ (закомментировано) ----
// this.BackColor = Color.LightYellow;
// topPanel.BackColor = Color.LightBlue;
// grid.BackgroundColor = Color.WhiteSmoke;
// btnTovar.BackColor = Color.LightGreen;
// btnUsers.BackColor = Color.LightCoral;
// -------------------------------------------
btnZakaz.Visible = false;
btnAdres.Visible = false;
topPanel.Dock = DockStyle.None;
grid.Dock = DockStyle.None;
panelProduct.Dock = DockStyle.None;
topPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
grid.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
panelProduct.Anchor = AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
Resize += delegate { FixLayout(); };
btnUsers.Visible = IsAdmin();
panelProduct.Visible = CanEditProducts();
LoadProducts();
FixLayout();
grid.RowPrePaint += Grid_RowPrePaint;
}
private void Grid_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
// Применяем раскраску только в режиме товаров
if (mode != "products") return;
if (grid.Rows[e.RowIndex].IsNewRow) return;
// Проверяем, существуют ли нужные колонки (защита от ошибок в других таблицах)
if (!grid.Columns.Contains("Количество на складе") || !grid.Columns.Contains("Скидка"))
return;
DataGridViewRow row = grid.Rows[e.RowIndex];
// Получаем количество на складе
object qtyObj = row.Cells["Количество на складе"].Value;
int quantity = (qtyObj != DBNull.Value && qtyObj != null) ? Convert.ToInt32(qtyObj) : 0;
// Получаем скидку
object discountObj = row.Cells["Скидка"].Value;
int discount = (discountObj != DBNull.Value && discountObj != null) ? Convert.ToInt32(discountObj) : 0;
if (quantity == 0)
{
// Нет в наличии – красная строка
row.DefaultCellStyle.BackColor = Color.LightCoral;
row.DefaultCellStyle.ForeColor = Color.Black;
}
else if (discount > 20)
{
// Скидка больше 20% – зелёная строка
row.DefaultCellStyle.BackColor = Color.LightGreen;
row.DefaultCellStyle.ForeColor = Color.Black;
}
else
{
// Обычный цвет
row.DefaultCellStyle.BackColor = grid.DefaultCellStyle.BackColor;
row.DefaultCellStyle.ForeColor = grid.DefaultCellStyle.ForeColor;
}
}
bool IsAdmin() => role == "Admin";
bool IsManager() => role == "Manager";
bool IsClient() => role == "Client";
bool CanEditProducts() => IsAdmin() || IsManager();
void FixLayout()
{
int bottom = panelProduct.Visible ? panelProduct.Height : 0;
topPanel.Location = new Point(0, 0);
topPanel.Width = ClientSize.Width;
grid.Location = new Point(0, topPanel.Height);
grid.Size = new Size(ClientSize.Width, ClientSize.Height - topPanel.Height - bottom);
panelProduct.Location = new Point(0, ClientSize.Height - panelProduct.Height);
panelProduct.Width = ClientSize.Width;
lblUser.Location = new Point(this.ClientSize.Width - lblUser.Width - 20, 5);
}
void LoadGrid(string sql, params MySqlParameter[] parameters)
{
DataTable table = Db.Select(sql, parameters);
grid.DataSource = table;
grid.AllowUserToAddRows = false;
grid.AllowUserToDeleteRows = false;
grid.ReadOnly = true;
grid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
lblCount.Text = "Строк: " + table.Rows.Count;
}
string SearchText() => "%" + txtSearch.Text.Trim() + "%";
void LoadProducts()
{
mode = "products";
panelProduct.Visible = CanEditProducts();
FixLayout();
string sql = @"SELECT
b.ID,
b.`Название`,
b.`Год издания`,
b.`Цена`,
b.`Количество на складе`,
b.`Скидка`,
b.`ISBN`,
b.`Путь к обложке`,
b.`Количество страниц`,
b.`Описание`,
a.`ФИО автора` AS Автор,
g.`Наименование жанра` AS Жанр,
p.`Наименование издательства` AS Издательство
FROM import_books b
LEFT JOIN import_authors a ON b.`АвторID` = a.ID
LEFT JOIN import_genres g ON b.`ЖанрID` = g.ID
LEFT JOIN import_publishers p ON b.`ИздательствоID` = p.ID
WHERE b.`Название` IS NOT NULL";
if (txtSearch.Text.Trim() != "")
{
sql += " AND (b.`Название` LIKE @q OR b.`ISBN` LIKE @q OR b.`Описание` LIKE @q OR a.`ФИО автора` LIKE @q OR g.`Наименование жанра` LIKE @q)";
LoadGrid(sql, Db.P("@q", SearchText()));
}
else
{
LoadGrid(sql);
}
}
void LoadUsers()
{
if (!IsAdmin())
{
MessageBox.Show("Пользователей может смотреть только администратор");
return;
}
mode = "users";
panelProduct.Visible = false;
FixLayout();
string sql = "SELECT ID, `Роль`, `ФИО`, `Логин`, `Пароль` FROM import_users";
if (txtSearch.Text.Trim() != "")
{
sql += " WHERE `Роль` LIKE @q OR `ФИО` LIKE @q OR `Логин` LIKE @q";
LoadGrid(sql, Db.P("@q", SearchText()));
}
else
{
LoadGrid(sql);
}
}
void Reload()
{
if (mode == "products") LoadProducts();
if (mode == "users") LoadUsers();
}
int SelectedProductId()
{
if (grid.CurrentRow == null)
throw new Exception("Выберите товар в таблице");
return Convert.ToInt32(grid.CurrentRow.Cells["ID"].Value);
}
bool ProductFieldsOk()
{
if (txtName.Text == "" || txtPrice.Text == "" || txtQty.Text == "")
{
MessageBox.Show("Заполните название, цену и количество");
return false;
}
return true;
}
void ClearProductFields()
{
txtArticle.Clear();
txtName.Clear();
txtPrice.Clear();
txtQty.Clear();
txtSupplier.Clear();
txtCategory.Clear();
txtDescription.Clear();
}
private void btnTovar_Click(object sender, EventArgs e)
{
txtSearch.Clear();
LoadProducts();
}
private void btnZakaz_Click(object sender, EventArgs e)
{
MessageBox.Show("Функционал заказов недоступен");
}
private void btnAdres_Click(object sender, EventArgs e)
{
MessageBox.Show("Функционал адресов недоступен");
}
private void btnUsers_Click(object sender, EventArgs e)
{
txtSearch.Clear();
LoadUsers();
}
private void btnSearch_Click(object sender, EventArgs e)
{
Reload();
}
private void btnRefresh_Click(object sender, EventArgs e)
{
txtSearch.Clear();
Reload();
}
private void btnExit_Click(object sender, EventArgs e)
{
Close();
}
string Cell(string column)
{
if (grid.CurrentRow == null || !grid.Columns.Contains(column))
return "";
object value = grid.CurrentRow.Cells[column].Value;
return value == null ? "" : value.ToString();
}
private void grid_SelectionChanged(object sender, EventArgs e)
{
if (mode != "products" || grid.CurrentRow == null || grid.CurrentRow.IsNewRow)
return;
txtName.Text = Cell("Название");
txtPrice.Text = Cell("Цена");
txtQty.Text = Cell("Количество на складе");
txtDescription.Text = Cell("Описание");
txtArticle.Text = Cell("ISBN");
txtSupplier.Text = Cell("Издательство");
txtCategory.Text = Cell("Жанр");
}
private void btnClearProduct_Click(object sender, EventArgs e)
{
ClearProductFields();
}
private void btnAddProduct_Click(object sender, EventArgs e)
{
if (!ProductFieldsOk()) return;
try
{
int newId = Convert.ToInt32(Db.Scalar("SELECT IFNULL(MAX(ID),0)+1 FROM import_books"));
string sql = @"INSERT INTO import_books
(ID, `Название`, `АвторID`, `ЖанрID`, `ИздательствоID`, `Год издания`, `Цена`,
`Количество на складе`, `Скидка`, `ISBN`, `Путь к обложке`, `Количество страниц`, `Описание`)
VALUES (@id, @name, 1, 1, 1, 2023, @price, @qty, 0, @isbn, '', 0, @desc)";
Db.Execute(sql,
Db.P("@id", newId),
Db.P("@name", txtName.Text),
Db.P("@price", txtPrice.Text),
Db.P("@qty", txtQty.Text),
Db.P("@isbn", txtArticle.Text),
Db.P("@desc", txtDescription.Text));
MessageBox.Show("Книга добавлена (автор, жанр, издательство установлены по умолчанию)");
LoadProducts();
}
catch (Exception ex)
{
MessageBox.Show("Ошибка добавления:\n" + ex.Message);
}
}
private void btnUpdateProduct_Click(object sender, EventArgs e)
{
if (!ProductFieldsOk()) return;
try
{
string sql = @"UPDATE import_books SET
`Название` = @name,
`Цена` = @price,
`Количество на складе` = @qty,
`ISBN` = @isbn,
`Описание` = @desc
WHERE ID = @id";
Db.Execute(sql,
Db.P("@id", SelectedProductId()),
Db.P("@name", txtName.Text),
Db.P("@price", txtPrice.Text),
Db.P("@qty", txtQty.Text),
Db.P("@isbn", txtArticle.Text),
Db.P("@desc", txtDescription.Text));
MessageBox.Show("Книга обновлена");
LoadProducts();
}
catch (Exception ex)
{
MessageBox.Show("Ошибка обновления:\n" + ex.Message);
}
}
private void btnDeleteProduct_Click(object sender, EventArgs e)
{
try
{
DialogResult result = MessageBox.Show("Удалить выбранную книгу?", "Подтверждение",
MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (result != DialogResult.Yes) return;
Db.Execute("DELETE FROM import_books WHERE ID=@id", Db.P("@id", SelectedProductId()));
MessageBox.Show("Книга удалена");
ClearProductFields();
LoadProducts();
}
catch (Exception ex)
{
MessageBox.Show("Ошибка удаления:\n" + ex.Message);
}
}
private void MainForm_Load(object sender, EventArgs e) { }
private void txtSupplier_TextChanged(object sender, EventArgs e)
{
}
}
}
PROGRAM.CS
using System;
using System.Windows.Forms;
namespace demo
{
internal static class Program
{
/// <summary>
/// Главная точка входа для приложения.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
// Общее название приложения – измените здесь один раз для всех форм
public static string AppTitle = "Книжный мир";
}
}