Документация ЛК
Модули

Менеджеры

Модуль "Менеджеры"

Версия: 1.0
Дата: 2025-11-23
Статус: Реализован


Содержание

  1. Общее описание
  2. Текущая реализация
  3. Права доступа
  4. Описание полей
  5. UI/UX
  6. Бизнес-логика
  7. Выявленные проблемы
  8. Рекомендации

1. Общее описание

1.1 Предназначение модуля

Модуль "Менеджеры" предназначен для управления менеджерами дилерских компаний (group_id = 3). Менеджеры — это сотрудники компании, которые курируют дилерские организации и их представителей.

Основные функции:

  • Создание и редактирование учётных записей менеджеров
  • Назначение индивидуальных прав (политик) доступа
  • Просмотр компаний, закреплённых за менеджером
  • Авторизация под учётной записью менеджера (impersonate)

1.2 Связь с другими модулями

МодульСвязь
Дилеры (компании)company.manager_id → менеджер курирует компании
Дилеры (менеджеры)user.manager_id → менеджер курирует дилеров
ЗаказыМенеджер видит заказы своих компаний
Политики доступаИндивидуальные права через user_policies

1.3 Статистика

МетрикаЗначение
Всего менеджеров10
Активных10
С Telegram7
Компаний у менеджеров183

2. Текущая реализация

2.1 Архитектура

┌─────────────────────────────────────────────────────────────────────────────┐
│                          МОДУЛЬ "МЕНЕДЖЕРЫ"                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  РОУТЫ (routes/web.php)                                                      │
│  ├── GET /managers           → ManagerController@index  → Список             │
│  ├── GET /managers/add       → ManagerController@create → Создание           │
│  └── GET /managers/edit/{id} → ManagerController@show   → Редактирование     │
│                                                                              │
│  КОНТРОЛЛЕР (ManagerController.php)                                          │
│  └── Проверка прав: manager_can_view, manager_can_add                        │
│                                                                              │
│  LIVEWIRE КОМПОНЕНТЫ                                                         │
│  ├── Managers/Listing.php  — Таблица менеджеров                             │
│  ├── Managers/Add.php      — Форма создания                                 │
│  ├── Managers/Edit.php     — Форма редактирования с 3 вкладками             │
│  ├── Managers/Policies.php — Таблица политик (вкладка "Права")              │
│  └── Managers/Dealers.php  — Таблица компаний менеджера (вкладка "Дилеры")  │
│                                                                              │
│  МОДЕЛЬ                                                                      │
│  └── User (group_id = 3) — менеджеры в общей таблице users                  │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

2.2 Структура данных

Менеджеры хранятся в таблице users с group_id = 3.

Поля менеджера в таблице users

ПолеТипОписание
idbigintPK
group_idint3 для менеджеров
emailstringEmail (уникальный)
passwordstringХэш пароля
namestringИмя
lastnamestringФамилия
middlenamestringОтчество
positionstringДолжность
phonestringТелефон
tg_idstringID Telegram
imagestringАватар
activebooleanАктивен
last_authdatetimeПоследняя авторизация
created_attimestamp
updated_attimestamp

2.3 Файлы модуля

app/
├── Http/Controllers/
│   └── ManagerController.php
├── Livewire/Managers/
│   ├── Add.php       — Форма создания
│   ├── Edit.php      — Форма редактирования (3 вкладки)
│   ├── Listing.php   — Таблица списка
│   ├── Policies.php  — Таблица политик
│   └── Dealers.php   — Таблица компаний менеджера
└── Models/
    └── User.php (group_id = 3)

resources/views/templates/managers/
├── table.blade.php
├── add.blade.php
├── edit.blade.php
├── policies.blade.php
└── dealers.blade.php

3. Права доступа

3.1 Политики модуля

ПолитикаОписание
manager_can_viewПросмотр списка менеджеров
manager_can_addСоздание менеджера
manager_can_editРедактирование данных менеджера
manager_can_deleteУдаление менеджера
manager_can_authАвторизация под менеджером (impersonate)
manager_can_edit_policyРедактирование прав менеджера
manager_can_view_dealersПросмотр вкладки "Дилеры" с компаниями

3.2 Проверка в контроллере

// ManagerController.php
public function index(Request $request)
{
    if (!$user->check_access('manager_can_view'))
        abort(403);
}

public function show(string $id, Request $request)
{
    if (!$user->check_access('manager_can_view'))
        abort(403);
    
    $manager = User::find($id);
    if (!$manager or $manager->group_id !== 3) abort(404);  // Проверка group_id
}

public function create(Request $request)
{
    if (!$user->check_access('manager_can_add'))
        abort(403);
}

3.3 Матрица доступа по ролям

РольПросмотрСозданиеРедактир.УдалениеImpersonateПраваДилеры
Администратор✅*✅*✅*✅*✅*✅*✅*
Менеджер
Производство
Дилер

*Зависит от индивидуальных политик пользователя


4. Описание полей

4.1 Форма создания (Add.php)

ПолеТипОбязательноеОписание
emailTextInputEmail (unique)
passwordPasswordПароль
lastnameTextInputФамилия
nameTextInputИмя
middlenameTextInputОтчество
positionTextInputДолжность
phoneTextInputТелефон (маска +7)
activeToggleАктивен (по умолчанию true)
imageFileUploadАватар (1:1, crop)

При создании автоматически: group_id = 3

4.2 Форма редактирования (Edit.php)

Вкладка "Данные"

ПолеТипОсобенности
emailTextInputDisabled если нет прав, unique(ignoreRecord)
passwordPasswordHidden если нет прав, хэшируется
lastnameTextInput
nameTextInput
middlenameTextInput
positionTextInput
tg_idTextInputID Telegram
phoneTextInputМаска +7(999) 999 99 99
last_authTextInputТолько чтение
activeToggle
imageFileUploadАватар

Вкладка "Права"

Доступна при наличии manager_can_edit_policy.

Содержит таблицу политик (Policies.php):

  • Группировка по категориям
  • ToggleColumn для включения/выключения
  • Фильтр по категориям

Вкладка "Дилеры"

Доступна при наличии manager_can_view_dealers.

Содержит таблицу компаний менеджера (Dealers.php):

  • Организация, договор, телефон, email, скидка
  • Клик ведёт на карточку компании

4.3 Колонки таблицы списка

КолонкаОписаниеОсобенности
imageАватарImageColumn
emailEmailПоиск
nameИмяПоиск
lastnameФамилияПоиск
phoneТелефонПоиск
tg_idID TelegramПоиск
activeАктивенToggleColumn

5. UI/UX

5.1 Список менеджеров

┌─────────────────────────────────────────────────────────────────────────────┐
│ Менеджеры                                                   [+ Создать]     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                    [Поиск...] [Столбцы ▾]   │
├──────┬──────┬────────────────────────┬─────────┬──────────┬──────────┬──────┤
│ ☐    │ Фото │ Email                  │ Имя     │ Фамилия  │ Телефон  │Актив.│
├──────┼──────┼────────────────────────┼─────────┼──────────┼──────────┼──────┤
│ ☐    │ [📷] │ slavyana@wwtp.ru       │ Славяна │ Маркина  │ +7(930)..│ [●]  │
│ ☐    │ [📷] │ v.dubrovin@trade-h...  │ Валерий │ Дубровин │ +7(930)..│ [●]  │
│ ☐    │ [📷] │ ka@trade-house.ru      │ Андрей  │ Кулик    │ +7(930)..│ [●]  │
└──────┴──────┴────────────────────────┴─────────┴──────────┴──────────┴──────┘

Действия:
✅ [Авторизоваться] — войти под учёткой (impersonate)
✅ [Удалить] — с подтверждением

Особенности:
- Кнопка "Создать" ведёт на отдельную страницу
- Клик по строке → карточка редактирования
- Массовое удаление

5.2 Карточка редактирования (3 вкладки)

┌─────────────────────────────────────────────────────────────────────────────┐
│ [← Назад]  Редактирование менеджера             [Удалить]     [Сохранить]   │
├─────────────────────────────────────────────────────────────────────────────┤
│  [Данные]  [Права]  [Дилеры]                                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│ ┌─────────────────────────────────────────────┐  ┌────────────────────────┐ │
│ │ Email        [slavyana@wwtp.ru          ]   │  │ Изображение            │ │
│ │                                             │  │ ┌────────────────────┐ │ │
│ │ Пароль       [••••••••              ] [👁]  │  │ │                    │ │ │
│ │                                             │  │ │   [📷 Аватар]      │ │ │
│ │ Фамилия      [Маркина                   ]   │  │ │                    │ │ │
│ │ Имя          [Славяна                   ]   │  │ └────────────────────┘ │ │
│ │ Отчество     [                          ]   │  │                        │ │
│ │ Должность    [                          ]   │  └────────────────────────┘ │
│ │ ID телеграмма [8214776166              ]   │                             │
│ │ Телефон      [+7(930) 035 11 06        ]   │                             │
│ │ Посл. авторизация  [                   ]   │                             │
│ │ Активен           [●]                      │                             │
│ └─────────────────────────────────────────────┘                             │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

5.3 Вкладка "Дилеры"

┌─────────────────────────────────────────────────────────────────────────────┐
│  [Данные]  [Права]  [Дилеры]                                                │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                    [Поиск...]               │
├────────────────────────┬────────────────┬──────────┬──────────┬─────────────┤
│ Компания               │ Договор        │ Телефон  │ Email    │ Скидка      │
├────────────────────────┼────────────────┼──────────┼──────────┼─────────────┤
│ ООО "ЭКОРУСЬ"          │ 2025-001       │ +7(495)..│ info@... │ 15%         │
│ ООО "ЯРТОРГ"           │ 2025-002       │ +7(4852).│ sales@.. │ 10%         │
│ ИП Иванов И.И.         │ 2025-003       │ +7(999)..│ ivan@... │ 5%          │
└────────────────────────┴────────────────┴──────────┴──────────┴─────────────┘
│ Показано с 1 по 10 из 25              [10][50][100][Все]                    │
└─────────────────────────────────────────────────────────────────────────────┘

Особенности:
- Показывает только компании, где manager_id = текущий менеджер
- Клик по строке → карточка компании (company-edit)
- Только просмотр, без редактирования

6. Бизнес-логика

6.1 Роль менеджера в системе

Менеджер — это куратор дилерских компаний. Он может:

  1. Видеть и редактировать свои компании (при наличии company_manager_can_*)
  2. Видеть и редактировать дилеров своих компаний (при наличии dealer_manager_can_*)
  3. Видеть заказы своих компаний

6.2 Связь с компаниями

Company.manager_id → User.id (group_id = 3)

Компонент Dealers.php показывает компании, где manager_id = ID менеджера:

// Dealers.php
->query(Company::query()
    ->with('manager')
    ->where('manager_id', $this->record->id))

6.3 Политики для менеджера (manager_can_ vs manager_can)

В системе есть два типа политик:

ПолитикаКто используетОписание
manager_can_*АдминистраторыУправление самими менеджерами
*_manager_can_*МенеджерыПрава менеджера на сущности

Примеры:

  • manager_can_view — админ видит список менеджеров
  • company_manager_can_view — менеджер видит свои компании
  • dealer_manager_can_edit — менеджер редактирует дилеров своих компаний

6.4 Автоматическое создание UserPolicy

При открытии карточки редактирования:

// Edit.php — mount()
$policies = Policy::all();
foreach ($policies as $policy) {
    UserPolicy::firstOrCreate(
        ['user_id' => $this->record->id, 'policy_id' => $policy->id],
        ['value' => false]
    );
}

6.5 Хэширование пароля

TextInput::make('password')
    ->dehydrateStateUsing(fn ($state) => $state ? Hash::make($state) : null)
    ->dehydrated(fn ($state) => filled($state))  // Только если заполнен

6.6 Проверка group_id в контроллере

// ManagerController.php — show()
$manager = User::find($id);
if (!$manager or $manager->group_id !== 3) abort(404);

Защита от просмотра пользователей других групп.


7. Выявленные проблемы

7.1 Критические

#ПроблемаФайлВлияние
Критических проблем не обнаружено

7.2 Средние

#ПроблемаОписаниеРешение
1Инверсия логики $can_edit$can_edit = !check_access() в Listing.phpПереименовать в $disableEdit
2Policies рендерит неправильный view'livewire.news.listing' вместо правильногоЗаменить на 'livewire.base.listing'
3Dealers рендерит неправильный view'livewire.news.listing' вместо правильногоЗаменить на 'livewire.base.listing'
4Разные маски телефонаВ Add: +7 (999)..., в Edit: +7(999)...Унифицировать

7.3 Низкие

#ПроблемаОписание
5Нет экспортаНельзя выгрузить список менеджеров
6Нет истории изменений правНе видно кто и когда менял политики
7Нет фильтровНапример, фильтр по количеству компаний

8. Рекомендации

8.1 Приоритет: Высокий

Исправить view в Policies и Dealers

// Policies.php:58 — было:
return view('livewire.news.listing');

// Стало:
return view('livewire.base.listing');
// Dealers.php:59 — было:
return view('livewire.news.listing');

// Стало:
return view('livewire.base.listing');

8.2 Приоритет: Средний

Исправить именование переменной

// Listing.php:28 — было:
$can_edit = !$this->authUser->check_access('manager_can_edit');

// Стало:
$disableEdit = !$this->authUser->check_access('manager_can_edit');

Унифицировать маску телефона

// Использовать везде:
->mask('+7(999) 999 99 99')

8.3 Приоритет: Низкий

Добавить статистику компаний в таблицу

Tables\Columns\TextColumn::make('companies_count')
    ->label('Компаний')
    ->counts('companies')
    ->sortable(),

Приложение: SQL для аналитики

Менеджеры с количеством компаний

SELECT 
    u.id,
    u.email,
    u.name,
    u.lastname,
    COUNT(c.id) as companies_count
FROM users u
LEFT JOIN companies c ON u.id = c.manager_id
WHERE u.group_id = 3
GROUP BY u.id, u.email, u.name, u.lastname
ORDER BY companies_count DESC;

Менеджеры без компаний

SELECT id, email, name, lastname
FROM users
WHERE group_id = 3
AND id NOT IN (SELECT DISTINCT manager_id FROM companies WHERE manager_id IS NOT NULL);

Статистика заказов по менеджерам

SELECT 
    u.name as manager,
    COUNT(o.id) as orders_count,
    SUM(o.cost) as total_cost
FROM users u
JOIN companies c ON u.id = c.manager_id
JOIN orders o ON c.id = o.company_id
WHERE u.group_id = 3
GROUP BY u.id, u.name
ORDER BY orders_count DESC;

Все политики менеджера

SELECT 
    p.key,
    p.name,
    p.category,
    up.value
FROM user_policies up
JOIN policies p ON up.policy_id = p.id
WHERE up.user_id = :manager_id
ORDER BY p.category, p.name;

Документ подготовлен на основе анализа исходного кода проекта

On this page

Модуль "Менеджеры"Содержание1. Общее описание1.1 Предназначение модуля1.2 Связь с другими модулями1.3 Статистика2. Текущая реализация2.1 Архитектура2.2 Структура данныхПоля менеджера в таблице users2.3 Файлы модуля3. Права доступа3.1 Политики модуля3.2 Проверка в контроллере3.3 Матрица доступа по ролям4. Описание полей4.1 Форма создания (Add.php)4.2 Форма редактирования (Edit.php)Вкладка "Данные"Вкладка "Права"Вкладка "Дилеры"4.3 Колонки таблицы списка5. UI/UX5.1 Список менеджеров5.2 Карточка редактирования (3 вкладки)5.3 Вкладка "Дилеры"6. Бизнес-логика6.1 Роль менеджера в системе6.2 Связь с компаниями6.3 Политики для менеджера (manager_can_ vs manager_can)6.4 Автоматическое создание UserPolicy6.5 Хэширование пароля6.6 Проверка group_id в контроллере7. Выявленные проблемы7.1 Критические7.2 Средние7.3 Низкие8. Рекомендации8.1 Приоритет: ВысокийИсправить view в Policies и Dealers8.2 Приоритет: СреднийИсправить именование переменнойУнифицировать маску телефона8.3 Приоритет: НизкийДобавить статистику компаний в таблицуПриложение: SQL для аналитикиМенеджеры с количеством компанийМенеджеры без компанийСтатистика заказов по менеджерамВсе политики менеджера