Скачиваний:
1
Добавлен:
12.04.2025
Размер:
3.07 Mб
Скачать

ГУАП

КАФЕДРА № 14

ОТЧЕТ ЗАЩИЩЕН С ОЦЕНКОЙ

ПРЕПОДАВАТЕЛЬ

Старший преподаватель

Н. В. Барклаевская

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №6

СОЗДАНИЕ САЙТА С ИСПОЛЬЗОВАНИЕМ ТЕХНОЛОГИИ ASP.NET. ЧАСТЬ 2. РЕАЛИЗАЦИЯ ЛИЧНОГО КАБИНЕТА ПОЛЬЗОВАТЕЛЯ

по курсу: ПРОЕКТИРОВАНИЕ ИНФОРМАЦИОННЫХ СИСТЕМ

РАБОТУ ВЫПОЛНИЛ

СТУДЕНТ гр. №

4116

подпись, дата

инициалы, фамилия

Санкт-Петербург 2024

Цель работы: создание сайта с использованием технологии ASP.NET, разработка страницы регистрации пользователя, авторизации пользователя, реализация оформления заказа услуги или товара, просмотр ранее выполненных заказов, редактирование данных пользователя.

Описание предметной области:

Туристическое агентство представляет собой организацию, которая занимается продажей туристических путёвок. Основными задачами агентства являются поиск и разработка туров, консультирование клиентов, оформление бронирований, обеспечение процесса оплаты и предоставление актуальной информации о турах и предложениях.

Реализована регистрация пользователей. Данных из формы, проверяется их корректность, выполняется подключение к базе данных, вычисляется новый идентификатор клиента, данные заносятся в таблицу Client. (Рисунок -21).

Рисунок 1- Форма регистрации пользователей

На рисунке 2 показано добавление пользователя в таблицу Клиент

Рисунок 2 – Добавление пользователя в таблицу Клиент

Листинг 1- Команда кнопки регистрации пользователя

protected void btnRegister_Click(object sender, EventArgs e)

{

// считывание данных из полей формы

string name = txtName.Text.Trim();

string surname = txtSurname.Text.Trim();

string patronymic = txtPatronymic.Text.Trim();

string dobText = txtDOB.Text.Trim();

string phone = txtPhone.Text.Trim();

string login = txtLogin.Text.Trim();

string password = txtPassword.Text.Trim();

if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(surname) || string.IsNullOrEmpty(phone) || string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))

{

lblMessage.Text = "Все поля должны быть заполнены.";

return;

}

if (!DateTime.TryParse(dobText, out DateTime dob))

{

lblMessage.Text = "Некорректная дата рождения.";

return;

}

string connectionString = "Data Source=localhost;Initial Catalog=travel;Integrated Security=True";

try

{

using (SqlConnection connection = new SqlConnection(connectionString))

{

connection.Open();

string maxIdQuery = "SELECT ISNULL(MAX(Client_ID), 0) + 1 FROM Client";

int newClientID;

using (SqlCommand maxIdCommand = new SqlCommand(maxIdQuery, connection))

{

newClientID = (int)maxIdCommand.ExecuteScalar();

}

string insertQuery = "INSERT INTO Client (Client_ID, Name_C, Surname_C, Patronymic_C, DOB_C, Phone_C, LoginC, PasswordC) " + "VALUES (@ClientID, @Name, @Surname, @Patronymic, @DOB, @Phone, @Login, @Password)";

using (SqlCommand insertCommand = new SqlCommand(insertQuery, connection))

{

insertCommand.Parameters.AddWithValue("@ClientID", newClientID);

insertCommand.Parameters.AddWithValue("@Name", name);

insertCommand.Parameters.AddWithValue("@Surname", surname);

insertCommand.Parameters.AddWithValue("@Patronymic", patronymic);

insertCommand.Parameters.AddWithValue("@DOB", dob);

insertCommand.Parameters.AddWithValue("@Phone", phone);

insertCommand.Parameters.AddWithValue("@Login", login);

insertCommand.Parameters.AddWithValue("@Password", password);

int rowsAffected = insertCommand.ExecuteNonQuery();

if (rowsAffected > 0)

{

lblMessage.ForeColor = System.Drawing.Color.Green;

lblMessage.Text = "Регистрация прошла успешно!";

}

else

{

lblMessage.Text = "Ошибка регистрации. Попробуйте снова.";

}

}

}

}

catch (Exception ex)

{

lblMessage.Text = "Ошибка: " + ex.Message;

}

}

Затем реализована авторизация пользователя (Рисунок 3-4). При нажатии на кнопку Вход, выполняется проверка логина и пароля пользователя в базе данных, если данные корректны, программа сохраняет информацию о пользователе в сессии и перенаправляет на главную страницу, если неверны, отображает сообщение об ошибке (Листинг 2).

Также написана функция для проверки, авторизован ли пользователь, в зависимости от этого, появляются или скрываются элементы интерфейса. Также реализовано приветствие пользователя, если он вошел в систему. После нажатии авторизованного пользователя на кнопку Выход, происходит очищение данных сессии, и элементы интерфейса становятся видимыми для неавторизованного пользователя (Листинг 3)

Рисунок 3 – Главная страница до авторизации

Рисунок 4 - Главная страница после авторизации пользователя

Листинг 2- Функция кнопки входа

protected void btnLogin_Click(object sender, EventArgs e)

{

string login = txtUsername.Text.Trim();

string password = txtPassword.Text.Trim();

if (string.IsNullOrEmpty(login) || string.IsNullOrEmpty(password))

{

lblMessage.Text = "Введите логин и пароль.";

lblMessage.ForeColor = System.Drawing.Color.Red;

return;

}

string connectionString = "Data Source=localhost;Initial Catalog=travel;Integrated Security=True";

string query = @"

SELECT 'Client' AS UserType, Client_ID AS UserId, Name_C AS FirstName

FROM Client WHERE LoginC = @Login AND PasswordC = @Password

UNION ALL

SELECT 'Employee' AS UserType, Employee_ID AS UserId, Name_E AS FirstName

FROM Employee WHERE LoginE = @Login AND PasswordE = @Password";

try

{

using (SqlConnection connection = new SqlConnection(connectionString))

{

connection.Open();

using (SqlCommand command = new SqlCommand(query, connection))

{

command.Parameters.AddWithValue("@Login", login);

command.Parameters.AddWithValue("@Password", password);

SqlDataReader reader = command.ExecuteReader();

if (reader.HasRows)

{

reader.Read();

// Сохранение данных в сессии

Session["UserType"] = reader["UserType"].ToString();

Session["UserId"] = reader["UserId"].ToString();

Session["UserName"] = reader["FirstName"].ToString();

lblMessage.ForeColor = System.Drawing.Color.Green;

lblMessage.Text = "Вход выполнен успешно!";

Response.Redirect("Home.aspx");

}

else

{

lblMessage.Text = "Неверный логин или пароль.";

lblMessage.ForeColor = System.Drawing.Color.Red;

}

}

}

}

catch (Exception ex)

{

lblMessage.Text = "Ошибка: " + ex.Message;

lblMessage.ForeColor = System.Drawing.Color.Red;

}

}

Листинг 3- Функция кнопки выхода

protected void btnLogout_Click(object sender, EventArgs e)

{

Session.Clear();

txtUsername.Visible = true;

txtPassword.Visible = true;

lblLogin.Visible = true;

lblPassword.Visible = true;

btnLogin.Visible = true;

btnRegister.Visible = true;

btnLogout.Visible = false;

lblMessage.Text = "Вы успешно вышли.";

lblMessage.ForeColor = System.Drawing.Color.Green;

Response.Redirect("Home.aspx");

}

Дале создана возможность оформления заказа пользователем. При выборе определенного тура, происходит переход на страницу этого тура. На странице тура есть возможно выбора дат для путешествия и проверки количества доступных путевок (Рисунок 5). При выборе дат и количества путевок пользователь получает сообщение о доступности или отсутствии путевок (Рисунок 6-7).

Рисунок 5- Страница тура и выбора дат

Рисунок 6 - Получение сообщения о доступности поездки

Рисунок 7- Сообщение о недоступности мест

Листинг 4- Функция для проверки доступности мест для бронирования на выбранную дату

protected void CheckAvailabilityButton_Click(object sender, EventArgs e)

{

string tourID = Request.QueryString["TourID"];

string startDate = StartDateTextBox.Text;

if (!int.TryParse(TicketCountTextBox.Text, out int ticketsRequested) || ticketsRequested <= 0)

{

AvailabilityLabel.Text = "Введите корректное количество путевок.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

return;

}

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["travelConnectionString4"].ConnectionString;

using (SqlConnection conn = new SqlConnection(connectionString))

{

string query = @"SELECT TripCount FROM Trip WHERE Tour_ID = @TourID AND StartDate = @StartDate";

using (SqlCommand cmd = new SqlCommand(query, conn))

{

cmd.Parameters.AddWithValue("@TourID", tourID);

cmd.Parameters.AddWithValue("@StartDate", startDate);

conn.Open();

object result = cmd.ExecuteScalar();

if (result != null && int.TryParse(result.ToString(), out int availableTickets))

{

if (availableTickets >= ticketsRequested)

{

AvailabilityLabel.Text = "Достаточно мест для бронирования.";

AvailabilityLabel.CssClass = "success";

OrderButton.Visible = true;

}

else

{

AvailabilityLabel.Text = "Недостаточно мест для бронирования.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

}

}

else

{

AvailabilityLabel.Text = "Нет данных для выбранной даты.";

AvailabilityLabel.CssClass = "error";

OrderButton.Visible = false;

}

}

}

}

При нажатии на кнопку «Перейти к оформлению заказа» открывается форма для заполнения данных пассажиров (Рисунок 8). В зависимости от количества путевок создаются текстовые поля и метки для ввода информации о пассажирах. Также рассчитывается общая стоимость тура, умножая цену одной путевки на количество путевок (Листинг 5).

Рисунок 8- Подробная информация о туре

Листинг 5- Функция расчета стоимости

private void CalculateTotalPrice(string tourID, int ticketsCount)

{

string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["travelConnectionString4"].ConnectionString;

try

{

using (SqlConnection conn = new SqlConnection(connectionString))

{ string query = @"SELECT Price FROM Trip WHERE Tour_ID = @TourID AND StartDate = @StartDate";

using (SqlCommand cmd = new SqlCommand(query, conn))

{

cmd.Parameters.AddWithValue("@TourID", tourID);

cmd.Parameters.AddWithValue("@StartDate", DateTime.Parse(StartDateLabel.Text));

conn.Open();

object result = cmd.ExecuteScalar();

if (result != null)

{

decimal pricePerTicket = Convert.ToDecimal(result);

decimal totalPrice = pricePerTicket * ticketsCount;

TotalPriceLabel.Text = $"Общая стоимость: {totalPrice:C}"; // Выводим стоимость

}

else

{

ErrorMessage.Text = "Ошибка: Цена не найдена.";

}

}

}

}

catch (Exception ex)

{

ErrorMessage.Text = $"Ошибка расчета стоимости: {ex.Message}";

}

}

При правильно заполненных данных, создается запись в таблице Заказ (Листинг 6), а в таблицу с путевками заносятся данные о пассажирах, которые привязаны к путевке (Листинг 7). Также при оформлении заказа, уменьшается количество доступных путевок (Листинг 8) (Рисунок 9-12).

Рисунок 9- Таблица с доступными путевками до оформления заказа

Рисунок 10- Успешное оформление заказа

Рисунок 11- Таблица с доступными путевками после оформления заказа

Рисунок 12- Таблицами с путевками

Листинг 6- Функция для создания записи в таблице с заказами

private int InsertOrder(SqlConnection conn, SqlTransaction transaction, int tripID, int ticketsCount)

{

string query = @"

INSERT INTO Order_data (OrderDate, Client_ID, PeopleCount, Trip_ID)

OUTPUT INSERTED.Order_ID

VALUES (GETDATE(), @ClientID, @PeopleCount, @TripID)";

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@ClientID", Session["UserId"]);

cmd.Parameters.AddWithValue("@PeopleCount", ticketsCount);

cmd.Parameters.AddWithValue("@TripID", tripID);

return (int)cmd.ExecuteScalar();

}

}

Листинг 7 – Добавление оформленных путевок в таблицу с путевками

private void AddPassengers(SqlConnection conn, SqlTransaction transaction, int orderID, int ticketsCount)

{

string query = @"

INSERT INTO Permit (Order_ID, LastName, FirstName, MiddleName, DOB)

VALUES (@OrderID, @LastName, @FirstName, @MiddleName, @DOB)";

for (int i = 1; i <= ticketsCount; i++)

{

string passengerName = ((TextBox)PassengersPanel.FindControl($"PassengerName_{i}"))?.Text;

string passengerDOB = ((TextBox)PassengersPanel.FindControl($"PassengerDOB_{i}"))?.Text;

string[] nameParts = passengerName?.Split(' ');

if (nameParts == null || nameParts.Length < 2)

{

throw new Exception($"Ошибка в данных пассажира {i}. Укажите ФИО в формате: 'Фамилия Имя Отчество'.");

}

string lastName = nameParts[0];

string firstName = nameParts[1];

string middleName = nameParts.Length > 2 ? nameParts[2] : "";

if (string.IsNullOrEmpty(passengerDOB) || !DateTime.TryParse(passengerDOB, out DateTime dob))

{

throw new Exception($"Ошибка в данных пассажира {i}. Укажите корректную дату рождения.");

}

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@OrderID", orderID);

cmd.Parameters.AddWithValue("@LastName", lastName);

cmd.Parameters.AddWithValue("@FirstName", firstName);

cmd.Parameters.AddWithValue("@MiddleName", middleName);

cmd.Parameters.AddWithValue("@DOB", dob);

cmd.ExecuteNonQuery();

}

}

}

Листинг 8- Функция уменьшения количества доступных путевок

private void UpdateTripCount(SqlConnection conn, SqlTransaction transaction, int tripID, int ticketsCount)

{

string query = @"

UPDATE Trip

SET TripCount = TripCount - @TicketsCount

WHERE Trip_ID = @TripID";

using (SqlCommand cmd = new SqlCommand(query, conn, transaction))

{

cmd.Parameters.AddWithValue("@TicketsCount", ticketsCount);

cmd.Parameters.AddWithValue("@TripID", tripID);

cmd.ExecuteNonQuery();

}

}

Также для авторизованного пользователь реализована возможность просмотра истории оформленных заказов (Рисунок 13).

Рисунок 13- Просмотр истории заказов

Листинг 9- Функция отображения истории заказов для текущего пользователя

protected void LoadOrderHistory()

{

string connectionString = "Data Source=localhost;Initial Catalog=travel;Integrated Security=True";

string query = @"

SELECT

Order_data.Order_ID,

Tour.Name_T AS TourName,

Tour.Description_T AS Description,

Trip.StartDate AS StartDate,

Trip.EndDate AS EndDate,

STRING_AGG(

Permit.LastName + ' ' + Permit.FirstName +

ISNULL(' ' + Permit.MiddleName, '') +

' (Дата рождения: ' + FORMAT(Permit.DOB, 'dd.MM.yyyy') + ')',

'<br/>'

) AS PassengerInfo,

(Trip.Price * Order_data.PeopleCount) AS TotalPrice,

Type_T.Name_T AS TourType,

Season.Name_Season AS Season,

Hotel.Name_H AS HotelName,

Locality.Name_L AS RouteLocality,

Locality.Country AS Country,

ISNULL(Image.FilePath, 'default.jpg') AS ImagePath

FROM

Order_data

INNER JOIN

Trip ON Order_data.Trip_ID = Trip.Trip_ID

INNER JOIN

Tour ON Trip.Tour_ID = Tour.Tour_ID

INNER JOIN

Permit ON Order_data.Order_ID = Permit.Order_ID

INNER JOIN

Type_T ON Tour.TypeT_ID = Type_T.TypeT_ID

INNER JOIN

TourSeason ON Tour.Tour_ID = TourSeason.Tour_ID

INNER JOIN

Season ON TourSeason.Season_ID = Season.Season_ID

INNER JOIN

TourHotel ON Tour.Tour_ID = TourHotel.Tour_ID

INNER JOIN

Hotel ON TourHotel.Hotel_ID = Hotel.Hotel_ID

INNER JOIN

Route ON Tour.Tour_ID = Route.Tour_ID

INNER JOIN

Locality ON Route.Locality_ID = Locality.Locality_ID

LEFT JOIN

ImageTour ON Tour.Tour_ID = ImageTour.TourID

LEFT JOIN

Image ON ImageTour.ImageID = Image.ImageID

WHERE

Order_data.Client_ID = @ClientID

GROUP BY

Order_data.Order_ID,

Tour.Name_T,

Tour.Description_T,

Trip.StartDate,

Trip.EndDate,

Trip.Price,

Order_data.PeopleCount,

Type_T.Name_T,

Season.Name_Season,

Hotel.Name_H,

Locality.Name_L,

Locality.Country,

Image.FilePath;";

try

{

int clientId = int.Parse(Session["UserId"].ToString());

using (SqlConnection connection = new SqlConnection(connectionString))

{

SqlCommand command = new SqlCommand(query, connection);

command.Parameters.AddWithValue("@ClientID", clientId);

SqlDataAdapter adapter = new SqlDataAdapter(command);

DataTable dt = new DataTable();

adapter.Fill(dt);

if (dt.Rows.Count > 0)

{

gvOrderHistory.DataSource = dt;

gvOrderHistory.DataBind();

}

else

{

lblMessage.Text = "У вас пока нет заказов.";

}

}

}

catch (Exception ex)

{

lblMessage.Text = "Ошибка загрузки данных: " + ex.Message;

}

}

При переходе на страницу Редактирование профиля, пользователь может изменить свои данные (Рисунок 14-16).

Рисунок 14- Форма для редактирования данных пользователя

Рисунок 15- Обновление номера телефона пользователя

Рисунок 16- Проверка обновления данных

Листинг 10- Функция обновления данных

protected void btnSave_Click(object sender, EventArgs e)

{

if (Session["UserId"] == null)

{

lblMessage.Text = "Вы не авторизованы. Пожалуйста, войдите в систему.";

return;

}

int clientId = int.Parse(Session["UserId"].ToString());

string connectionString = "Data Source=localhost;Initial Catalog=travel;Integrated Security=True";

string query = @"

UPDATE Client

SET Name_C = @Name,

Surname_C = @Surname,

Patronymic_C = @Patronymic,

DOB_C = @DOB,

Phone_C = @Phone

WHERE Client_ID = @ClientID";

try

{

using (SqlConnection connection = new SqlConnection(connectionString))

{ SqlCommand command = new SqlCommand(query, connection);

command.Parameters.AddWithValue("@Name", txtName.Text);

command.Parameters.AddWithValue("@Surname", txtSurname.Text);

command.Parameters.AddWithValue("@Patronymic", txtPatronymic.Text);

command.Parameters.AddWithValue("@DOB", Convert.ToDateTime(txtDOB.Text));

command.Parameters.AddWithValue("@Phone", txtPhone.Text);

command.Parameters.AddWithValue("@ClientID", clientId);

connection.Open();

int rowsAffected = command.ExecuteNonQuery();

if (rowsAffected > 0)

{

lblSuccess.Text = "Данные успешно обновлены!";

lblMessage.Text = "";

}

else

{

lblMessage.Text = "Ошибка обновления данных.";

}

}

}

catch (Exception ex)

{

lblMessage.Text = "Ошибка сохранения данных: " + ex.Message;

}

}

}

Вывод: созданы странницы сайта с использованием технологии ASP.NET, разработаны страницы регистрации пользователя, авторизации пользователя, оформления заказа услуги или товара, просмотра ранее выполненных заказов, редактирования данных пользователя.

Соседние файлы в предмете Проектирование информационных систем