11 KiB
11 KiB
Анализ существующего кода для Detail View
Статус: 📋 Анализ Дата: 26 декабря 2025 г. Задача: feature/requests-detail-view - Этап 1
🔍 Анализ RequestsView
Файл: backend/requests_app/views_front.py
class RequestsView(LoginRequiredMixin, TemplateView):
template_name = 'requests/requests_list.html'
# ... логика загрузки списка заявок
Выводы:
- ✅ Используется TemplateView (можем использовать для RequestDetailView)
- ✅ Требует LoginRequiredMixin
- ✅ Загружает данные через API клиента
- ✅ Использует pagination
Как загружает данные:
client = get_api_client(request)
# Запрос к /api/v1/requests/
response = client.get('/api/v1/requests/', params={...})
🔍 Анализ request_comments() и request_comment_add()
Функции в views_front.py (строки ~277, ~293)
def request_comments(request: HttpRequest, pk: int) -> JsonResponse:
"""Загружает комментарии к заявке"""
# Возвращает JSON с комментариями
def request_comment_add(request: HttpRequest, pk: int) -> JsonResponse:
"""Добавляет комментарий к заявке"""
# POST запрос с текстом комментария
# Возвращает JSON с результатом
Выводы:
- ✅ Используют JsonResponse для AJAX
- ✅ Работают через POST/GET
- ✅ Уже адаптированы для фронтенда
- ⚠️ Нужно будет интегрировать в модальное окно
🔍 Анализ API эндпоинтов
/api/v1/requests/{pk}/ - RequestViewSet
Файл: backend/api/v1/requests/views.py
Методы:
- ✅ GET - получить одно заявление
- ✅ PATCH/PUT - обновить заявление (изменить статус)
- ✅ DELETE - удалить (если есть права)
Структура ответа:
{
"id": 1,
"title": "Название заявки",
"description": "Описание",
"status": "new|processed|approved|rejected",
"employee": {"id": 1, "full_name": "Иван Иванов"},
"recipients": [...],
"cc_users": [...],
"approver": {...},
"departments": [...],
"created_at": "2025-12-26T10:00:00Z",
"updated_at": "2025-12-26T10:00:00Z",
"decided_at": null,
"type": "document|info|order",
// ... другие поля
}
Проверка прав доступа:
- Пользователь видит заявку если:
- Он автор
- Он в списке recipients
- Он в списке cc_users
- Он approver
- Он в числе сотрудников указанных отделов
🔍 Анализ существующих шаблонов
backend/templates/requests/requests_list.html
Структура:
- Header с фильтрами (Мои/Все/Новая)
- Таблица со списком заявок
- Пагинация
- Sidebar с фильтрами (статус, отделы, тип)
Как открываются детали:
- Может быть, есть модальное окно? Нужно проверить
- Или просто кликает по ссылке?
🔍 Анализ модальных окон в проекте
Где уже используются модали:
- В communications (открытие чата)
- В documents (просмотр документа)
- В employees (профиль сотрудника)
- Возможно, в других местах
Как реализованы:
- Bootstrap modals (5.x)
- Открываются через JavaScript
- Загружают контент через AJAX или встроены в HTML
Пример структуры:
<div class="modal fade" id="requestModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Заявление #<span id="requestId"></span></h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Содержимое загружается сюда -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Закрыть</button>
<button type="button" class="btn btn-primary" id="saveBtn">Сохранить</button>
</div>
</div>
</div>
</div>
🔍 Структура JavaScript модулей
Директория: backend/static/js/modules/
Существующие модули:
chatModule.js- работа с чатамиdocumentModule.js- работа с документами- Другие...
Паттерн использования:
// Экспортирование как ES6 модулей
export class RequestDetailManager {
constructor() { }
init() { }
openModal(id) { }
loadData(id) { }
// ...
}
Как подключаются:
<script type="module">
import { RequestDetailManager } from '/static/js/modules/requestDetail.js';
const manager = new RequestDetailManager();
manager.init();
</script>
🔍 Анализ прав доступа
Где проверяются права:
-
В API (RequestViewSet):
- DRF permission classes
- Проверяет право просмотра заявки
- Проверяет право редактирования
-
Во views_front.py:
LoginRequiredMixin- требует аутентификацию- Фильтрует заявки по доступным для пользователя
-
На фронтенде:
- Скрывают кнопки действий если нет прав
- JS проверяет ответы API (403 Forbidden)
Правила доступа к заявке:
- ✅ Просмотр: автор, recipients, cc_users, approver, сотрудники отделов
- ✅ Редактирование статуса: approver, сотрудники с правом обработки
- ✅ Комментирование: все, кто видит заявку
🔍 CSS стили
Фреймворк: Bootstrap 5
Существующие классы для модалей:
.modal,.modal-dialog,.modal-content.modal-header,.modal-body,.modal-footer.btn,.btn-primary,.btn-secondary- Кастомные классы в
requests.css
Нужно создать:
- Стили для модального окна заявки
- Стили для вкладок (может быть, уже есть)
- Стили для комментариев
- Стили для действий (кнопок)
📋 Чек-лист для следующих этапов
Что готово использовать:
- ✅ API эндпоинты работают
- ✅ Функции для комментариев есть
- ✅ Структура views понятна
- ✅ Bootstrap модали используются в проекте
Что нужно создать:
- ❌ RequestDetailView (новый класс)
- ❌ URL маршрут для detail
- ❌ HTML шаблон модального окна
- ❌ JavaScript модуль для логики
- ❌ CSS стили для модали
Потенциальные проблемы:
- ⚠️ CSRF токен при AJAX запросах
- ⚠️ Права доступа нужно проверить
- ⚠️ N+1 проблема при загрузке связанных данных
- ⚠️ Кэширование при массивных запросах
🎯 Рекомендации для реализации
1. RequestDetailView
class RequestDetailView(LoginRequiredMixin, TemplateView):
"""
Отображает детальную страницу заявления.
Может быть как отдельная страница, так и содержимое модали.
"""
template_name = 'requests/request_detail.html'
def get_context_data(self, pk, **kwargs):
context = super().get_context_data(**kwargs)
# Загрузить заявление через API
client = get_api_client(self.request)
response = client.get(f'/api/v1/requests/{pk}/')
if response.ok:
context['request_obj'] = response.json()
else:
# Обработать ошибку (404, 403 и т.д.)
pass
return context
2. JavaScript модуль
export class RequestDetailModal {
constructor(containerId = 'requestModal') {
this.modal = new bootstrap.Modal(document.getElementById(containerId));
this.container = document.getElementById(containerId);
this.init();
}
init() {
// Добавить обработчики событий
// Инициализировать элементы
}
open(requestId) {
this.loadData(requestId)
.then(() => this.modal.show());
}
loadData(requestId) {
// Загрузить данные через API
// Обновить содержимое модали
}
}
3. Интеграция с список заявок
// На странице списка добавить слушатели
document.querySelectorAll('[data-request-id]').forEach(row => {
row.addEventListener('click', (e) => {
const requestId = row.dataset.requestId;
requestDetailModal.open(requestId);
});
});
📚 Полезные ссылки в проекте
- API документация:
/api/v1/ - Существующие views:
backend/requests_app/views_front.py - Существующие templates:
backend/templates/requests/ - JS модули:
backend/static/js/modules/ - CSS:
backend/static/css/
🚀 Готово начинать разработку!
Ключевые файлы для открытия:
backend/requests_app/views_front.py- понять структуруbackend/templates/requests/requests_list.html- понять шаблонbackend/static/js/modules/- посмотреть примеры JSbackend/api/v1/requests/views.py- понять API
Следующий шаг: Начать Этап 2 - создание RequestDetailView