diff --git a/backend/requests_app/urls_front.py b/backend/requests_app/urls_front.py index c5a84e01..48ab43d0 100644 --- a/backend/requests_app/urls_front.py +++ b/backend/requests_app/urls_front.py @@ -2,6 +2,7 @@ from django.urls import path from .views_front import ( RequestsView, + RequestDetailView, request_comments, request_comment_add, ) @@ -10,6 +11,7 @@ app_name = "requests" urlpatterns = [ path("", RequestsView.as_view(), name="request_list"), + path("/", RequestDetailView.as_view(), name="request_detail"), path("comments//", request_comments, name="request_comments"), path( "comments//add/", diff --git a/backend/requests_app/views_front.py b/backend/requests_app/views_front.py index d5b8f847..e5b41494 100644 --- a/backend/requests_app/views_front.py +++ b/backend/requests_app/views_front.py @@ -274,6 +274,81 @@ class RequestsView(LoginRequiredMixin, TemplateView): return ctx +class RequestDetailView(LoginRequiredMixin, TemplateView): + """ + Детальный просмотр заявления. + + Загружает одно заявление и его комментарии через API. + Может быть использовано как для отдельной страницы, так и для модального окна. + + GET /requests/{pk}/: + - Загружает заявление через GET /api/v1/requests/{pk}/ + - Загружает комментарии через GET /api/v1/requests/{pk}/comments/ + - Проверяет права доступа (делает ошибку если нет прав) + + Контекст: + - request_obj: dict с данными заявления + - comments: list[dict] с комментариями + - can_process: bool - может ли пользователь обрабатывать заявку + - error: str - описание ошибки (если она была) + - error_code: int - HTTP код ошибки + """ + + template_name = "requests_app/request_detail.html" + + def get_context_data(self, pk: int, **kwargs: Any) -> Dict[str, Any]: + """ + Загружает данные заявления и комментарии. + + Args: + pk: ID заявления + + Returns: + Dict с контекстом для шаблона + """ + ctx = super().get_context_data(**kwargs) + request = self.request + api = get_api_client(request) + + # Загружаем основные данные заявления + ok, data, status = _api_unpack(api.get(f"v1/requests/{pk}/")) + + if not ok: + # Обработка ошибок (404, 403 и т.д.) + error_msg = data.get("detail", f"HTTP {status}") + if isinstance(error_msg, list): + error_msg = "; ".join(str(e) for e in error_msg) + + ctx.update({ + "request_obj": None, + "comments": [], + "can_process": _user_can_process_requests(request.user), + "error": error_msg, + "error_code": status, + }) + return ctx + + request_data = data + + # Загружаем комментарии + comments = [] + ok_c, data_c, st_c = _api_unpack(api.get(f"v1/requests/{pk}/comments/")) + if ok_c: + results_c, _, _, _ = _parse_page_payload(data_c) + comments = _format_datetime_fields( + results_c, + fields=("created_at", "updated_at") + ) + + ctx.update({ + "request_obj": _format_datetime_fields([request_data], fields=("created_at", "updated_at", "decided_at"))[0], + "comments": comments, + "can_process": _user_can_process_requests(request.user), + }) + + return ctx + + def request_comments(request: HttpRequest, pk: int) -> JsonResponse: """Прокси: список комментариев (JSON) для заявки. Требует авторизации (используем ту же обёртку клиента, что и основная вью). diff --git a/backend/templates/requests_app/request_detail.html b/backend/templates/requests_app/request_detail.html index 2e7850ba..189b0186 100644 --- a/backend/templates/requests_app/request_detail.html +++ b/backend/templates/requests_app/request_detail.html @@ -8,7 +8,22 @@
- {# — Шапка — #} + {% if error %} + {# — Ошибка при загрузке — #} + + + К списку заявлений + + {% elif request_obj %}

Детали заявления

@@ -150,7 +165,12 @@
- --> + + {% else %} + + {% endif %}