Система подачи заявок. RequestController

Создание системы заявок

Последнее обновление: 31.10.2015

Центральным объектом в системе helpdesk является заявка на обслуживание, сообщение о проблеме, что-то поломалось, что-то работает не так. При построении системы надо разграничить права и круг действий всех возможных ролей в системе. Итак, все группы пользователей у нас смогут создавать новые заявки. Далее все группы пользователей могут смотреть список своих заявок, а администратор может смотреть все заявки.

Кроме того, модератору добавляется функция распределять все новые заявки по исполнителям. А исполнители могут просматривать список назначенных заявок и изменять их статус - вплоть до самого завершения.

Итак, добавим контроллер RequestController, который у нас будет управлять системой заявок:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Web;
using System.Web.Mvc;
using HelpDeskTrain.Models;

namespace HelpDeskTrain.Controllers
{
	[Authorize]
    public class RequestController : Controller
    {
        HelpdeskContext db = new HelpdeskContext();
		public ActionResult Index()
        {
			return View();
		}
    }
}

Также используем атрибут [Authorize], чтобы запретить неавторизированный доступ. Метод Index мы потом изменим - он у нас буде выводить все заявки для текущего пользователя. А пока настроим маршрутизацию, чтобы при обращении к приложению по умолчанию шло обращение к этому методу.

Перейдем в проекте в папку App_Start и откроем в ней файл RouteConfig.cs, который содержит определение маршрутов. Сейчас в нем есть класс RouteConfig, который выглядит следующим образом:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Параметр defaults в методе routes.MapRoute указывает на маршрут по умолчанию. В данном случае по умолчанию приложение обращается к методу Index контроллера Home. Теперь изменим название контроллера на Request: defaults: new { controller = "Request", action = "Index", id = UrlParameter.Optional }

Также необходимо, чтобы при удачном логине в методе Login контроллера Account также был предусмотрен редирект на метод Index контроллера RequestController, а не контроллера HomeController.

Теперь по умолчанию при логине пользователь сразу будет попадать на страницу со своим заявками.

Добавление заявки

Теперь добавим первую общую для всех групп функциональность - создание новой заявки. Итак, добавим в контроллер следующий метод Create:

[HttpGet]
public ActionResult Create()
{
    // получаем текущего пользователя
    User user = db.Users.Where(m => m.Login == HttpContext.User.Identity.Name).FirstOrDefault();
    if (user != null)
    {
        // получаем набор кабинетов для департамента, в котором работает пользователь
        var cabs = from cab in db.Activs
                    where cab.DepartmentId == user.DepartmentId
                    select cab;
        ViewBag.Cabs = new SelectList(cabs, "Id", "CabNumber");

        ViewBag.Categories = new SelectList(db.Categories, "Id", "Name");

        return View();
    }
    return RedirectToAction("LogOff", "Account");
}

// Создание новой заявки
[HttpPost]
public ActionResult Create(Request request, HttpPostedFileBase error)
{
    // получаем текущего пользователя
    User user = db.Users.Where(m => m.Login == HttpContext.User.Identity.Name).FirstOrDefault();
    if(user==null)
    {
        return RedirectToAction("LogOff", "Account");
    }
    if (ModelState.IsValid)
    {
        // указываем статус Открыта у заявки
        request.Status = (int)RequestStatus.Open;
        //получаем время открытия
        DateTime current = DateTime.Now;

        //Создаем запись о жизненном цикле заявки
        Lifecycle newLifecycle = new Lifecycle() { Opened = current };
        request.Lifecycle = newLifecycle;

        //Добавляем жизненный цикл заявки
        db.Lifecycles.Add(newLifecycle);

        // указываем пользователя заявки
        request.UserId = user.Id;

        // если получен файл
        if (error != null)
        {
            // Получаем расширение
            string ext = error.FileName.Substring(error.FileName.LastIndexOf('.'));
            // сохраняем файл по определенному пути на сервере
            string path = current.ToString("dd/MM/yyyy H:mm:ss").Replace(":", "_").Replace("/", ".") + ext;
            error.SaveAs(Server.MapPath("~/Files/" + path));
            request.File = path;
        }
        //Добавляем заявку
        db.Requests.Add(request);
        db.SaveChanges();

        return RedirectToAction("Index");
    }
    return View(request);
}

В get-версии метода Create сначала получаем текущего пользователя через объект HttpContext.User.Identity. Если пользователь по какой-то причине не определен, делаем логаут. Если же определен, получаем кабинеты департамента пользователя, а также категории проблем и передаем из в представление через ViewBag.

В post-версии мы получаем два параметра: Request (сам объект заявки) и HttpPostedFileBase (данный объект у нас представляет переданный вместе с заявкой файл с ошибкой, например, какое-нибудь изображение).

В самом методе мы также получаем опять же текущего пользователя и его id устанавливаем у заявки. Устанавливаем ее статус, объект жизненного цикла и сохраняем переданный файл, если он, конечно же, был передан. При этом сохранение идет в папку Files, которая должна быть в проекте в приложения. Для этого мы можем добавить папку Files в наш проект, а при развертывании приложения также не надо забывать, что финальное приложение также должно содержать данную папку. В этой папке будут храниться переданные файлы, и для каждого файла имя будет образовано от времени передачи. И после всех этих этапов заявка попадает в базу данных.

И создадим представление Create, которое будет выглядеть следующим образом:

@model HelpDeskTrain.Models.Request

@{
    ViewBag.Title = "Создать заявку";
}

<h2>Cоздать заявку</h2>

@using (Html.BeginForm("Create", "Request", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Новая заявка</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Priority)
        </div>
        <div class="editor-field">
             @Html.DropDownListFor(model => model.Priority, new[] { new SelectListItem() { Text = "Низкий", Value = "1" }, 
        new SelectListItem() { Text = "Средний", Value = "2" }, new SelectListItem() { Text = "Высокий", Value = "3" }, 
        new SelectListItem() { Text = "Критичный", Value = "4" }})
            @Html.ValidationMessageFor(model => model.Priority)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ActivId)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.ActivId, ViewBag.Cabs as SelectList)
            @Html.ValidationMessageFor(model => model.ActivId)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CategoryId)
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(model => model.CategoryId, ViewBag.Categories as SelectList)
            @Html.ValidationMessageFor(model => model.CategoryId)
        </div>
        
        <div class="editor-label">
            @Html.LabelFor(model => model.File)
        </div>
        <div class="editor-field">
           <input type="file" id="error" name="error" />
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Comment)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Comment)
            @Html.ValidationMessageFor(model => model.Comment)
        </div>

        <p>
            <input type="submit" value="Сохранить заявку" />
        </p>
    </fieldset>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850