lsnull
Постоялец
- Регистрация
- 18 Сен 2013
- Сообщения
- 388
- Реакции
- 132
- Автор темы
- #1
Всем привет.
Пишу CMS Каталога товаров - объявлений (CMS Catalog) + Корзина товаров, сделки, статусы товара, личная переписка между продавцом и покупателем (в заказе) + Админка и разный под функционал для заказов (формирование заказа), добавления в корзину, отслеживание статуса, продажи, покупки, баланс, управление товарами, продление срока публикаций товара и так далее.
Пощупать можно по адресу Для просмотра ссылки Войдиили Зарегистрируйся
Кого заинтересовал, пишите комменты.
Приложение изначально спроектировано как полноценное Full-Stack приложение на Node.js (Express + React + Vite).
Вот как устроена эта архитектура:

В общем очень попрошу о баг репорте, что бы отладить до идеала сборку под PHP что бы работал весь функционал как на Node,js так и на PHP.Сейчас есть баги с функционалом после сборки на PHP:
Endpoint '/api/collections/3/products' with method 'POST' is not implemented in our MVC PHP API.
Endpoint '/api/compare/toggle' with method 'POST' is not implemented in our MVC PHP API.
Часть уже пофиксил, расширил api для сборки
исправил проблему с удалением связанных данных и очистил зависшие избранные товары!
Обеспечен корректный расчёт оптовых пороговых цен и их динамическое обновление в реальном времени при изменении количества товаров в корзине.
Выполненные работы:
Реализована функциональность «Черновик товара» с соблюдением принципа единственной ответственности (SRP) и стандартов работы с базой данных.
1. Эволюция схемы базы данных
В server.ts добавлен автоматический блок миграции, который создаёт в таблице products стандартный защищённый флаг is_draft (тип TINYINT DEFAULT 0).
2. Унифицированная логика контроллера на бэкенде
В модальном окне редактирования товара (ProductFormModal) в разделе «Расширенные атрибуты» добавлен высококонтрастный блок управления статусом публикации и черновиком. Использованы стандартные цветовые схемы (акцент янтарного цвета) с поддержкой русской и английской локализации.
Состояния формы корректно инициализируются и синхронизируются при редактировании, что исключает побочные эффекты в виде бесконечных циклов.
4. Списки товаров и управление жизненным циклом
Внедрение системы управления пользователями и блокировок (User Management & Banning) в панели администратора (каталог RBAC), обеспечив полную совместимость как с локальным сервером разработки на Node.js, так и с виртуальным хостингом на PHP:
Визуальное оформление и дизайн интерфейса
Исправил поведение форм авторизации и регистрации на сайте, чтобы они были доступны только гостям и неавторизованным пользователям.
Реализовал как пагинацию, так и ленивую загрузку (бесконечный скролл / кнопку «Загрузить ещё») для списка товаров, строго следуя методологии Feature-Sliced Design (FSD)
Архитектура и реализованные функции:
Уровень Shared UI (shared/ui) :
Установил и настроил ESLint для проекта с использованием самой современной и производительной конфигурации Flat Config (v9)
Пишу CMS Каталога товаров - объявлений (CMS Catalog) + Корзина товаров, сделки, статусы товара, личная переписка между продавцом и покупателем (в заказе) + Админка и разный под функционал для заказов (формирование заказа), добавления в корзину, отслеживание статуса, продажи, покупки, баланс, управление товарами, продление срока публикаций товара и так далее.
Пощупать можно по адресу Для просмотра ссылки Войди
Кого заинтересовал, пишите комменты.
Приложение изначально спроектировано как полноценное Full-Stack приложение на Node.js (Express + React + Vite).
Вот как устроена эта архитектура:
- Режим Node.js (Основной) Когда приложение запускается на сервере Node.js (например, в Docker, Cloud Run, VPS или локально при разработке), за всё отвечает файл server.ts. Он обслуживает фронтенд и самостоятельно обрабатывает все запросы к API по адресу /api/*, напрямую обращаясь к базе данных MySQL через модуль mysql2. В этом режиме PHP вообще не требуется и никак не задействуется.
- Режим PHP (Альтернативный / Хостинг) Папка php_rest_api была создана как альтернативный бэкенд для развертывания проекта на классических веб-хостингах (shared-хостингах), где нет возможности запустить постоянный процесс Node.js, но есть поддержка PHP и MySQL.
- Если это локальная среда разработки или облачный контейнер (Node.js), запросы идут напрямую на бэкенд Express (/api/*).
- Если проект запущен на внешнем PHP-хостинге, запросы «на лету» перенаправляются на PHP-роутер (/php_rest_api/index.php/api/*).

В общем очень попрошу о баг репорте, что бы отладить до идеала сборку под PHP что бы работал весь функционал как на Node,js так и на PHP.Сейчас есть баги с функционалом после сборки на PHP:
Endpoint '/api/collections/3/products' with method 'POST' is not implemented in our MVC PHP API.
Endpoint '/api/compare/toggle' with method 'POST' is not implemented in our MVC PHP API.
1. Исправление Избранного и Сравнения товаров (Wishlist & Comparisons)
- Причина бага: В методе /api/db-state при получении состояния базы данных возвращались полные строки товаров для избранного и сравнения, в то время как фронтенд ожидал сырые пары отношений { user_id, product_id } из связующих таблиц. Из-за отсутствия этих полей фильтрация на клиенте data.favorites.filter((f) => f.user_id === userKey) всегда возвращала пустой массив. Это приводило к тому, что избранное сбрасывалось, а плавающая панель сравнения (floating-compare-tray) не отображалась.
- Решение:
- В модели /public/php_rest_api/models/Product.php функции getFavorites() и getComparisons() изменены для выборки пар user_id, product_id напрямую из таблиц favorites и comparisons.
- В контроллере /public/php_rest_api/controllers/ProductController.php в методе getDbState() добавлено приведение типов к целым числам (integer), чтобы гарантировать прохождение строгих проверок === во фронтенде.
- Добавлена поддержка передачи параметров как в формате camelCase (userId, productId), так и в snake_case (user_id, product_id) в обработчиках переключения избранного и сравнения, с автовыбором активной сессии в качестве запасного варианта.
2. Сохранение Основных характеристик (Custom Values / Characteristics)
- Причина бага: При создании или редактировании товара фронтенд отправляет AJAX-запрос на специальный эндпоинт POST /api/products/:id/custom-values для сохранения структурированных динамических характеристик. Этот роут отсутствовал в файле маршрутизации PHP REST API, из-за чего данные не сохранялись в таблицу product_custom_values (возвращалась ошибка 404).
- Решение:
- В файле маршрутизатора /public/php_rest_api/index.php зарегистрирован роут POST products/:id/custom-values.
- В контроллере /public/php_rest_api/controllers/ProductController.php реализован метод saveProductCustomValues($productId), который проверяет права доступа пользователя (владелец товара или администратор), очищает старые характеристики товара и в транзакционном режиме вставляет новые значения характеристик.
Часть уже пофиксил, расширил api для сборки
исправил проблему с удалением связанных данных и очистил зависшие избранные товары!
Что было еще сделано:
- Каскадное удаление при удалении товара:
- В обработчик удаления товара (DELETE /api/products/:id в /server/routes/products.ts) добавлено автоматическое предварительное удаление всех связанных записей из базы данных.
- Теперь при удалении товара автоматически стираются:
- Избранное (favorites)
- Сравнения (comparisons)
- Отзывы и комментарии (reviews)
- Товары в коллекциях (collection_products)
- Дополнительные характеристики (значения кастомных полей) (product_custom_values)
- История изменения цен (product_price_history)
- История просмотров (viewing_history)
- Уведомления, связанные с товаром (notifications)
- Загруженные изображения товара (физическая папка с файлами)
- Очистка существующих «битых» связей на старте сервера:
- В /server.ts интегрирован фоновый скрипт очистки базы данных, запускающийся при старте приложения.
- Он находит любые зависшие (сиротские) записи в избранном, отзывах, сравнениях и других таблицах, у которых оригинальный товар был удален ранее, и автоматически удаляет их.
- Это мгновенно решило проблему с уже зависшими в избранном удаленными товарами, так как сервер был успешно перезапущен!
- Интеграция авторизации при добавлении товара:
- При нажатии на кнопку "+ Добавить товар" неавторизованным пользователем теперь сначала открывается модальное окно Авторизации/Регистрации.
- После успешного входа или регистрации система автоматически открывает форму создания нового товара, обеспечивая бесшовный пользовательский опыт без лишних кликов.
- Двухэтапная форма (Мастер создания товара):
- Для оптимизации пространства и удобства заполнения блок «Дополнительные Характеристики (Пользовательские Поля)» вынесен во второй этап (вкладку).
- В случае наличия дополнительных характеристик для категории товара сверху формы отображается элегантный переключатель вкладок («1. Основные параметры» и «2. Дополнительные характеристики»).
- Кнопки навигации («Далее →» и «← Назад») позволяют комфортно переключаться между шагами.
- Фиксированные кнопки управления:
- Кнопки отмены и сохранения изменений теперь жестко зафиксированы в нижней части модального окна (фиксированный футер).
- Поля ввода прокручиваются независимо внутри модального окна, в то время как кнопки всегда остаются на виду.
- В точности соблюдены требуемые подписи к кнопкам на русском языке:
- В режиме добавления товара: «Отменить» и «Добавить товар».
- В режиме редактирования товара: «Отмена» и «Сохранить изменения».
1. Унифицированная основная логика ценообразования
- Доминирование основной цены:
Изменены правила расчёта и отображения цен. Теперь product.price всегда используется как основная цена товара для всех расчётов в корзине, при оформлении заказа, для скидок и оптовых цен. - Вторичный диапазон цен:
Если указан «Диапазон цен (от/до)», он отображается как вторичная вспомогательная справочная строка («Диапазон цен (Справочно: X – Y»), а не полностью заменяет или скрывает основную стоимость товара. Эти изменения внедрены в:- Карточках товаров в каталоге (CatalogView.tsx);
- Странице детального просмотра (ProductDetailsView.tsx);
- Модальном окне быстрого просмотра товара (ProductDetailModal.tsx).
2. Многоуровневое (трёхступенчатое) оптовое ценообразование
- Интеграция с базой данных и сохраняемость:
Расширена схема БД пользовательскими столбцами для второго уровня (wholesale_price_2, wholesale_threshold_2) и третьего уровня (wholesale_price_3, wholesale_threshold_3).
Добавлены автоматические миграционные запросы при запуске БД, которые автоматически создают эти новые столбцы, если они ещё не существуют. - Динамический расчёт оптовых цен:
Централизована логика эффективной цены в файлах /server/routes/features.ts и /server/routes/wallet.ts.
Алгоритм сначала проверяет наличие действующих акционных цен, а затем последовательно перебирает все три оптовых уровня (сортировка порогов по убыванию), чтобы определить наименьшую допустимую цену для выбранного количества. - Формы создания и редактирования товаров:
Обновлён ProductFormModal.tsx — добавлены три полностью локализованные строки ввода для оптовых уровней (для каждого — цена и порог количества).
Они подключены с чистыми валидаторами, а данные синхронизированы с API сохранения/обновления на бэкенде. - Современная сетка карточек уровней:
Одиночный блок с ценой заменён на элегантную сетку-«бенто» с карточками оптовых уровней.
Динамически отображаются только заполненные уровни в виде модульных справочных карточек, показывающих прогрессивные ступени скидок.
Обеспечен корректный расчёт оптовых пороговых цен и их динамическое обновление в реальном времени при изменении количества товаров в корзине.
Выполненные работы:
- Реализация оптовой логики в корзине
В файле /src/components/cart/ShoppingCart.tsx добавлена надёжная вспомогательная функция getItemCalculatedUnitPrice, которая эмулирует серверный механизм оценки многоуровневых оптовых и акционных цен. Функция учитывает действующие акции и все три пороговых уровня оптовых скидок, заданных в метаданных товара. - Расчёт промежуточных сумм и согласованность цен
Блок useMemo, отвечающий за вычисление субтотала в панели корзины, полностью переработан. Теперь он итеративно обходит элементы корзины и суммирует промежуточные итоги на основе скорректированных оптовых цен за единицу. Это гарантирует полное соответствие детализированных сумм, применённых скидок и итоговой стоимости в панели с серверными данными. - Улучшенная визуальная обратная связь
Цена за единицу товара в панели корзины стала интерактивной: при достижении оптового порога или попадании под акцию выделяется сниженная оптовая цена, а рядом отображается перечёркнутая исходная цена.
Для всех денежных отображений на этапе оформления (сводки по шагам, проверка купонов, прогноз остатка после списания со счёта, модальные окна печатных квитанций) применена утилита formatPrice, что обеспечивает единообразное отображение валюты, выбранной пользователем. - Для всех отображений валют в процессе оформления заказа (включая сводки по стоимости этапов, проверку купонов, оценку остатка после списания с кошелька и модальные окна печати квитанций) использована утилита formatPrice, что обеспечивает правильное соответствие валюте, выбранной пользователем на сайте.
Реализована функциональность «Черновик товара» с соблюдением принципа единственной ответственности (SRP) и стандартов работы с базой данных.
1. Эволюция схемы базы данных
В server.ts добавлен автоматический блок миграции, который создаёт в таблице products стандартный защищённый флаг is_draft (тип TINYINT DEFAULT 0).
2. Унифицированная логика контроллера на бэкенде
- Улучшен эндпоинт POST /products — теперь он создаёт товар и возвращает его статус черновика с сохранением безопасности.
- Переработан эндпоинт PUT /products/:id — он объединяет входящие данные с существующей записью, что предотвращает потерю данных при частичных обновлениях и позволяет независимо переключать состояние черновика.
В модальном окне редактирования товара (ProductFormModal) в разделе «Расширенные атрибуты» добавлен высококонтрастный блок управления статусом публикации и черновиком. Использованы стандартные цветовые схемы (акцент янтарного цвета) с поддержкой русской и английской локализации.
Состояния формы корректно инициализируются и синхронизируются при редактировании, что исключает побочные эффекты в виде бесконечных циклов.
4. Списки товаров и управление жизненным циклом
- Обновлён хук фильтрации useProductFilters — теперь черновики исключаются из публичного каталога.
- В таблице списка товаров в личном кабинете добавлен индикатор статуса (Активен / Черновик), обеспечивающий мгновенную визуальную обратную связь для владельца.
- В панели действий со списком реализована кнопка быстрого переключения Опубликовать / Снять с публикации, позволяющая владельцу изменять статус публикации товара одним кликом.
Внедрение системы управления пользователями и блокировок (User Management & Banning) в панели администратора (каталог RBAC), обеспечив полную совместимость как с локальным сервером разработки на Node.js, так и с виртуальным хостингом на PHP:
Визуальное оформление и дизайн интерфейса
- Интерактивная панель пользователя: Модернизировал представление каталога RBAC в панели администратора, добавив сворачиваемую карточку формы с высокой контрастностью для обработки как регистрации, так и редактирования профиля пользователя.
- Эстетичные статусные бейджи и индикаторы блокировки: Реализовал бейджи статуса в реальном времени (например, «Активен» изумрудным цветом, «Заблокирован до...» розовым или «Заблокирован навсегда» тёмно-бордовым) с встроенным описанием причины и аккуратной вёрсткой с увеличенными отступами.
- Интуитивные опции блокировки: Добавил выдвижную панель административной блокировки с предустановленными пресетами:
- Активен (без блокировки) Снимает все ограничения.
- Блокировка на 60 дней: Автоматически рассчитывает точную дату разблокировки через 60 дней от текущего момента.
- Блокировка навсегда: Устанавливает перманентную блокировку.
- Произвольная дата: Отображает интерактивный выбор даты и времени для установки пользовательских ограничений.
- Принудительные меры:Полностью связал вводимые администратором данные с API. Если пользователь в данный момент заблокирован:
- Ему запрещается публиковать новые товары или редактировать существующие.
- Ему запрещается оставлять отзывы о товарах.
- Ему запрещается оценивать чужие объявления.
- Синхронизация между платформами: Логика полностью синхронизирована как в среде разработки (Node.js/Express), так и в рабочей среде (PHP API). Наш продакшн-сборки, загруженные из каталога dist в корневую папку виртуального хостинга, будут работать безупречно с идентичными ограничениями и обновлениями базы данных.
Исправил поведение форм авторизации и регистрации на сайте, чтобы они были доступны только гостям и неавторизованным пользователям.
Основные изменения:
- Защита отображения форм: Теперь формы входа (login) и регистрации (register) отображаются на главной странице и в модальном окне только в том случае, если пользователь еще не авторизован (currentUser равен null).
- Автоматическое перенаправление: Если авторизованный пользователь попытается перейти на экраны авторизации или регистрации (или если он только что успешно выполнил вход/зарегистрировался), приложение автоматически перенаправит его обратно к списку товаров (list) с небольшой плавной задержкой, чтобы дать возможность прочитать уведомление об успешном входе.
- Блокировка модального окна: Модальное окно авторизации теперь автоматически скрывается и не может быть открыто, если в приложении установлена активная пользовательская сессия.
Онлайн-проверка занятости Username при регистрации
- Добавление функции проверки: В поле Username формы регистрации добавлена кнопка со значком лупы (поиска) для моментальной проверки занятости имени пользователя.
- Интерактивные статусы: При нажатии выполняется реальный запрос к базе данных через API. Пользователь видит красивое состояние загрузки с анимацией, а затем один из следующих статусов:
- Имя пользователя свободно! (с зеленой галочкой)
- Это имя пользователя уже занято. (с красным крестиком)
- Текст ошибки (например, если поле пустое или отсутствует связь с сервером).
- Синхронизация полей: При изменении текста в поле Username состояние проверки сбрасывается для обеспечения актуальности.
Добавление поля Email и обязательная валидация всех полей
- Новое поле: В форму регистрации добавлено полноценное поле Email с placeholder-ом yourname@example.com.
- Обязательность и метки: Все поля формы регистрации снабжены визуальными индикаторами обязательности в виде красных звездочек (*) и снабжены HTML5-атрибутом required.
- Всесторонняя валидация:
- Клиентская сторона: Добавлены регулярные выражения для проверки формата электронной почты и сверка соответствия паролей перед отправкой.
- Серверная сторона (Node.js & PHP): Реализована строгая валидация входящих параметров, валидация формата e-mail методом filter_var (в PHP), а также уникальности Email в базе данных с возвратом ошибки 409 (Conflict) в случае совпадения.
Полная поддержка PHP REST API (public/php_rest_api)
- Синхронизация кода: Обновлен контроллер UserController.php и роутер index.php в папке public/php_rest_api. Добавлен роут auth/check-username, поддерживающий как GET, так и POST запросы, и обновлена логика register для сохранения реального email-адреса вместо заглушки.
Что было сделано еще:
- Интерактивная валидация в UI (Регистрация):
- В компоненте src/components/auth/AuthForms.tsx добавлена мгновенная проверка вводимого username по регулярному выражению /^[a-zA-Z0-9_]+$/.
- Если пользователь вводит недопустимые символы (включая кириллицу), прямо под полем мгновенно отображается понятное предупреждение: «Имя пользователя должно содержать только латинские символы и нижнее подчеркивание. Кириллица недопустима.»
- Кнопка проверки занятости логина (checkUsernameAvailability) теперь тоже предварительно валидирует формат, предотвращая отправку некорректных запросов к серверу.
- Защита при отправке формы:
- В хуке src/hooks/useAuth.ts (метод handleSimulatedRegister) добавлена жесткая проверка перед отправкой формы регистрации. Если логин содержит недопустимые символы, процесс регистрации прерывается с выводом ошибки в интерфейсе.
- Серверная валидация (Node.js):
- В файле /server/routes/auth.ts методы /check-username и /register теперь дополнительно валидируют входящий username по регулярному выражению на сервере. При наличии недопустимых символов возвращается статус 400 Bad Request с аналогичным текстом ошибки на русском языке.
- Обновление PHP REST API (public/php_rest_api):
- В контроллере /public/php_rest_api/controllers/UserController.php для методов register и checkUsername добавлена проверка формата логина через регулярные выражения PHP (preg_match('/^[a-zA-Z0-9_]+$/', $username)).
- Обновлен файл /src/data.ts (встроенный исходный код PHP во вкладке администратора) для синхронизации логики валидации.
Реализовал как пагинацию, так и ленивую загрузку (бесконечный скролл / кнопку «Загрузить ещё») для списка товаров, строго следуя методологии Feature-Sliced Design (FSD)
Архитектура и реализованные функции:
Уровень Shared UI (shared/ui) :
- Создал переиспользуемый, визуально отполированный компонент пагинации. Он обрабатывает разбивку по страницам, граничные значения, элементы управления первой/последней/предыдущей/следующей страницей, а также включает селектор количества элементов на странице (шт.), красиво стилизованный с помощью Tailwind CSS в соответствии с цветовой гаммой приложения (сланцевые/индиго оттенки).
- Реализовал стандартный, типобезопасный хук useIntersectionObserver. Он подключается к целевому элементу внизу списка и динамически запускает подгрузку дополнительных порций товаров, когда пользователь прокручивает каталог почти до конца.
- Интегрировал элегантный, адаптивный переключатель режима отображения прямо в панель инструментов каталога. Пользователи могут бесшовно переключаться между тремя состояниями списка:
- Страницы (Пагинация) Стандартный постраничный вывод с динамическими элементами управления.
- Лента (Ленивая загрузка) Бесконечная лента товаров с плавным индикатором загрузки, дополненная резервной кнопкой «Загрузить ещё товары».
- Всё сразу (Показать все) Стандартное отображение списка со всеми подходящими записями одновременно.
- Встроил наблюдатели сброса состояния в движок списка. Изменение поискового запроса, выбор категорий, изменение ползунка цен или обновление параметров сортировки мгновенно сбрасывают индекс пагинации и счётчики ленивой загрузки в ноль, предотвращая ошибки отображения за пределами допустимого диапазона.
- Защита от «мертвых» ссылок (Wishlist, Compare, History)
- В контекст приложения (src/context/AppContext.tsx) добавлены строгие проверки на существование продуктов.
- Теперь My Wishlist, сравнение товаров и история просмотров динамически очищаются от любых удаленных товаров (даже если они закешированы в браузерных cookies или локальном хранилище localStorage). Это полностью решает проблему висящих счетчиков и битых элементов.
- Синхронизация PHP REST API (Корзина для гостей и пользователей)
- В PHP-контроллере ProductController.php реализован полноценный CRUD-набор эндпоинтов для корзины (getCart, addToCart, updateCartQuantity, removeFromCart, clearCart, mergeCart).
- Маршрутизатор public/php_rest_api/index.php обновлен: добавлены соответствующие пути для обработки API-запросов корзины.
- В метод оформления заказа checkout() в ProductController.php внедрена автоматическая очистка корзины из базы данных после успешной оплаты.
- Слияние гостевой корзины при авторизации (PHP)
- В UserController.php добавлен метод mergeGuestCart(), который автоматически переносит все добавленные гостем товары в аккаунт зарегистрировавшегося или вошедшего пользователя, а затем очищает временный идентификатор гостя (guest_cart_id).
- Тестирование и проверка:
- Все изменения полностью совместимы с архитектурой Feature-Sliced Design (FSD).
- Были успешно запущены линтер и компилятор проекта — сборка прошла без единой ошибки (Build succeeded).
Установил и настроил ESLint для проекта с использованием самой современной и производительной конфигурации Flat Config (v9)
Что это даёт и для чего нужен ESLint?
ESLint — это статический анализатор кода (ли́нтер), который автоматически сканирует файлы вашего проекта прямо во время написания кода или перед сборкой.Вложения
-
Screenshot_82.png627,8 KB · Просмотры: 9 -
Screenshot_81.png481,7 KB · Просмотры: 8 -
Screenshot_80.png162,5 KB · Просмотры: 5 -
Screenshot_79.png274,1 KB · Просмотры: 4 -
Screenshot_78.png450,9 KB · Просмотры: 4 -
Screenshot_76.png1,1 MB · Просмотры: 3 -
Screenshot_75.png428,2 KB · Просмотры: 3 -
Screenshot_74.png424,9 KB · Просмотры: 3 -
Screenshot_73.png582 KB · Просмотры: 3 -
Screenshot_72.png702 KB · Просмотры: 3 -
Screenshot_71.png310,6 KB · Просмотры: 3 -
Screenshot_70.png339,7 KB · Просмотры: 3 -
Screenshot_69.png330,6 KB · Просмотры: 3 -
Screenshot_68.png317,7 KB · Просмотры: 3 -
Screenshot_67.png185 KB · Просмотры: 3 -
Screenshot_66.png147,3 KB · Просмотры: 4
Последнее редактирование:

