Производство
Модуль "Производство"
Версия: 1.0
Дата: 2025-11-25
Статус: Реализован
Содержание
- Общее описание
- Текущая реализация
- Права доступа
- Описание полей
- UI/UX
- Бизнес-логика
- Выявленные проблемы
- Рекомендации
1. Общее описание
1.1 Предназначение модуля
Модуль "Производство" предназначен для управления пользователями производственных площадок (group_id = 4). Это сотрудники, работающие непосредственно на производстве и складах.
Основные функции:
- Создание и редактирование учётных записей работников производства
- Привязка к конкретному складу (
stock_id) - Привязка к месту производства (
manufacture_id) - Назначение индивидуальных прав (политик) доступа
- Авторизация под учётной записью (impersonate)
1.2 Связь с другими модулями
| Модуль | Связь |
|---|---|
| Склады | user.stock_id → работник видит только свой склад |
| Места производства | user.manufacture_id → привязка к производству |
| Заказы | Производственник видит заказы своего производства |
| Политики доступа | Индивидуальные права через user_policies |
1.3 Статистика
| Метрика | Значение |
|---|---|
| Всего производственников | 1 |
| Активных | 1 |
| С Telegram | 0 |
| Со складом | 0 |
| С производством | 0 |
2. Текущая реализация
2.1 Архитектура
┌─────────────────────────────────────────────────────────────────────────────┐
│ МОДУЛЬ "ПРОИЗВОДСТВО" │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ РОУТЫ (routes/web.php) │
│ ├── GET /productions → ProductionController@index → Список │
│ ├── GET /productions/add → ProductionController@create → Создание │
│ └── GET /productions/edit/{id} → ProductionController@show → Редактир. │
│ │
│ КОНТРОЛЛЕР (ProductionController.php) │
│ └── Проверка прав: production_can_view, production_can_add │
│ │
│ LIVEWIRE КОМПОНЕНТЫ │
│ ├── Productions/Listing.php — Таблица пользователей производства │
│ ├── Productions/Add.php — Форма создания │
│ ├── Productions/Edit.php — Форма редактирования с 2 вкладками │
│ └── Productions/Policies.php — Таблица политик (вкладка "Права") │
│ │
│ МОДЕЛЬ │
│ └── User (group_id = 4) — производственники в общей таблице users │
│ │
└─────────────────────────────────────────────────────────────────────────────┘2.2 Структура данных
Производственники хранятся в таблице users с group_id = 4.
Поля производственника в таблице users
| Поле | Тип | Описание |
|---|---|---|
id | bigint | PK |
group_id | int | 4 для производства |
email | string | Email (уникальный) |
password | string | Хэш пароля |
name | string | Имя |
lastname | string | Фамилия |
middlename | string | Отчество |
position | string | Должность |
phone | string | Телефон |
tg_id | string | ID Telegram |
image | string | Аватар |
active | boolean | Активен |
stock_id | FK | Привязка к складу |
manufacture_id | FK | Привязка к производству |
last_auth | datetime | Последняя авторизация |
created_at | timestamp | — |
updated_at | timestamp | — |
2.3 Файлы модуля
app/
├── Http/Controllers/
│ └── ProductionController.php
├── Livewire/Productions/
│ ├── Add.php — Форма создания
│ ├── Edit.php — Форма редактирования (2 вкладки)
│ ├── Listing.php — Таблица списка
│ └── Policies.php — Таблица политик
└── Models/
└── User.php (group_id = 4)
resources/views/templates/productions/
├── table.blade.php
├── add.blade.php
├── edit.blade.php
└── policies.blade.php3. Права доступа
3.1 Политики модуля
| Политика | Описание |
|---|---|
production_can_view | Просмотр списка производственников |
production_can_add | Создание производственника |
production_can_edit | Редактирование данных производственника |
production_can_delete | Удаление производственника |
production_can_edit_policy | Редактирование прав производственника |
3.2 Проверка в контроллере
// ProductionController.php
public function index(Request $request)
{
if (!$user->check_access('production_can_view'))
abort(403);
}
public function show(string $id, Request $request)
{
if (!$user->check_access('production_can_view'))
abort(403);
$manager = User::find($id);
if (!$manager or $manager->group_id !== 4) abort(404); // Проверка group_id
}
public function create(Request $request)
{
if (!$user->check_access('production_can_add'))
abort(403);
}3.3 Матрица доступа по ролям
| Роль | Просмотр | Создание | Редактир. | Удаление | Права |
|---|---|---|---|---|---|
| Администратор | ✅* | ✅* | ✅* | ✅* | ✅* |
| Менеджер | ❌ | ❌ | ❌ | ❌ | ❌ |
| Производство | ❌ | ❌ | ❌ | ❌ | ❌ |
| Дилер | ❌ | ❌ | ❌ | ❌ | ❌ |
*Зависит от индивидуальных политик пользователя
3.4 Особенности: Использование manager_can_ в Listing
⚠️ Внимание! В
Listing.phpиспользуются политикиmanager_can_edit,manager_can_delete,manager_can_authвместоproduction_can_*. Это баг!
// Listing.php:29-30 — ОШИБКА!
$can_edit = ! $this->authUser->check_access('manager_can_edit');
$can_delete = $this->authUser->check_access('manager_can_delete');4. Описание полей
4.1 Форма создания (Add.php)
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
email | TextInput | ✅ | Email (unique) |
password | Password | ✅ | Пароль |
lastname | TextInput | ✅ | Фамилия |
name | TextInput | ✅ | Имя |
middlename | TextInput | ❌ | Отчество |
position | TextInput | ❌ | Должность |
phone | TextInput | ❌ | Телефон (маска +7) |
stock_id | Select | ❌ | Склад |
manufacture_id | Select | ❌ | Производство |
active | Toggle | ✅ | Активен (по умолчанию true) |
image | FileUpload | ❌ | Аватар (1:1, crop) |
При создании автоматически: group_id = 4
4.2 Форма редактирования (Edit.php)
Вкладка "Данные"
| Поле | Тип | Особенности |
|---|---|---|
email | TextInput | Disabled если нет прав, unique(ignoreRecord) |
password | Password | Hidden если нет прав, хэшируется |
lastname | TextInput | — |
name | TextInput | — |
middlename | TextInput | — |
position | TextInput | — |
phone | TextInput | Маска +7(999) 999 99 99 |
stock_id | Select | Выбор склада |
manufacture_id | Select | Выбор производства |
last_auth | TextInput | Только чтение |
active | Toggle | — |
image | FileUpload | Аватар |
Вкладка "Права"
Доступна при наличии production_can_edit_policy.
4.3 Колонки таблицы списка
| Колонка | Описание | Особенности |
|---|---|---|
image | Аватар | ImageColumn |
email | Поиск | |
name | Имя | Поиск |
lastname | Фамилия | Поиск |
phone | Телефон | Поиск |
stock.name | Склад | Поиск, сортировка |
manufacture.name | Производство | Поиск, сортировка |
tg_id | ID Telegram | Поиск |
active | Активен | ToggleColumn |
5. UI/UX
5.1 Список пользователей производства
┌─────────────────────────────────────────────────────────────────────────────┐
│ Пользователи производства [+ Создать] │
├─────────────────────────────────────────────────────────────────────────────┤
│ [Поиск...] [Столбцы ▾] │
├──────┬──────┬────────────────────┬───────┬──────────┬──────────┬───────┬────┤
│ ☐ │ Фото │ Email │ Имя │ Фамилия │ Склад ▾ │Произв.│Акт.│
├──────┼──────┼────────────────────┼───────┼──────────┼──────────┼───────┼────┤
│ ☐ │ [📷] │ worker@example.org │Иван │ Петров │ Вертек │Верхов.│ [●]│
│ ☐ │ [📷] │ master@example.org │Сергей │ Сидоров │ СПБ │Елкино │ [●]│
└──────┴──────┴────────────────────┴───────┴──────────┴──────────┴───────┴────┘
Действия:
✅ [Авторизоваться] — войти под учёткой (impersonate)
✅ [Удалить] — с подтверждением
Особенности:
- Колонки "Склад" и "Производство" — ключевые для этой группы
- Сортировка по складу и производству
- Кнопка "Создать" ведёт на отдельную страницу5.2 Карточка редактирования
┌─────────────────────────────────────────────────────────────────────────────┐
│ [← Назад] Редактирование пользователя производства [Удалить] [Сохранить] │
├─────────────────────────────────────────────────────────────────────────────┤
│ [Данные] [Права] │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ ┌────────────────────────┐ │
│ │ Email [worker@example.org ] │ │ Изображение │ │
│ │ Пароль [•••••••• ] [👁] │ │ ┌────────────────────┐ │ │
│ │ Фамилия [Петров ] │ │ │ [📷 Аватар] │ │ │
│ │ Имя [Иван ] │ │ └────────────────────┘ │ │
│ │ Отчество [Сергеевич ] │ │ │ │
│ │ Должность [Мастер цеха ] │ └────────────────────────┘ │
│ │ │ │
│ │ Телефон [+7(930) 123 45 67 ] │ │
│ │ │ │
│ │ Склад [Вертек ▾] │ ← КЛЮЧЕВОЕ ПОЛЕ │
│ │ │ │
│ │ Производство [Производство Верховье ▾] │ ← КЛЮЧЕВОЕ ПОЛЕ │
│ │ │ │
│ │ Посл. авторизация [ ] │ │
│ │ Активен [●] │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘6. Бизнес-логика
6.1 Роль производственника в системе
Производственник — это работник производственной площадки. Он:
- Привязан к конкретному складу (
stock_id) - Привязан к конкретному месту производства (
manufacture_id) - Видит только свой склад в модуле складов
- Видит только свои заказы по производству
6.2 Ограничение доступа к складу
В модуле "Склады" производственник видит только свой склад:
// Stocks/Listing.php
if ($this->authUser->group_id == 4) { // Производство
if ($this->authUser->stock_id) {
$query->where('id', $this->authUser->stock_id); // Только свой склад
} else {
$query->where('id', 0); // Нет доступа
}
}6.3 Связи модели User для производства
// User.php — отношения
public function stock()
{
return $this->belongsTo(Stock::class);
}
public function manufacture()
{
return $this->belongsTo(Manufacture::class);
}6.4 Проверка смены статусов заказа
В модели Status проверяется право производственника на смену статуса:
// Status.php
case '4': // manufacture (group_id = 4)
$condition = [
'check' => 'two',
'first' => 'production_can', // Право на свой заказ
'second' => 'productions_can', // Общее право
];
break;6.5 Автоматическое создание UserPolicy
При открытии карточки редактирования:
// Edit.php — mount()
$policies = Policy::all();
foreach ($policies as $policy) {
UserPolicy::firstOrCreate(
['user_id' => $this->record->id, 'policy_id' => $policy->id],
['value' => false]
);
}7. Выявленные проблемы
7.1 Критические
| # | Проблема | Файл | Влияние |
|---|---|---|---|
| 1 | Неправильные политики в Listing | Listing.php:29-30, 86-87 | Используется manager_can_* вместо production_can_* |
7.2 Средние
| # | Проблема | Описание | Решение |
|---|---|---|---|
| 2 | Policies рендерит неправильный view | 'livewire.news.listing' вместо правильного | Заменить на 'livewire.base.listing' |
| 3 | Нет tg_id в карточке | В списке есть, в карточке нет | Добавить поле |
| 4 | Разные маски телефона | В Add: +7 (999)..., в Edit: +7(999)... | Унифицировать |
7.3 Низкие
| # | Проблема | Описание |
|---|---|---|
| 5 | Нет экспорта | Нельзя выгрузить список производственников |
| 6 | Нет фильтров по складу/производству | Только поиск |
| 7 | Нет impersonate в Title.php | production_can_auth не проверяется |
8. Рекомендации
8.1 Приоритет: Критический
Исправить политики в Listing.php
// Listing.php:29-30 — было:
$can_edit = ! $this->authUser->check_access('manager_can_edit');
$can_delete = $this->authUser->check_access('manager_can_delete');
// Стало:
$can_edit = ! $this->authUser->check_access('production_can_edit');
$can_delete = $this->authUser->check_access('production_can_delete');// Listing.php:86-87 — было:
$can_delete = $this->authUser->check_access('manager_can_delete');
$can_auth = $this->authUser->check_access('manager_can_auth');
// Стало:
$can_delete = $this->authUser->check_access('production_can_delete');
$can_auth = $this->authUser->check_access('production_can_auth');8.2 Приоритет: Высокий
Исправить view в Policies
// Policies.php:58 — было:
return view('livewire.news.listing');
// Стало:
return view('livewire.base.listing');8.3 Приоритет: Средний
Добавить tg_id в форму редактирования
// Edit.php — в editData()
TextInput::make('tg_id')
->label('ID телеграмма')
->disabled($disableEdit)
->maxLength(255)
->columnSpan(['lg' => 3]),Добавить фильтры по складу и производству
->filters([
SelectFilter::make('stock_id')
->label('Склад')
->options(Stock::all()->pluck('name', 'id')),
SelectFilter::make('manufacture_id')
->label('Производство')
->options(Manufacture::all()->pluck('name', 'id')),
])Приложение: SQL для аналитики
Производственники с привязками
SELECT
u.id,
u.email,
u.name,
u.lastname,
s.name as stock,
m.name as manufacture
FROM users u
LEFT JOIN stocks s ON u.stock_id = s.id
LEFT JOIN manufactures m ON u.manufacture_id = m.id
WHERE u.group_id = 4
ORDER BY s.name, m.name;Производственники без привязки к складу
SELECT id, email, name, lastname
FROM users
WHERE group_id = 4 AND stock_id IS NULL;Производственники без привязки к производству
SELECT id, email, name, lastname
FROM users
WHERE group_id = 4 AND manufacture_id IS NULL;Все политики производственника
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 = :production_user_id
ORDER BY p.category, p.name;Документ подготовлен на основе анализа исходного кода проекта