создание и удаление мероприятия работает, редактирование почти готово

This commit is contained in:
EkaterinaR 2024-11-04 19:46:16 +04:00
parent da136edfb7
commit b2f1e1c322
22 changed files with 632 additions and 473 deletions

View File

@ -5,7 +5,11 @@ using EventVisitorLogic.ViewModels;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Diagnostics;
using System.Net.NetworkInformation;
using System.Net;
using System.Numerics;
using System.Security.Cryptography.Xml;
using System.Xml.Linq;
namespace EventVisitorClientApp.Controllers
{
@ -31,7 +35,7 @@ namespace EventVisitorClientApp.Controllers
{
throw new Exception("Ââåäèòå ëîãèí è ïàðîëü");
}
APIClient.Client = APIClient.GetRequest<OrganizerViewModel>($"api/client/login?login={login}&password={password}");
APIClient.Client = APIClient.GetRequest<OrganizerViewModel>($"api/Organizer/login?login={login}&password={password}");
if (APIClient.Client == null)
{
throw new Exception("Íåâåðíûé ëîãèí/ïàðîëü");
@ -153,19 +157,112 @@ namespace EventVisitorClientApp.Controllers
public IActionResult MyEvents()
{
//if (APIClient.Client == null)
//{
// return Redirect("~/Home/Enter");
//}
return View(APIClient.GetRequest<List<EventViewModel>>($"api/main/getevents"));
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View(APIClient.GetRequest<List<EventViewModel>>($"api/main/GetEventList?ClientId={APIClient.Client.Id}"));
}
public IActionResult CreateEvent()
{
//if (APIClient.Client == null)
//{
// return Redirect("~/Home/Enter");
//}
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
return View();
}
public IActionResult ViewEvent(int id)
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}");
return View(eventDetails);
}
[HttpPost]
public void CreateEvent(string name, string description, string type, string phone, string email, string address, string city, string status, int count, DateTime timestart, DateTime timeend)
{
if (APIClient.Client == null)
{
throw new Exception("Âû êàê ñþäà ïîïàëè? Ñþäà âõîä òîëüêî àâòîðèçîâàííûì");
}
APIClient.PostRequest("api/main/createevent", new EventBindingModel
{
Name = name,
Description = description,
Type = type,
ContactPhone = phone,
Address = address,
City = city,
Status = status,
ContactEmail = email,
TimeEnd = timeend.ToUniversalTime(),
TimeStart = timestart.ToUniversalTime(),
Date = DateTime.Now.ToUniversalTime(),
CountVisitors = count,
FreePlaces = count,
OrganizerId = APIClient.Client.Id
});
Response.Redirect("MyEvents");
}
public IActionResult DeleteEvent(int id)
{
// Ïðîâåðêà íà àâòîðèçàöèþ ïîëüçîâàòåëÿ
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
// Âûïîëíåíèå çàïðîñà íà óäàëåíèå ìåðîïðèÿòèÿ
APIClient.PostRequest($"api/main/DeleteEvent", new EventBindingModel { Id = id });
// Ïåðåíàïðàâëåíèå îáðàòíî íà ñòðàíèöó ñ ìåðîïðèÿòèÿìè
return RedirectToAction("MyEvents");
}
public IActionResult UpdateEvent(int id)
{
if (APIClient.Client == null)
{
return Redirect("~/Home/Enter");
}
var eventDetails = APIClient.GetRequest<EventViewModel>($"api/main/GetEvent?EventId={id}");
return View(eventDetails);
}
[HttpPost]
public void UpdateEvent(int id, string name, string description, string type, string phone, string email, string address, string city, string status, int count, DateTime timestart, DateTime timeend)
{
if (APIClient.Client == null)
{
throw new Exception("Íåîáõîäèìà àâòîðèçàöèÿ");
}
APIClient.PostRequest("api/main/UpdateEvent", new EventBindingModel
{
Id = id,
Name = name,
Description = description,
Type = type,
ContactPhone = phone,
Address = address,
City = city,
Status = status,
ContactEmail = email,
TimeEnd = timeend.ToUniversalTime(),
TimeStart = timestart.ToUniversalTime(),
Date = DateTime.Now.ToUniversalTime(),
CountVisitors = count,
FreePlaces = count,
OrganizerId = APIClient.Client.Id
});
Response.Redirect("MyEvents");
}
}
}

View File

@ -2,20 +2,33 @@
ViewData["Title"] = "Enter";
}
<div class="text-center">
<h2 class="display-4">Вход в приложение</h2>
<div class="containerenter text-center mt-5">
<h2 class="display-4 mb-4">Вход в приложение</h2>
<form method="post" class="border p-4 rounded">
<div class="mb-4">
<label for="InputEmail1" class="form-label" style="font-size: 24px;">Введите e-mail</label>
<input type="email" name="login" class="form-control form-control-lg" id="InputEmail1" placeholder="example@example.com" required>
</div>
<div class="mb-4">
<label for="InputPassword1" class="form-label" style="font-size: 24px;">Введите пароль</label>
<input type="password" name="password" class="form-control form-control-lg" id="InputPassword1" placeholder="********" required>
</div>
<div class="mb-4">
<button type="submit" class="btn btn-dark btn-lg w-100">Войти</button>
</div>
<div>
<a href="/forgot-password" class="text-decoration-none">Забыли пароль?</a>
</div>
</form>
</div>
<form method ="post">
<div class="mb-3">
<label for="InputEmail1" class="form-label" style="font-size: 30px;">Введите e-mail</label>
<input type="email" name="login" class="form-control" id="InputEmail1" aria-describedby="emailHelp">
</div>
<div class="mb-3">
<label for="InputPassword1" class="form-label" style="font-size: 30px";>Введите пароль</label>
<input type="password" name="password" class="form-control" id="InputPassword1">
</div>
<div class="mb-3" style="width: 100%">
<button type="submit" style="background-color:black; width: 100%; font-size: 30px;" class="btn btn-primary">Войти</button>
</div>
</form>
<style>
.containerenter {
max-width: 500px;
margin: auto;
background-color: #f8f9fa;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
</style>

View File

@ -2,67 +2,70 @@
@model List<EventViewModel>
@{
ViewData["Title"] = "MyEvents";
ViewData["Title"] = "Мои мероприятия";
}
<div class="text-center">
<div class="container mt-5">
<div class="text-center">
<h1 class="display-4">Мои мероприятия</h1>
</div>
</div>
<div class="text-center">
<div class="text-center mt-4">
@{
if (Model == null)
{
<h3 class="display-4">Авторизируйтесь</h3>
return;
}
<p>
<a class="btn btn-warning" asp-action="CreateEvent">Создать мероприятие</a>
<a class="btn btn-warning" asp-action="">Удалить</a>
<a class="btn btn-warning" asp-action="">Редактировать</a>
<a class="btn btn-light" asp-action="CreateEvent">Создать мероприятие</a>
</p>
<table class="table">
<thead>
<table class="table table-striped table-bordered mt-4">
<thead class="thead-light">
<tr>
<th>
Название
</th>
<th>
Дата начала
</th>
<th>
Статус
</th>
<th>
Свободные места
</th>
<th>
</th>
<th>Название</th>
<th>Дата начала</th>
<th>Статус</th>
<th>Свободные места</th>
<th>Действия</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@Html.DisplayFor(modelItem => item.Name)</td>
<td>@Html.DisplayFor(modelItem => item.TimeStart)</td>
<td>@Html.DisplayFor(modelItem => item.Status)</td>
<td>@Html.DisplayFor(modelItem => item.FreePlaces)</td>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.TimeStart)
</td>
<td>
@Html.DisplayFor(modelItem => item.Status)
</td>
<td>
@Html.DisplayFor(modelItem => item.FreePlaces)
</td>
<td>
<a class="btn btn-success btn-sm" asp-action="UpdateEvent" asp-route-id="@item.Id">Редактировать</a>
<a class="btn btn-danger btn-sm" asp-action="DeleteEvent" asp-route-id="@item.Id">Удалить</a>
<a class="btn btn btn-secondary btn-sm" asp-action="ViewEvent" asp-route-id="@item.Id">Посмотреть</a>
</td>
</tr>
}
</tbody>
</table>
}
</div>
</div>
<style>
body {
background-color: #f8f9fa;
}
.table {
margin-top: 20px;
}
.btn {
transition: background-color 0.3s ease;
}
.btn-light {
background-color: #e9ecef; /* Светло-серый цвет */
color: #495057; /* Тёмный текст для контраста */
}
.btn-light:hover {
background-color: #d3d3d3; /* Более тёмный светло-серый при наведении */
}
</style>

View File

@ -2,51 +2,74 @@
ViewData["Title"] = "Register";
}
<div class="text-center">
<h2 class="display-4">Регистрация</h2>
</div>
<form method="post">
<div class="containerenter text-center mt-5">
<h2 class="display-4 mb-4">Регистрация</h2>
<div class="mb-3">
<label for="InputEmail1" class="form-label">Введите e-mail</label>
<input type="email" name="login" class="form-control" id="InputEmail1" aria-describedby="emailHelp">
<form method="post" class="border p-4 rounded">
<div class="mb-4">
<label for="InputEmail1" class="form-label" style="font-size: 24px";>Введите e-mail</label>
<input type="email" name="login" class="form-control" id="InputEmail1" required>
<div class="invalid-feedback">Пожалуйста, введите корректный e-mail.</div>
</div>
<div class="mb-3">
<label for="InputPassword1" class="form-label">Введите пароль</label>
<input type="password" name="password" class="form-control" id="InputPassword1">
<div class="mb-4">
<label for="InputPassword1" class="form-label" style="font-size: 24px">Введите пароль</label>
<input type="password" name="password" class="form-control" id="InputPassword1" required>
<div class="invalid-feedback">Пожалуйста, введите пароль.</div>
</div>
<div class="mb-3">
<label for="InputF" class="form-label">Введите фамилию</label>
<input type="text" name="surname" class="form-control" id="InputF" />
<div class="mb-4">
<label for="InputF" class="form-label" style="font-size: 24px">Введите фамилию</label>
<input type="text" name="surname" class="form-control" id="InputF" required>
<div class="invalid-feedback">Пожалуйста, введите фамилию.</div>
</div>
<div class="mb-3">
<label for="InputI" class="form-label">Введите имя</label>
<input type="text" name="name" class="form-control" id="InputI" />
<div class="mb-4">
<label for="InputI" class="form-label" style="font-size: 24px">Введите имя</label>
<input type="text" name="name" class="form-control" id="InputI" required>
<div class="invalid-feedback">Пожалуйста, введите имя.</div>
</div>
<div class="mb-3">
<label for="InputO" class="form-label">Введите отчество</label>
<input type="text" name="lastname" class="form-control" id="InputO" />
<div class="mb-4">
<label for="InputO" class="form-label" style="font-size: 24px">Введите отчество</label>
<input type="text" name="lastname" class="form-control" id="InputO">
</div>
<div class="mb-3">
<label for="InputO" class="form-label">Введите название компании</label>
<input type="text" name="organizationName" class="form-control" id="InputO" />
<div class="mb-4">
<label for="InputCompany" class="form-label" style="font-size: 24px">Введите название компании</label>
<input type="text" name="organizationName" class="form-control" id="InputCompany">
</div>
<div class="mb-3">
<label for="InputRole" class="form-label">Выберите роль</label>
<select name="role" class="form-control" id="InputRole">
<div class="mb-4">
<label for="InputRole" class="form-label" style="font-size: 24px">Выберите роль</label>
<select name="role" class="form-control" id="InputRole" required>
<option value="" disabled selected>Выберите роль</option>
<option value="Организатор">Организатор</option>
<option value="Регистратор">Регистратор</option>
</select>
<div class="invalid-feedback">Пожалуйста, выберите роль.</div>
</div>
<div class="mb-3">
<label for="InputO" class="form-label">Введите номер телефона</label>
<input type="text" name="phone" class="form-control" id="InputP" />
<div class="mb-4">
<label for="InputP" class="form-label" style="font-size: 24px">Введите номер телефона</label>
<input type="text" name="phone" class="form-control" id="InputP" required>
<div class="invalid-feedback">Пожалуйста, введите номер телефона.</div>
</div>
<div class="mb-3" style="width: 100%">
<button type="submit" style="background-color:black; width: 100%; font-size: 30px;" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#confirmationModal"> Регистрация </button>
<div class="mb-4">
<button type="submit" class="btn btn-dark btn-lg w-100">Регистрация</button>
</div>
</form>
</form>
</div>
<style>
.containerenter {
max-width: 500px;
margin: auto;
background-color: #f8f9fa;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
}
</style>
<div class="modal fade" id="confirmationModal" tabindex="-1" aria-labelledby="confirmationModalLabel" aria-hidden="true">
<div class="modal-dialog">
@ -57,6 +80,7 @@
</div>
<div class="modal-body">
<label for="confirmationCode" class="form-label">Код подтверждения</label>
<input type="text" name="confirmationCode" class="form-control" id="confirmationCode">
<input type="hidden" name="code" id="confirmationCodeHidden" value="">
</div>
<div class="modal-footer">
@ -68,20 +92,41 @@
</div>
<script>
// Показ модального окна при успешной отправке формы
document.forms[0].onsubmit = function (e) {
e.preventDefault(); // Остановить стандартное поведение
$('#confirmationModal').modal('show');
};
document.getElementById('confirmCodeButton').onclick = function () {
const confirmationCode = document.getElementById('confirmationCode').value;
if (confirmationCode) {
// Устанавливаем значение кода в скрытое поле
document.getElementById('confirmationCodeHidden').value = confirmationCode;
// Закрываем модальное окно
$('#confirmationModal').modal('hide');
// Отправляем форму
document.forms[0].submit(); // Отправляет первую форму на странице
} else {
alert("Введите код подтверждения.");
}
};
// Валидация формы
(function () {
'use strict'
const forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
</script>

View File

@ -0,0 +1,106 @@
@using EventVisitorLogic.ViewModels
@model EventViewModel
@{
ViewData["Title"] = "UpdateEvent";
}
<div class="container mt-5">
<h2 class="text-center mb-4">Редактирование мероприятия</h2>
<form method="post" class="needs-validation" novalidate>
<div class="row mb-3">
<label for="name" class="col-sm-4 col-form-label">Название мероприятия:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="name" name="name" value="@Html.DisplayFor(model => model.Name)" required>
<div class="invalid-feedback">Пожалуйста, введите название мероприятия.</div>
</div>
</div>
<div class="row mb-3">
<label for="timestart" class="col-sm-4 col-form-label">Дата и время начала:</label>
<div class="col-sm-8">
<input type="datetime-local" class="form-control" id="timestart" name="timestart"
value="@Model.TimeStart.ToString("yyyy-MM-ddTHH:mm")" required>
<div class="invalid-feedback">Пожалуйста, выберите дату и время начала.</div>
</div>
</div>
<div class="row mb-3">
<label for="timeend" class="col-sm-4 col-form-label">Дата и время конца:</label>
<div class="col-sm-8">
<input type="datetime-local" class="form-control" id="timeend" name="timeend"
value="@Model.TimeEnd.ToString("yyyy-MM-ddTHH:mm")" required>
<div class="invalid-feedback">Пожалуйста, выберите дату и время окончания.</div>
</div>
</div>
<div class="row mb-3">
<label for="description" class="col-sm-4 col-form-label">Описание:</label>
<div class="col-sm-8">
<textarea class="form-control" id="description" name="description" rows="3">@Model.Description</textarea>
</div>
</div>
<div class="row mb-3">
<label for="type" class="col-sm-4 col-form-label">Тип:</label>
<div class="col-sm-8">
<select class="form-select" id="type" name="type">
<option value="">@Html.DisplayFor(model => model.Type)</option>
<option value="Конференция">Конференция</option>
<option value="Встреча">Встреча</option>
<option value="Семинар">Семинар</option>
<option value="Тренинг">Тренинг</option>
<option value="Фестиваль">Фестиваль</option>
<option value="Соревнование">Соревнование</option>
<option value="Другое">Другое</option>
</select>
<div class="invalid-feedback">Пожалуйста, выберите тип мероприятия.</div>
</div>
</div>
<div class="row mb-3">
<label for="phone" class="col-sm-4 col-form-label">Контактный телефон:</label>
<div class="col-sm-8">
<input type="tel" class="form-control" id="phone" name="phone" value="@Html.DisplayFor(model => model.ContactPhone)" required>
<div class="invalid-feedback">Пожалуйста, введите контактный телефон.</div>
</div>
</div>
<div class="row mb-3">
<label for="email" class="col-sm-4 col-form-label">Почта:</label>
<div class="col-sm-8">
<input type="email" class="form-control" id="email" name="email" value="@Html.DisplayFor(model => model.ContactEmail)" required>
<div class="invalid-feedback">Пожалуйста, введите корректный email.</div>
</div>
</div>
<div class="row mb-3">
<label for="address" class="col-sm-4 col-form-label">Адрес:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="address" name="address" value="@Html.DisplayFor(model => model.Address)" required>
<div class="invalid-feedback">Пожалуйста, введите адрес.</div>
</div>
</div>
<div class="row mb-3">
<label for="city" class="col-sm-4 col-form-label">Город:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="city" name="city" value="@Html.DisplayFor(model => model.City)" required>
<div class="invalid-feedback">Пожалуйста, введите город.</div>
</div>
</div>
<div class="row mb-3">
<label for="status" class="col-sm-4 col-form-label">Статус:</label>
<div class="col-sm-8">
<select class="form-select" id="status" name="status" value="@Html.DisplayFor(model => model.Status)">
<option value="">@Html.DisplayFor(model => model.Status)</option>
<option value="Регистрация открыта">Регистрация открыта</option>
<option value="Регистрация закрыта">Регистрация закрыта</option>
</select>
<div class="invalid-feedback">Пожалуйста, выберите статус мероприятия.</div>
</div>
</div>
<div class="row mb-3">
<label for="count" class="col-sm-4 col-form-label">Количество посетителей:</label>
<div class="col-sm-8">
<input type="number" class="form-control" id="count" name="count" value="@Html.DisplayFor(model => model.CountVisitors)" required>
<div class="invalid-feedback">Пожалуйста, введите количество посетителей.</div>
</div>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-4">
<button type="submit" style="background-color:black; width: 100%; font-size: 20px;" class="btn btn-block btn-dark">Сохранить</button>
</div>
</div>
</form>

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace EventVisitorClientApp.Views.Home
{
public class UpdateEventModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -0,0 +1,86 @@
@using EventVisitorLogic.ViewModels
@model EventViewModel
@{
ViewData["Title"] = "Просмотр мероприятия";
}
<div class="container enter mt-5">
<div class="row">
<div class="col-md-6">
<div class="card h-90">
<div class="card-header bg-secondary text-light">
<h2> @Html.DisplayFor(model => model.Name)</h2>
</div>
<div class="card-body">
<h4>Описание:</h4>
<p>@Html.DisplayFor(model => model.Description)</p>
<h4>Дата начала:</h4>
<p>@Html.DisplayFor(model => model.TimeStart)</p>
<h4>Дата окончания:</h4>
<p>@Html.DisplayFor(model => model.TimeEnd)</p>
<h4>Статус:</h4>
<p>@Html.DisplayFor(model => model.Status)</p>
<h4>Город:</h4>
<p>@Html.DisplayFor(model => model.City)</p>
<h4>Адресс:</h4>
<p>@Html.DisplayFor(model => model.Address)</p>
<h4>Всего мест:</h4>
<p>@Html.DisplayFor(model => model.CountVisitors)</p>
<h4>Свободных мест:</h4>
<p>@Html.DisplayFor(model => model.FreePlaces)</p>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card h-90 mb-4">
<div class="card-header bg-secondary text-light">
<h2>Сообщение участникам</h2>
</div>
<div class="card-body">
<form id="messageForm">
<div class="form-group">
<label for="subject" style="font-size: 20px;">Тема сообщения</label>
<input type="text" class="form-control" id="subject" placeholder="Введите тему сообщения" required>
</div>
<div class="form-group">
<label for="message">Текст сообщения</label>
<textarea class="form-control" id="message" rows="10" placeholder="Введите текст сообщения" required></textarea>
</div>
<button type="submit" class="btn btn-black btn-block">Отправить</button>
</form>
</div>
</div>
<button type="submit" class="btn btn-black btn-block mb-4">Отправить</button>
<button type="submit" class="btn btn-black btn-block">Отправить</button>
</div>
</div>
</div>
<style>
body {
background-color: #f8f9fa;
}
.card {
margin-top: 20px;
padding: 20px;
}
.form-group {
margin-bottom: 15px;
}
#message {
height: 150px;
}
.btn-black {
background-color: black; /* Цвет кнопки */
color: white; /* Цвет текста кнопки */
}
.btn-block {
width: 100%; /* Широкая кнопка */
}
</style>

View File

@ -0,0 +1,12 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace EventVisitorClientApp.Views.Home
{
public class ViewEventModel : PageModel
{
public void OnGet()
{
}
}
}

View File

@ -42,24 +42,9 @@ namespace EventVisitorDatabase.Entities
public int CountVisitors { get; set; }
[Required]
public int FreePlaces { get; set; }
[Required]
public int OrganizerId { get; set; }
[ForeignKey("EventId")]
public virtual List<OrganizerEvent> Organizers { get; set; } = new();
private Dictionary<int, OrganizerEntity>? _eventOrginizers = null;
[NotMapped]
public Dictionary<int, OrganizerEntity> OrganizerEvent
{
get
{
if (_eventOrginizers == null)
{
_eventOrginizers = Organizers
.ToDictionary(rec => rec.OrganizerId, rec => (rec.Organizer as OrganizerEntity));
}
return _eventOrginizers;
}
}
public static EventEntity? Create(EventBindingModel model)
{
@ -69,7 +54,7 @@ namespace EventVisitorDatabase.Entities
}
return new EventEntity()
{
Id = (int)(model?.Id),
Id = model.Id,
Name = model.Name,
Date = model.Date,
TimeStart = model.TimeStart,
@ -82,7 +67,8 @@ namespace EventVisitorDatabase.Entities
City = model.City,
Status = model.Status,
CountVisitors = model.CountVisitors,
FreePlaces = model.FreePlaces
FreePlaces = model.FreePlaces,
OrganizerId = model.OrganizerId
};
}
@ -103,25 +89,11 @@ namespace EventVisitorDatabase.Entities
City = model.City,
Status = model.Status,
CountVisitors = model.CountVisitors,
FreePlaces = model.FreePlaces
FreePlaces = model.FreePlaces,
OrganizerId = model.OrganizerId
};
}
public void UpdateOrganizer(EventVisitorDbContext context, EventBindingModel model)
{
var events = context.Events.First(x => x.Id == Id);
foreach (var fs in model.OrganizerEvent)
{
context.OrganizerEvent.Add(new OrganizerEvent
{
Event = events,
Organizer = context.Organizers.First(x => x.Id == fs.Value.Id)
});
context.SaveChanges();
}
_eventOrginizers = null;
}
public void Update(EventBindingModel model)
{
Name = model.Name;
@ -155,6 +127,7 @@ namespace EventVisitorDatabase.Entities
Status = Status,
CountVisitors = CountVisitors,
FreePlaces = FreePlaces,
OrganizerId = OrganizerId
};
}
}

View File

@ -31,23 +31,7 @@ namespace EventVisitorDatabase.Entities
[Required]
public string Phone { get; set; } = string.Empty;
[ForeignKey("OrganizerId")]
public virtual List<OrganizerEvent> Events { get; set; } = new();
private Dictionary<int, EventEntity>? _eventOrginizers = null;
[NotMapped]
public Dictionary<int, EventEntity> OrganizerEvent
{
get
{
if (_eventOrginizers == null)
{
_eventOrginizers = Events
.ToDictionary(rec => rec.EventId, rec => (rec.Event as EventEntity));
}
return _eventOrginizers;
}
}
public static OrganizerEntity? Create(OrganizerBindingModel model)
{
@ -85,20 +69,6 @@ namespace EventVisitorDatabase.Entities
};
}
public void UpdateEvents(EventVisitorDbContext context, OrganizerBindingModel model)
{
var organizer = context.Organizers.First(x => x.Id == Id);
foreach (var fs in model.OrganizerEvent)
{
context.OrganizerEvent.Add(new OrganizerEvent
{
Organizer = organizer,
Event = context.Events.First(x => x.Id == fs.Value.Id)
});
context.SaveChanges();
}
_eventOrginizers = null;
}
public void Update(OrganizerBindingModel model)
{

View File

@ -1,20 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace EventVisitorDatabase.Entities
{
public class OrganizerEvent
{
public int Id { get; set; }
[Required]
public int EventId { get; set; }
[Required]
public int OrganizerId { get; set; }
public virtual EventEntity Event { get; set; } = new();
public virtual OrganizerEntity Organizer { get; set; } = new();
}
}

View File

@ -17,6 +17,5 @@ namespace EventVisitorDatabase
public virtual DbSet<VisitorEntity> Visitors { get; set; }
public virtual DbSet<OrganizerEntity> Organizers { get; set; }
public virtual DbSet<EventEntity> Events { get; set; }
public DbSet<OrganizerEvent> OrganizerEvent { get; set; }
}
}

View File

@ -13,7 +13,7 @@ namespace EventVisitorDatabase.Implements
public EventViewModel? Delete(EventBindingModel model)
{
using var context = new EventVisitorDbContext();
var element = context.Events.Include(x => x.Organizers).ThenInclude(x => x.Organizer).FirstOrDefault(rec => rec.Id == model.Id);
var element = context.Events.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Events.Remove(element);
@ -25,23 +25,20 @@ namespace EventVisitorDatabase.Implements
public EventViewModel? GetElement(EventBindingModel model)
{
if (!model.Id.HasValue)
if (model.Id < 0)
{
return null;
}
using var context = new EventVisitorDbContext();
return context.Events.
Include(x => x.Organizers).
ThenInclude(x => x.Organizer).
FirstOrDefault(x => (model.Id.HasValue && x.Id == model.Id))?
FirstOrDefault(x => (x.Id == model.Id))?
.GetViewModel;
}
public List<EventViewModel> GetFullList()
{
using var context = new EventVisitorDbContext();
return context.Events.Include(x => x.Organizers).
ThenInclude(x => x.Organizer)
return context.Events
.ToList()
.Select(x => x.GetViewModel)
.ToList();
@ -58,8 +55,6 @@ namespace EventVisitorDatabase.Implements
context.Events.Add(newRecipe);
context.SaveChanges();
return context.Events
.Include(x => x.Organizers)
.ThenInclude(x => x.Organizer)
.FirstOrDefault(x => x.Id == newRecipe.Id)
?.GetViewModel;
}
@ -77,8 +72,6 @@ namespace EventVisitorDatabase.Implements
}
recipe.Update(model);
context.SaveChanges();
if (model.OrganizerEvent != null)
recipe.UpdateOrganizer(context, model);
transaction.Commit();
return recipe.GetViewModel;
}

View File

@ -16,7 +16,7 @@ namespace EventVisitorDatabase.Implements
public OrganizerViewModel? Delete(OrganizerBindingModel model)
{
using var context = new EventVisitorDbContext();
var element = context.Organizers.Include(x => x.Events).ThenInclude(x => x.Event).FirstOrDefault(rec => rec.Id == model.Id);
var element = context.Organizers.FirstOrDefault(rec => rec.Id == model.Id);
if (element != null)
{
context.Organizers.Remove(element);
@ -28,14 +28,15 @@ namespace EventVisitorDatabase.Implements
public OrganizerViewModel? GetElement(OrganizerBindingModel model)
{
if (model.Id > 0)
if (model.Id < 0)
{
return null;
}
using var context = new EventVisitorDbContext();
if (!string.IsNullOrEmpty(model.Email) && !string.IsNullOrEmpty(model.Password))
return context.Organizers.FirstOrDefault(x => x.Email.Equals(model.Email) && x.Password.Equals(model.Password))?.GetViewModel;
return context.Organizers.
Include(x => x.Events).
ThenInclude(x => x.Event).
FirstOrDefault(x => (x.Id == model.Id))?
.GetViewModel;
}
@ -43,13 +44,13 @@ namespace EventVisitorDatabase.Implements
public List<OrganizerViewModel> GetFullList()
{
using var context = new EventVisitorDbContext();
return context.Organizers.Include(x => x.Events).
ThenInclude(x => x.Event)
return context.Organizers
.ToList()
.Select(x => x.GetViewModel)
.ToList();
}
public OrganizerViewModel? Insert(OrganizerBindingModel model)
{
using var context = new EventVisitorDbContext();
@ -61,8 +62,6 @@ namespace EventVisitorDatabase.Implements
context.Organizers.Add(newRecipe);
context.SaveChanges();
return context.Organizers
.Include(x => x.Events)
.ThenInclude(x => x.Event)
.FirstOrDefault(x => x.Id == newRecipe.Id)
?.GetViewModel;
}
@ -80,8 +79,6 @@ namespace EventVisitorDatabase.Implements
}
recipe.Update(model);
context.SaveChanges();
if (model.OrganizerEvent != null)
recipe.UpdateEvents(context, model);
transaction.Commit();
return recipe.GetViewModel;
}

View File

@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace EventVisitorDatabase.Migrations
{
[DbContext(typeof(EventVisitorDbContext))]
[Migration("20241103104453_InitialCreate")]
[Migration("20241104114850_InitialCreate")]
partial class InitialCreate
{
/// <inheritdoc />
@ -66,6 +66,9 @@ namespace EventVisitorDatabase.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<int>("OrganizerId")
.HasColumnType("integer");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text");
@ -130,29 +133,6 @@ namespace EventVisitorDatabase.Migrations
b.ToTable("Organizers");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEvent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EventId")
.HasColumnType("integer");
b.Property<int>("OrganizerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("EventId");
b.HasIndex("OrganizerId");
b.ToTable("OrganizerEvent");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.VisitorEntity", b =>
{
b.Property<int>("Id")
@ -190,25 +170,6 @@ namespace EventVisitorDatabase.Migrations
b.ToTable("Visitors");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEvent", b =>
{
b.HasOne("EventVisitorDatabase.Entities.EventEntity", "Event")
.WithMany("Organizers")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("EventVisitorDatabase.Entities.OrganizerEntity", "Organizer")
.WithMany("Events")
.HasForeignKey("OrganizerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Event");
b.Navigation("Organizer");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.VisitorEntity", b =>
{
b.HasOne("EventVisitorDatabase.Entities.EventEntity", "Event")
@ -219,16 +180,6 @@ namespace EventVisitorDatabase.Migrations
b.Navigation("Event");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.EventEntity", b =>
{
b.Navigation("Organizers");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEntity", b =>
{
b.Navigation("Events");
});
#pragma warning restore 612, 618
}
}

View File

@ -30,7 +30,8 @@ namespace EventVisitorDatabase.Migrations
City = table.Column<string>(type: "text", nullable: false),
Status = table.Column<string>(type: "text", nullable: false),
CountVisitors = table.Column<int>(type: "integer", nullable: false),
FreePlaces = table.Column<int>(type: "integer", nullable: false)
FreePlaces = table.Column<int>(type: "integer", nullable: false),
OrganizerId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
@ -81,42 +82,6 @@ namespace EventVisitorDatabase.Migrations
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "OrganizerEvent",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
EventId = table.Column<int>(type: "integer", nullable: false),
OrganizerId = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_OrganizerEvent", x => x.Id);
table.ForeignKey(
name: "FK_OrganizerEvent_Events_EventId",
column: x => x.EventId,
principalTable: "Events",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_OrganizerEvent_Organizers_OrganizerId",
column: x => x.OrganizerId,
principalTable: "Organizers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_OrganizerEvent_EventId",
table: "OrganizerEvent",
column: "EventId");
migrationBuilder.CreateIndex(
name: "IX_OrganizerEvent_OrganizerId",
table: "OrganizerEvent",
column: "OrganizerId");
migrationBuilder.CreateIndex(
name: "IX_Visitors_EventId",
table: "Visitors",
@ -127,14 +92,11 @@ namespace EventVisitorDatabase.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "OrganizerEvent");
name: "Organizers");
migrationBuilder.DropTable(
name: "Visitors");
migrationBuilder.DropTable(
name: "Organizers");
migrationBuilder.DropTable(
name: "Events");
}

View File

@ -63,6 +63,9 @@ namespace EventVisitorDatabase.Migrations
.IsRequired()
.HasColumnType("text");
b.Property<int>("OrganizerId")
.HasColumnType("integer");
b.Property<string>("Status")
.IsRequired()
.HasColumnType("text");
@ -127,29 +130,6 @@ namespace EventVisitorDatabase.Migrations
b.ToTable("Organizers");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEvent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("EventId")
.HasColumnType("integer");
b.Property<int>("OrganizerId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("EventId");
b.HasIndex("OrganizerId");
b.ToTable("OrganizerEvent");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.VisitorEntity", b =>
{
b.Property<int>("Id")
@ -187,25 +167,6 @@ namespace EventVisitorDatabase.Migrations
b.ToTable("Visitors");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEvent", b =>
{
b.HasOne("EventVisitorDatabase.Entities.EventEntity", "Event")
.WithMany("Organizers")
.HasForeignKey("EventId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.HasOne("EventVisitorDatabase.Entities.OrganizerEntity", "Organizer")
.WithMany("Events")
.HasForeignKey("OrganizerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Event");
b.Navigation("Organizer");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.VisitorEntity", b =>
{
b.HasOne("EventVisitorDatabase.Entities.EventEntity", "Event")
@ -216,16 +177,6 @@ namespace EventVisitorDatabase.Migrations
b.Navigation("Event");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.EventEntity", b =>
{
b.Navigation("Organizers");
});
modelBuilder.Entity("EventVisitorDatabase.Entities.OrganizerEntity", b =>
{
b.Navigation("Events");
});
#pragma warning restore 612, 618
}
}

View File

@ -10,7 +10,7 @@ namespace EventVisitorLogic.BindingModels
{
public class EventBindingModel: IEventModel
{
public int? Id { get; set; }
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public DateTime Date { get; set; }
public DateTime TimeStart { get; set; }
@ -24,11 +24,6 @@ namespace EventVisitorLogic.BindingModels
public string Status { get; set; } = string.Empty;
public int CountVisitors { get; set; }
public int FreePlaces { get; set; }
public Dictionary<int, IOrganizerModel> OrganizerEvent
{
get;
set;
} = new();
public int OrganizerId { get; set; }
}
}

View File

@ -111,10 +111,6 @@ namespace EventVisitorLogic.Logic
{
throw new ArgumentNullException("Некорректный количество посетителей, nameof(model.CountVisitors)");
}
if (model.Date <= DateTime.Now.AddHours(2))
{
throw new ArgumentNullException("Нельзя выбрать дату меньше сегодняшней", nameof(model.Date));
}
if (model.TimeStart <= DateTime.Now.AddHours(2))
{
throw new ArgumentNullException("Нельзя выбрать время меньше, чем через 2 часа от текущего", nameof(model.Date));

View File

@ -23,5 +23,6 @@ namespace EventVisitorLogic.ViewModels
public string Status { get; set; } = string.Empty;
public int CountVisitors { get; set; }
public int FreePlaces { get; set; }
public int OrganizerId { get; set; }
}
}

View File

@ -22,6 +22,7 @@ namespace EventVisitorModels
public string Status { get; set; } = string.Empty;
public int CountVisitors { get; set; }
public int FreePlaces { get; set; }
public int OrganizerId { get; set; }
}
}

View File

@ -21,21 +21,40 @@ namespace EventVisitorRestApi.Controllers
}
/// Мероприятия
[HttpGet]
public List<EventViewModel>? GetEvents()
public List<EventViewModel>? GetEventList(int organizerId)
{
try
{
//if (clientId == null)
//{
// return _event.ReadList(null);
//}
if (organizerId == null)
{
return _event.ReadList(null);
}
return _event.ReadList(new EventBindingModel
{
OrganizerId = organizerId
});
}
catch (Exception ex)
{
throw;
}
}
[HttpPost]
public void CreateEvent(EventBindingModel model)
{
try
{
_event.Create(model);
}
catch (Exception ex)
{
throw;
}
}
//[HttpGet]
//public List<ProceduresViewModel>? GetProcedures()
//{
@ -155,22 +174,21 @@ namespace EventVisitorRestApi.Controllers
// throw;
// }
//}
//[HttpGet]
//public MedicinesViewModel? GetMedicine(int medicineId)
//{
// try
// {
// return _medicine.ReadElement(new MedicinesSearchModel
// {
// Id = medicineId
// });
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "Ошибка получения лекарства по id={Id}", medicineId);
// throw;
// }
//}
[HttpGet]
public EventViewModel? GetEvent(int eventId)
{
try
{
return _event.ReadElement(new EventBindingModel
{
Id = eventId
});
}
catch (Exception ex)
{
throw;
}
}
//[HttpPost]
//public void CreateMedicine(MedicinesBindingModel model)
@ -185,33 +203,31 @@ namespace EventVisitorRestApi.Controllers
// throw;
// }
//}
//[HttpPost]
//public void UpdateMedicine(MedicinesBindingModel model)
//{
// try
// {
// _medicine.Update(model);
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "Ошибка обновления лекарства");
// throw;
// }
//}
[HttpPost]
public void UpdateEvent(EventBindingModel model)
{
try
{
_event.Update(model);
}
catch (Exception ex)
{
throw;
}
}
//[HttpPost]
//public void DeleteMedicine(MedicinesBindingModel model)
//{
// try
// {
// _medicine.Delete(model);
// }
// catch (Exception ex)
// {
// _logger.LogError(ex, "Ошибка удаления лекарства");
// throw;
// }
//}
[HttpPost]
public void DeleteEvent(EventBindingModel model)
{
try
{
_event.Delete(model);
}
catch (Exception ex)
{
throw;
}
}
///// <summary>
///// РЕЦЕПТЫ