Commit 074a6e78 authored by SergeevaAA's avatar SergeevaAA

Merge branch 'feature/#13-Statistics' into 'develop'

#13 - Добавлен просмотр статистики действий с файлами

See merge request !13
parents b328bfa1 efd1c9f5
namespace FileDesk.Domain.Enums
{
using System.ComponentModel.DataAnnotations;
/// <summary>
/// Тип действия с файлом
/// </summary>
......@@ -8,11 +10,13 @@
/// <summary>
/// Загрузка
/// </summary>
[Display(Name = "Загрузка")]
Upload = 1,
/// <summary>
/// Выгрузка (скачивание)
/// </summary>
[Display(Name = "Скачивание")]
Download = 2
}
}
\ No newline at end of file
namespace FileDesk.Domain.ViewModels
{
using System;
using FileDesk.Domain.Models;
/// <summary>
/// Вью-модель действия с файлом
/// </summary>
public class ActionViewModel : AbstractEntity
{
/// <summary>
/// Идентификатор файла
/// </summary>
public virtual long FileId { get; set; }
/// <summary>
/// Название файла
/// </summary>
public virtual string FileName { get; set; }
/// <summary>
/// Логин пользователя
/// </summary>
public virtual string UserLogin { get; set; }
/// <summary>
/// Дата и время
/// </summary>
public virtual DateTime DateTime { get; set; }
/// <summary>
/// Тип действия
/// </summary>
public virtual string ActionType { get; set; }
}
}
\ No newline at end of file
namespace FileDesk.Services.Interfaces
{
using System.Collections.Generic;
using System.Linq;
using FileDesk.DataAccess.Repository;
using FileDesk.Domain.Enums;
using FileDesk.Domain.ViewModels;
using Microsoft.EntityFrameworkCore;
/// <summary>
/// Сервис для работы со статистикой действий с файлами
/// </summary>
public class ActionService : IActionService
{
private readonly FileDeskContext _db;
/// <summary>
/// Создает новый экземпляр класса <see cref = "ActionService"/>
/// </summary>
/// <param name="db">Контекст для работы с БД</param>
public ActionService(FileDeskContext db)
{
_db = db;
}
/// <summary>
/// Получение статистики
/// </summary>
/// <returns>Список действий с файлами</returns>
public List<ActionViewModel> GetAll()
{
return _db.Actions.OrderByDescending(a => a.DateTime).Include(a => a.User).Include(a => a.File)
.Select(a => new ActionViewModel
{
Id = a.Id,
FileId = a.FileId,
FileName = a.File.Name,
ActionType = a.ActionType.GetDisplayName(),
DateTime = a.DateTime,
UserLogin = a.User.Login
}).ToList();
}
}
}
\ No newline at end of file
namespace FileDesk.Services.Interfaces
{
using System.Collections.Generic;
using FileDesk.Domain.ViewModels;
/// <summary>
/// Интерфейс сервиса для работы со статистикой действий с файлами
/// </summary>
public interface IActionService
{
/// <summary>
/// Получение статистики
/// </summary>
/// <returns>Список действий с файлами</returns>
List<ActionViewModel> GetAll();
}
}
\ No newline at end of file
namespace FileDesk.Web.Controllers
{
using System;
using Microsoft.AspNetCore.Mvc;
using FileDesk.Services.Interfaces;
using FileDesk.Web.Helpers;
using Microsoft.AspNetCore.Authorization;
/// <summary>
/// Контроллер для работы со статистикой действий с файлами
/// </summary>
[Authorize(Roles = "admin")]
public class ActionController : Controller
{
#region Свойства
private readonly IActionService _actionService;
#endregion
#region Конструкторы и деструкторы
/// <summary>
/// Создает новый экземпляр класса <see cref = "ActionController"/>
/// </summary>
/// <param name="actionService">Сервис для работы со статистикой действий с файлами</param>
public ActionController(IActionService actionService)
{
_actionService = actionService;
}
#endregion
#region Методы
/// <summary>
/// Получение статистики действий с файлами
/// </summary>
/// <returns>Статистика действий с файлами</returns>
[Authorize(Roles = "admin")]
[HttpGet]
public IActionResult Index()
{
try
{
var model = _actionService.GetAll();
return View(model);
}
catch (Exception ex)
{
return PartialView("Error", ExceptionHelper.GetMessage(ex));
}
}
#endregion
}
}
\ No newline at end of file
......@@ -13,6 +13,8 @@
/// <summary>
/// Контроллер для работы с файлами
/// </summary>
///
[Authorize]
public class FileController : Controller
{
#region Свойства
......
......@@ -2,32 +2,24 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
namespace FileDesk.Web.Controllers
{
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
[Authorize(Roles = "admin, user")]
public IActionResult Index()
public IActionResult About()
{
return View();
}
public IActionResult AccessDenied()
[Authorize(Roles = "admin, user")]
public IActionResult Contacts()
{
return View();
}
[Authorize(Roles = "admin")]
public IActionResult About()
public IActionResult AccessDenied()
{
return View();
}
......@@ -38,4 +30,4 @@ namespace FileDesk.Web.Controllers
return View();
}
}
}
}
\ No newline at end of file
......@@ -8,6 +8,7 @@
using FileDesk.Domain.ViewModels;
using FileDesk.Services.Interfaces;
using Microsoft.AspNetCore.Authorization;
/// <summary>
/// Контроллер для работы с пользователями
......@@ -38,6 +39,7 @@
/// Получение страницы регистрации
/// </summary>
/// <returns>Страница регистрации</returns>
[AllowAnonymous]
[HttpGet]
public IActionResult Register()
{
......@@ -51,6 +53,7 @@
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
[AllowAnonymous]
public async Task<IActionResult> Register(RegisterViewModel model)
{
if (!_userService.IsExist(model.Login))
......@@ -73,6 +76,7 @@
/// Получение страницы авторизации
/// </summary>
/// <returns>Страница авторизации</returns>
[AllowAnonymous]
[HttpGet]
public IActionResult Login()
{
......@@ -83,6 +87,7 @@
/// Авторизация пользователя
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(LoginViewModel model)
......@@ -106,8 +111,8 @@
/// Выход со страницы пользователя
/// </summary>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize]
[HttpGet]
public async Task<IActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
......
......@@ -35,6 +35,7 @@ namespace FileDesk.Web
services.AddTransient<IUserService, UserService>();
services.AddTransient<IFileService, FileService>();
services.AddTransient<IActionService, ActionService>();
services.AddTransient<Microsoft.AspNetCore.Mvc.Infrastructure.IActionContextAccessor, Microsoft.AspNetCore.Mvc.Infrastructure.ActionContextAccessor>();
services.AddTransient<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
......
@model List<FileDesk.Domain.ViewModels.ActionViewModel>
@{
ViewData["Title"] = "Статистика действий с файлами";
}
<h1>@ViewData["Title"]</h1>
@if (Model != null && Model.Any())
{
<table class="table">
<tr>
<th>Название файла</th>
<th>Дата и время действия</th>
<th>Тип действия</th>
<th>Пользователь</th>
<th>Действия</th>
</tr>
@foreach (var statistics in Model)
{
<tr>
<td>
<input hidden asp-for="@statistics.Id" />
<input hidden asp-for="@statistics.FileId" />
<input asp-for="@statistics.FileName" />
</td>
<td><input asp-for="@statistics.DateTime" /></td>
<td><input asp-for="@statistics.ActionType" /></td>
<td><input asp-for="@statistics.UserLogin" /></td>
<td>
<button type="submit" class="download" onclick="downloadFile(@statistics.FileId)" title="Скачать файл" />
<button type="submit" class="delete" onclick="deleteFile(@statistics.FileId)" title="Удалить файл" />
</td>
</tr>
}
</table>
}
else
{
<br />
<h4>С файлами не производилось никаких действий.</h4>
}
<script>
function downloadFile(id) {
$.get('@Url.Action("GetDownloadUrl", "File")', { id: id })
.done(function (url) {
location.href = url;
})
.fail(function (xhr) {
searchFiles();
alert(xhr.responseText);
})
}
function deleteFile(id) {
$.get('@Url.Action("Delete", "File")', { id: id })
.done(function (message) {
searchFiles();
alert(message);
})
.fail(function (xhr) {
searchFiles();
alert(xhr.responseText);
})
}
</script>
<style>
.download {
height: 30px;
width: 30px;
background-image: url(/images/Download.png);
background-size: cover;
}
.delete {
height: 30px;
width: 30px;
background-image: url(/images/Delete.png);
background-size: cover;
}
</style>
\ No newline at end of file
<h2>Все файлы</h2>
@{
ViewData["Title"] = "Все файлы";
}
<h1>@ViewData["Title"]</h1>
<a asp-action="Upload" asp-controller="File">Добавить файл</a>
<br />
......
@model FileDesk.Domain.ViewModels.UploadViewModel
<h2>Загрузка файла</h2>
@{
ViewData["Title"] = "Загрузка файла";
}
<h1>@ViewData["Title"]</h1>
<form asp-action="Upload" asp-controller="File" asp-anti-forgery="true" enctype="multipart/form-data">
<div class="validation" asp-validation-summary="All"></div>
......@@ -21,7 +24,7 @@
<span asp-validation-for="Description" />
</div>
<div class="form-group">
<input type="submit" value="Загрузить" class="btn" />
<input type="submit" value="Загрузить" class="btn-primary" />
</div>
</div>
</form>
\ No newline at end of file
@{
ViewData["Title"] = "Privacy Policy";
ViewData["Title"] = "О сайте";
}
<h1>@ViewData["Title"]</h1>
......
Здесь будет контактная информация
\ No newline at end of file
@{
ViewData["Title"] = "О разработчике";
}
<h1>@ViewData["Title"]</h1>
Здесь будет контактная информация
\ No newline at end of file
@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
......@@ -3,7 +3,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - FileDesk.Web</title>
<title>@ViewData["Title"] - FileDesk</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
......@@ -11,28 +11,32 @@
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">FileDesk.Web</a>
<a class="navbar-brand" asp-area="" asp-controller="File" asp-action="Index">FileDesk</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="File" asp-action="Index">Все файлы</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="File" asp-action="Upload">Добавить файл</a>
</li>
@if (User.Identity.IsAuthenticated)
{
<li class="nav-item">
<p class="nav-link text-dark">@User.Identity.Name</p>
<a class="nav-link text-dark" asp-area="" asp-controller="File" asp-action="Index">Все файлы</a>
</li>
<li class="nav-item">
<form method="post" asp-controller="User" asp-action="Logout">
<input class="nav-link text-dark" type="submit" value="Выход" />
</form>
<a class="nav-link text-dark" asp-area="" asp-controller="File" asp-action="Upload">Добавить файл</a>
</li>
@if (User.IsInRole("admin"))
{
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Action" asp-action="Index">Просмотр статистики</a>
</li>
}
<li class="nav-item">
<p class="nav-link text-dark">Вы вошли как @User.Identity.Name</p>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="User" asp-action="Logout">Выход</a>
</li>
}
else
......@@ -57,7 +61,7 @@
<footer class="border-top footer text-muted">
<div class="container">
&copy; 2020 - FileDesk.Web - <a asp-area="" asp-controller="Home" asp-action="About">About</a>
&copy; 2020 - FileDesk - <a asp-area="" asp-controller="Home" asp-action="About">О сайте</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
......
@model FileDesk.Domain.ViewModels.LoginViewModel
<h2>Вход на сайт</h2>
@{
ViewData["Title"] = "Вход на сайт";
}
<h1>@ViewData["Title"]</h1>
<a asp-action="Register" asp-controller="User">Регистрация</a>
......@@ -17,7 +21,7 @@
<span asp-validation-for="Password" />
</div>
<div class="form-group">
<input type="submit" value="Войти" class="btn" />
<input type="submit" value="Войти" class="btn-primary" />
</div>
</div>
</form>
\ No newline at end of file
@model FileDesk.Domain.ViewModels.RegisterViewModel
<h2>Регистрация</h2>
@{
ViewData["Title"] = "Регистрация на сайте";
}
<h1>@ViewData["Title"]</h1>
<a asp-action="Login" asp-controller="User">Авторизация</a>
<form asp-action="Register" asp-controller="User" asp-anti-forgery="true">
......@@ -22,7 +25,7 @@
<span asp-validation-for="ConfirmPassword" />
</div>
<div class="form-group">
<input type="submit" value="Регистрация" class="btn" />
<input type="submit" value="Регистрация" class="btn-primary" />
</div>
</div>
</form>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment