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

Характеристики

Модуль "Характеристики"

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


Содержание

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

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

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

Модуль "Характеристики" предназначен для управления справочником характеристик товаров. Это базовый справочник, который определяет какие свойства можно присваивать товарам (вес, размер, производительность и т.д.).

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

  • Создание и редактирование характеристик
  • Указание единиц измерения
  • Изменение порядка отображения (drag & drop)
  • Привязка к товарам с указанием значений

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

МодульСвязь
Товарыproperty_product — значения характеристик для товаров
КаталогХарактеристики отображаются в карточке товара
ЗаказыХарактеристики товаров видны в составе заказа

1.3 Статистика

МетрикаЗначение
Всего характеристик4
Связей с товарами84

1.4 Список характеристик

IDНазваниеЕдиницы измерения
1Человек
2Производительностьм3/сутки
3Размеры
4Вескг.

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

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

┌─────────────────────────────────────────────────────────────────────────────┐
│                        МОДУЛЬ "ХАРАКТЕРИСТИКИ"                               │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  РОУТЫ (routes/web.php)                                                      │
│  └── GET /properties → PropertyController@index → Список                     │
│                                                                              │
│  КОНТРОЛЛЕР (PropertyController.php)                                         │
│  └── БЕЗ ПРОВЕРКИ ПРАВ! Доступен всем авторизованным                        │
│                                                                              │
│  LIVEWIRE КОМПОНЕНТЫ                                                         │
│  ├── Property/Listing.php — Таблица с inline-редактированием                │
│  └── Property/Control.php — Модальное создание                              │
│                                                                              │
│  МОДЕЛИ                                                                      │
│  ├── Property        — Характеристика                                       │
│  └── PropertyProduct — Pivot: значение характеристики для товара            │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

2.2 Структура БД

Таблица properties

ПолеТипОписание
idbigintPK
indexintПорядок сортировки
namestringНазвание характеристики
unitsstringЕдиницы измерения (nullable)
created_attimestamp
updated_attimestamp

Таблица property_product (pivot)

ПолеТипОписание
idbigintPK
product_idFKТовар
property_idFKХарактеристика
valuestringЗначение характеристики

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

app/
├── Http/Controllers/
│   └── PropertyController.php
├── Livewire/Property/
│   ├── Control.php  — Модальное создание + редактирование
│   └── Listing.php  — Таблица с inline-редактированием
└── Models/
    ├── Property.php
    └── PropertyProduct.php

database/migrations/
├── 2024_03_21_101832_create_properties_table.php
└── 2024_03_21_154118_create_property_products_table.php

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

3.1 Контроллер БЕЗ проверки прав

// PropertyController.php — НЕТ ПРОВЕРКИ!
public function index()
{
    return view('templates.property.table');
}

⚠️ Внимание! Модуль доступен всем авторизованным пользователям. Нет проверки прав доступа в контроллере.

3.2 Политики в Livewire

В Listing.php проверяются права:

$disableEdit = $this->authUser->check_access('property_can_edit');
$canDelete = $this->authUser->check_access('property_can_delete');

// В getActions()
$canDelete = ($this->authUser->check_access('property_can_delete') 
    or $this->authUser->check_access('property_manager_can_delete'));

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

ПолитикаОписание
property_can_editРедактирование характеристик
property_can_deleteУдаление характеристик
property_manager_can_deleteУдаление для менеджеров

3.4 Матрица доступа

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

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


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

4.1 Модальное создание (Control.php)

ПолеТипОбязательноеОписание
nameTextInputНазвание характеристики
unitsTextInputЕдиницы измерения

4.2 Inline-редактирование (Listing.php)

ПолеТипОписание
nameTextInputНазвание
unitsTextInputЕдиницы измерения

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

КолонкаОписаниеОсобенности
nameНазваниеПоиск, сортировка
unitsЕдиницы измеренияПоиск, сортировка

5. UI/UX

5.1 Список характеристик

┌─────────────────────────────────────────────────────────────────────────────┐
│ Характеристики                                              [+ Создать]     │
├─────────────────────────────────────────────────────────────────────────────┤
│ [↕]                                            [Поиск...] [Столбцы ▾]       │
├────────────────────────────────┬──────────────────────┬─────────────────────┤
│ Название ▾                     │ Единицы измерения ▾  │                     │
├────────────────────────────────┼──────────────────────┼─────────────────────┤
│ Человек                        │                      │ [Изменить][Удалить] │
│ Производительность             │ м3/сутки             │ [Изменить][Удалить] │
│ Размеры                        │                      │ [Изменить][Удалить] │
│ Вес                            │ кг.                  │ [Изменить][Удалить] │
└────────────────────────────────┴──────────────────────┴─────────────────────┘

Особенности:
✅ Drag & Drop для изменения порядка (reorderable)
✅ Кнопка "Изменить порядок" для активации режима
✅ Модальное создание (без перехода на другую страницу)
✅ Inline-редактирование в модальном окне
✅ Сортировка по колонкам

5.2 Модальное создание

┌─────────────────────────────────────────────────────────────────────────────┐
│                          Создать характеристику                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│   Название*                                                                 │
│   [                                                                     ]   │
│                                                                              │
│   Единицы измерения                                                         │
│   [                                                                     ]   │
│                                                                              │
│                                               [Отмена]    [Создать]         │
└─────────────────────────────────────────────────────────────────────────────┘

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

6.1 Связь с товарами

Характеристики связаны с товарами через pivot-таблицу property_product:

// Product.php
public function propertiesItems()
{
    return $this->belongsToMany(Property::class, 'property_product', 'product_id', 'property_id')
        ->withPivot(['value']);
}

public function productProperties()
{
    return $this->hasMany(PropertyProduct::class);
}

6.2 Присвоение характеристик товару

В карточке товара (Product/Control.php) есть Repeater для характеристик:

Repeater::make('productProperties')
    ->relationship()
    ->schema([
        Hidden::make('product_id')->default($recordID),
        Select::make('property_id')
            ->options(Property::all()->pluck('name', 'id')),
        TextInput::make('value')->maxLength(255)->required(),
    ])

6.3 Пример данных

Товар: "Септик Топас 5"
├── Производительность: 1 м3/сутки
├── Вес: 230 кг
├── Человек: 5
└── Размеры: 1100x1200x2500 мм

6.4 Порядок сортировки

Характеристики имеют поле index для сортировки:

->reorderable('index')
->defaultSort('index', 'asc')

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

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

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

7.2 Средние

#ПроблемаОписаниеРешение
1Нет проверки прав в контроллереURL доступен всем авторизованнымДобавить проверку property_can_view
2Неиспользуемая переменная$disableEdit не используетсяУбрать или использовать
3Нет защиты от удаления используемыхМожно удалить характеристику, которая привязана к товарамДобавить проверку

7.3 Низкие

#ПроблемаОписание
4Control.php: redirect в каталогПосле удаления идёт redirect в catalog, а не properties
5Нет экспортаНельзя выгрузить список характеристик
6Нет подсчёта использованийНе видно сколько товаров используют характеристику

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

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

Добавить проверку прав в контроллер

// PropertyController.php — было:
public function index()
{
    return view('templates.property.table');
}

// Стало:
public function index(Request $request)
{
    $user = $request->user();
    if (!$user or !$user->check_access('property_can_view'))
        abort(403);
    return view('templates.property.table');
}

Добавить защиту от удаления используемых

// Listing.php — в getActions()
Action::make('delete')
    ->hidden(fn (Property $record) => PropertyProduct::where('property_id', $record->id)->exists())
    ->requiresConfirmation()
    ->action(fn (Property $record) => $record->delete())

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

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

Tables\Columns\TextColumn::make('products_count')
    ->label('Товаров')
    ->getStateUsing(fn ($record) => PropertyProduct::where('property_id', $record->id)->count())
    ->sortable(),

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

Исправить redirect в Control.php

// Control.php:106-110 — было:
if ($this->parentId) {
    redirect()->route('category', $this->parentId);
} else {
    redirect()->route('catalog');
}

// Стало:
redirect()->route('properties');

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

Характеристики с количеством товаров

SELECT 
    p.id,
    p.name,
    p.units,
    COUNT(pp.id) as products_count
FROM properties p
LEFT JOIN property_product pp ON p.id = pp.property_id
GROUP BY p.id, p.name, p.units
ORDER BY p.index;

Неиспользуемые характеристики

SELECT id, name, units
FROM properties
WHERE id NOT IN (SELECT DISTINCT property_id FROM property_product);

Значения характеристик для товара

SELECT 
    pr.name as product,
    p.name as property,
    p.units,
    pp.value
FROM property_product pp
JOIN products pr ON pp.product_id = pr.id
JOIN properties p ON pp.property_id = p.id
WHERE pr.id = :product_id
ORDER BY p.index;

Товары с определённой характеристикой

SELECT 
    pr.id,
    pr.name,
    pp.value
FROM products pr
JOIN property_product pp ON pr.id = pp.product_id
WHERE pp.property_id = :property_id
ORDER BY pr.name;

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

On this page

Модуль "Характеристики"Содержание1. Общее описание1.1 Предназначение модуля1.2 Связь с другими модулями1.3 Статистика1.4 Список характеристик2. Текущая реализация2.1 Архитектура2.2 Структура БДТаблица propertiesТаблица property_product (pivot)2.3 Файлы модуля3. Права доступа3.1 Контроллер БЕЗ проверки прав3.2 Политики в Livewire3.3 Политики модуля3.4 Матрица доступа4. Описание полей4.1 Модальное создание (Control.php)4.2 Inline-редактирование (Listing.php)4.3 Колонки таблицы5. UI/UX5.1 Список характеристик5.2 Модальное создание6. Бизнес-логика6.1 Связь с товарами6.2 Присвоение характеристик товару6.3 Пример данных6.4 Порядок сортировки7. Выявленные проблемы7.1 Критические7.2 Средние7.3 Низкие8. Рекомендации8.1 Приоритет: ВысокийДобавить проверку прав в контроллерДобавить защиту от удаления используемых8.2 Приоритет: СреднийДобавить колонку с количеством использований8.3 Приоритет: НизкийИсправить redirect в Control.phpПриложение: SQL для аналитикиХарактеристики с количеством товаровНеиспользуемые характеристикиЗначения характеристик для товараТовары с определённой характеристикой