Я делал бэкенд, дизайном и вёрсткой занимались другие люди.
Плюс перенос всего контента из drupal 6 + ubercart 2.
26000 сущностей product,
3000 product display,
116 типов товаров (отдельная сущность, в которой хранятся настройки атрибутов, отображения и т.д)
1500 цветов,
600 размеров,
90 особенностей товаров - по ним можно делать выборку в каталоге,
225 характеристик товаров, пока выполняют описательную функцию, планируется добавлять их в индекс в зависимости от типа товара
Цвета и размеры приведены к общепонятным.
Например: цвет Alert, у одного производителя он может быть красным, а у другого - оранжевым, и т.п. Все цвета приведены к красному-желтому-зелёному, понятным пользователям.
Один производитель может шить одежду-маломерку, его размер М будет соответствовать 46 размеру, а другой - наоборот: его М - это 50й размер. Это мужские размеры, а есть ещё женские и детские.
Размеры приведены к буквенным S-M-L среднестатистического здорового человека, и к числовым размерам старого доброго ГОСТа.
Из особенностей:
- сортировка и фильтрация товаров внутри дисплеев,
- отслеживание остатков товаров по 16 магазинам розничной сети - можно отфильтровать только те товары, которые есть в определенном магазине, если покупатель захочет примерить вещь перед покупкой,
- соответственно - синхронизация остатков и цен (в т.ч. старая цена - новая цена) с базой данных розничной сети,
- мультидоменность: пока запущен сайт розничной сети, День Сурка, планируется перенос остальных сайтов с d6+uc2 и добавление новых. Ожидается увеличение кол-ва товаров/дисплеев до 40000/5000 сущностей.
У каждого сайта может быть отдельный ассортимент (на уровне product и product display), своя ценовая политика (цены синхронизируются с бд сети подоменно), свои маркетинговые активности (хит продаж, товар дня и т.п), - общая панель администрирования заказов для всех доменов, в данный момент заказы из нового сайта на d7 синхронизируются со старой админкой остальных сайтов на d6 через services
- существенно переработан checkout - способы доставки сгруппированы, способы оплаты привязаны к способам доставки, поля для пользовательского ввода минимизированы, в зависимости от выбранных доставки и оплаты
Что не сделано:
- очень много не свёрстано (вопрос не ко мне)
- планируется аяксификация фасетов, я бы ещё дополнительно поработал над их внешним видом
- фильтрация каталога по отдельным характеристикам товаров
- генерация файлов для Я.Маркета
Вложение | Размер |
---|---|
snimok_ekrana_ot_2015-06-28_152315.png | 1.14 МБ |
Комментарии
Быстро работает,на чем крутится это добро?
Там многоуровневое кеширование:
1. Кешируются панели,
2. Кешируются результаты вьюсов, сам вьюс, которым строится каталог, делает запросы к солру, откуда получает готовые значения цен, скидок, акций и т.п. - разгружая БД.
3. Entitycache.
Ну, и весь кеш лежит в Redis.
По железу - http://servers.agava.ru/server_nezavisim.shtml, тариф А1273
хочется кейс-стадии
ну типа доклад на друпал-пати
Как и чем решались разные задачи, траблы. Как удалось не убить логистов
В прошлом году я приводил этот сайт в качестве примера каталога на кэмпе.
Тогда магазин ещё не работал, только каталожная его часть. В этом году можно будет и про магазин рассказать.
Ну, в этом случае тоже была спешка, но не настолько суровая.
Чуть меньше года прошло от начала до запуска, и запускали - как обычно, с недоделками.
PageSpeed от гугла не очень одобряет. А выглядит симпатично.
А что PageSpeed'у не понравилось?
А, сам посмотрел - да, есть над чем поработать.
Спасибо!
И в каком месте там друпал?
Прибейте спамера.
Судя по описанию - нормально работы проделали.
Основная сложность - разнесение данных по доменам и изоляция их друг от друга.
Предполагается, что на отдельных доменах будут сторонние продавцы: своего рода интернет-маркетинг на аутсорсе.
Компания обеспечивает отработку заказов: оплату, доставку, рекламации и т.п. а задача владельца домена - привлечение покупателей и их конвертация в заказы.
Соответственно, таким юзерам административный доступ ограничивается рамками их домена.
Это ещё не реализовано на 100%, но заложено в структуру сайта.
ага, вот и базар на коммерце нарисовался,
респект))
Нет, как такового - маркетплейса там не будет.
Весь ассортимент должен находиться в местах хранения и он должен быть проведён по учету.
На каждом домене может быть представлены как все дисплеи и все товары, привязанные к ним, так и их часть.
Например, на сайтах-ИМ, показываются только те дисплеи и товары в них, которые имеются в наличии.
На сайтах-каталогах брендов - только товары-дисплеи определенного бренда, в т.ч. отсутствующие и/или снятые с производства - в качестве архива продукции.
Есть тематические сайты - например, отдельно для экстремалов, где собраны только товары для разного рода фрирайда.
Ну и т.д.
Сегментируем ЦА - повышаем конверсию, джаст бизнес.
Реализовал генерацию прайс-листа для Яндекс Маркета.
Генерится по крону, раздача обновляется по мере поступления новой выгрузки.
При изменении фильтров - рестартует.
Получается вот такой xml:
Все настройки хранятся подоменно, выгрузка происходит параллельно.
Архив ничем не поможет - сейчас богатый внутренний мир сайта обрабатывается хардкодом, не укладывается его логика в стандартные средства друпала.
Видится мне там отдельный вьюс дисплей, которым тянутся и рендерятся значения, с раскрытыми фильтрами в админке, и какой-нибудь рул для постпроцесса.
Но позже. Осенью.
Всё, на 3+
p.s. Если автору интересно покажу косяки.
Да, интересно.
1.Нажми на ссылку "Вход Регистрация" и как появится окно, посмотри в вверх в право на Корзину
2.На странице checkout
в стиль - #payment-details label, #commerce-shipping-service-details label - добавь...
#payment-details label, #commerce-shipping-service-details label{
display:inline-block:
width:130px;
text-align:right;
}
для поля доп.инфа по доставке ширину лейбла пропиши отдельно(что бы было красиво)
#edit-customer-profile-shipping-msk-field-profile-shipping-info label{
width:100%Important;
}
3. на странице http://www.densurka.ru/news/tovar_nedeli - внизу нажми на кнопку заполнить анкету и посмотри что там с полями в модальной форме...(ужасть, именно в модальном окне а не на странице)
ну и еще конечно просто лень писать прости...
Ок, понятно.
Ну, а что в таком случае, можно оценить на 4 (без плюса), или на 5 ?
Какая, вообще, шкала: 3+ из трёх - это высокая оценка, а из 100 - в пределах погрешности, ни о чём.
Как выглядит весь диапазон, что там на максимуме, и на минимуме?
нет, 4-
максимум 5+
p.s. Все субъективно.
Впечатляет. И размах, и оформление.
Доработали систему скидок.
Теперь их 3 типа:
-
старая ценановая цена, это изначально синхронизируется с учетным софтом- накопительная скидка пользователя: поле user_discount типа Integer List с предустановленными значениями
- сущность Акция, которая может быть активирована вручную или по расписанию, распространяется на любой список товаров.
Дело в том, что скидки, реализованные в commerce_discount, влияют на commerce_line_item, а не на продукт, и могут быть применены при создании заказа/корзины, а надо в каталоге.
При изменении Акции - товары, на которые она распространялась/будет распространена, помечаются на переиндексацию, поскольку надо фильтровать и сортировать каталог с учетом результирующей скидки, рассчитанной с поправкой на накопительную скидку юзера.
Размер итоговой цены/скидки/её типа - рассчитывается рулом, там можно прописать логику любой степени извращенности.
В данном случае, применено вытеснение большей скидкой ту, что меньше.
Для Анонимуса:
и для юзера с накопительной скидкой 25%
А можно сделать, например, акцию +5% к имеющейся скидке.
Ajax facets + Pretty path в итоге работают для аяксификации выдачи, только сортировка с Search sorts не работает, вроде ее можно с помощью Search API ajax прикрутить, но с этим модулем перестают работать Ajax facets (вероятно из-за того лишь впрочем, что я не настраивал Search API ajax в собственном модуле). Но в целос аякс пашет, даже диапозоны нормально работают, не схлопываясь до одного неизменяемого значения.
Кстати хотел спросить, вот кнопка "Добавить в корзину" при использовании панелей добавляется с помощью вьювсов (по крайней мере это наиболее распространенный метод на сколько я заметил), у вас так же? Просто интересно как оно работает со столь сложным типом материала? У вас же там можно выбрать товар на странице дисплея с помощью нескольких селектов (как это кстати реализовано?).
Кнопка добавления в корзину - это самостоятельный content pane, на странице карточки товара их несколько: список товаров с ценами, селекты для выбора атрибутов, изображение товара, превью изображений - тоже отдельный content pane, ну и т.д.
Между ними проброшена логика на js - при смене атрибута товара - перерисовываются панели.
Тут напрашивается backbone, тем более что информация о товарах хранится в js-объектах, максимально приближенных к коллекциям, но пока нет.
Без js, разумеется, работать не будет, но и коробочное решение и так не позволит оформить заказ с отключенным js.
Поэтому на 0.5% юзеров без js - просто забили.
Кнопка добавления в корзину - дёргает аяксом сервис на сервере, которому передаёт id ноды-дисплея, id продукта и его количество.
При изменении атрибутов / перерисовке кнопки - проверяется, что товар доступен для заказа, иначе кнопка недоступна для клика.
Здорово получилось! Но вот кстати по поводу backbone наверное не соглашусь, но только от того, что предпочитаю AngularJS, правда вот совместить ангуляр с друпалом пока не пробовал (если не считатать этого) но там от друпала давно ничего не осталось кроме разметки по-сути это чистый ангуляр вставленный в ноду. Как совмещается backbone даже представить не могу.
Я совершенно не против ангуляра, но вот сколько не пытался выяснить у разработчиков, работающих с ним - плюсы/минусы в сравнении с бекбоном - никакой внятной картины.
За backbone у меня сейчас 2 аргумента:
- он в коробке D8
- я нашел к нему замечательную либу Backbone.Facetr можно фильтровать элементы коллекций по их свойствам, фасеты на клиенте - это же прекрасно
Вот про то, что он сейчас в коробке D8 - этого я не знал и это уже весомый повод им заняться! Правда я пока в работе D8 не использую, пока все на 7ке, но уже походу пора переходить.
В ангуляре мне более всего понравился простой и внятный синтаксис, двустороннее связывание (очень упрощает верстку местами), система областей видимости и строгость всей структуры приложения, которая заранее определена библиотекой, а так же огромное количество сторонних директив расширяющих функционал (их значительно больше чем модулей в backbone). Ну и например фасеты там организуются элементарно прямо из коробки, это одна из основных фишечек как мне показалось этой библиотеки.
<ul><li ng-repeat="item in array | {item.condition:someCondition}">{{item.attr}}</li></ul>
При изменении someCondition любым способом список тут же переформатируется так, чтобы условие элемента массива (item.condition) совпадало с someCondition. Сам список выводит некий атрибут item'a, но можно понятно выводить все что угодно. При том тут логика уже упрятана в сами директивы, надо только прописать условия изменения someCondition и задать ему дефолтное значение, дальше ангуляр сам...
Андрей, день добрый! Я к вам там в скайп постучался (мне его Витя Вильчинский дал, если что) никак не могу найти инфу о том как добавить агрегацию к вьюхе каталога, гугл об это как будто совсем не в курсе (ну т.е. пару человек интересовалось, но никто ответа не получил).
ни разу не летает.
9.5 секунд страница каталога.
такой медленный каталог я раньше видел только в битриксе
http://joxi.ru/BA0dXEUB9o7YAy.png
Да, возникли проблемы с производительностью недели 2 назад - пока боремся.
Там и база разрослась, и индекс солра, стало не хватать ресурсов.
Fixed.
Если кратко, то:
- почистили базу
- добавили памяти mysql
- добавили памяти solr
- изменили режим persistence для redis
- выбросили apache2
- перешли на php7-fpm
В прошлую пятницу, 13 апреля, исполнилось 3 года как сайт был запущен в продакшн.
С тех пор много чего изменилось, добавилось и было пофикшено.
Из последних доработок - фасет по цене:
Был доработан плагин Min/Max UI Slider из модуля Search API ranges в связи с тем, что:
Заодно сделал корректное округление диапазонов с учетом шага (он равен 1000р.) и решил проблему с ростом кеша url - из-за значений фильтра по цене, он стал рости очень быстро.
Круто!
Может патчиком с сообществом поделитесь? Думаю, кому-нибудь пригодилось бы.
А там, собственно, не патч, а свой кастомный модуль, который наследует виджет из Search API ranges:
class CustomSearchApiRangesWidgetUISlider extends SearchApiRangesWidgetUISlider
самая мякотка в public function _buildUISliderForm() - заменяем search_api_ranges_minmax() на свою cusom_search_api_ranges_minmax()
В исходном коде зачем-то грузится сущность и затем search_api_extract_fields().
У меня это не работало по двум причинам: используется денормализация по доменам с помощью Search API Grouping - там к ID сущности добавляется целое число _0, _1, и т.д.
И цены с учетом пользовательской скидки - являются entity property, а не полями.
Странно, зачем так было сделано - ведь эти значения уже есть в индексе, раз мы строим по ним фасет, и они возвращаются поисковым сервером при запросе минимального-максимального значений.
А что касается альтера запроса - там используется hook_search_api_solr_query_alter(), но в нем хардкод.
неплохо.
жаль только семерка(((
Я между делом накатываю "желтые" обновления контриба (обновления безопасности устанавливаются сразу же - это святое), просматриваю diff.
Во многих случаях изменения носят косметический характер - форматирование кода по стандартам, добавляются примечания, легкий рефакторинг, не меняющий логику, но добавляющий удобочитаемости кода.
Семёрка напоминает мне сейчас хорошее выдержанное вино - приятно смотреть на свет через бокал.
Надеюсь, что восьмерку ждет та же участь, но пока я "подожду второго сервиспака".