asdoria/sylius-pickup-point-plugin

Asdoria Sylius 提货点插件

安装: 256

依赖项: 0

建议者: 0

安全: 0

星标: 4

关注者: 0

分支: 4

开放问题: 0

类型:sylius-plugin

0.1.6 2023-10-31 08:54 UTC

This package is auto-updated.

Last update: 2024-09-20 17:27:34 UTC


README

Asdoria Lgoo

Asdoria Sylius 提货点插件

此插件允许您在 Sylius 商店中检索和使用不同提供商的提货点

Pickup Point Plugin

安装

使用 composer 安装插件

$ composer require asdoria/sylius-pickup-point-plugin

config/bundles.php 中注册包

[...]
Bazinga\Bundle\JsTranslationBundle\BazingaJsTranslationBundle::class => ['all' => true],
Setono\SyliusPickupPointPlugin\SetonoSyliusPickupPointPlugin::class => ['all' => true],
Asdoria\SyliusPickupPointPlugin\AsdoriaSyliusPickupPointPlugin::class => ['all' => true],
FOS\JsRoutingBundle\FOSJsRoutingBundle::class => ['all' => true],
[...]

导入配置

# config/packages/asdoria_sylius_pickup_point.yaml
imports:
    - { resource: "@SetonoSyliusPickupPointPlugin/Resources/config/app/config.yaml" }
    - { resource: "@AsdoriaSyliusPickupPointPlugin/Resources/config/config.yaml" }

setono_sylius_pickup_point:
    resources:
        pickup_point:
            classes:
                model: Asdoria\SyliusPickupPointPlugin\Entity\PickupPoint

asdoria_sylius_pickup_point:
    chrono_relay:
        enabled: true
        options:
            accountNumber: JOHNDOE
            password: 123456
    mondial_relay:
        enabled: false
        options:
            accountNumber: JOHNDOE
            password: 123456
    colissimo_relay:
        enabled: false
        options:
            accountNumber: JOHNDOE
            password: 123456
    shop2shop_relay:
        enabled: false
        options:
            accountNumber: JOHNDOE
            password: 123456
            maxPointChronopost: 20
    dpd_relay:
        enabled: false
        options:
            key: KEY

导入路由

# config/routes/setono_sylius_pickup_point.yaml
setono_sylius_pickup_point_plugin:
    resource: "@SetonoSyliusPickupPointPlugin/Resources/config/routing.yaml"

# config/routes/fos_js_routing.yaml
fos_js_routing:
    resource: "@FOSJsRoutingBundle/Resources/config/routing/routing-sf4.xml"
    prefix: /{_locale}

# config/packages/js_translation.yaml
bazinga_js_translation:
    resource: "@BazingaJsTranslationBundle/Resources/config/routing/routing.yml"
    prefix: /{_locale}

将以下内容粘贴到 src/Entity/Shipping/Shipment.php 文件

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusPickupPointPlugin\Model\PickupPointAwareTrait;
use Setono\SyliusPickupPointPlugin\Model\ShipmentInterface;
use Sylius\Component\Core\Model\Shipment as BaseShipment;

/**
 * @ORM\Entity()
 * @ORM\Table(name="sylius_shipment")
 */
class Shipment extends BaseShipment implements ShipmentInterface
{
    use PickupPointAwareTrait;
}

如果您不使用注解,请添加 Shipment.orm.xml

<?xml version="1.0" encoding="UTF-8"?>

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">

    <mapped-superclass name="App\Entity\Shipping\Shipment" table="sylius_shipment">
        <field name="pickupPointId" column="pickup_point_id" nullable="true"/>
    </mapped-superclass>
</doctrine-mapping>

将以下内容粘贴到 src/Entity/Shipping/ShippingMethod.php 文件

<?php

declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusPickupPointPlugin\Model\PickupPointProviderAwareTrait;
use Setono\SyliusPickupPointPlugin\Model\ShippingMethodInterface;
use Sylius\Component\Core\Model\ShippingMethod as BaseShippingMethod;

/**
 * @ORM\Entity()
 * @ORM\Table(name="sylius_shipping_method")
 */
class ShippingMethod extends BaseShippingMethod implements ShippingMethodInterface
{
    use PickupPointProviderAwareTrait;
}

如果您不使用注解,请添加 ShippingMethod.orm.xml

<?xml version="1.0" encoding="UTF-8"?>

<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping">

    <mapped-superclass name="App\Entity\Shipping\ShippingMethod" table="sylius_shipping_method">
        <field name="pickupPointProvider" column="pickup_point_provider" nullable="true"/>
    </mapped-superclass>
</doctrine-mapping>

config/packages/_sylius.yaml 中告诉 Sylius 使用您自己的扩展资源

sylius_shipping:
    resources:
        shipment:
            classes:
                model: App\Entity\Shipping\Shipment
        shipping_method:
            classes:
                model: App\Entity\Shipping\ShippingMethod

更新数据库模式

bin/console doctrine:migrations:diff
bin/console doctrine:migrations:migrate 

运行以下命令

bin/console cache:clear
bin/console fos:js-routing:dump --format=json --target=public/js/fos_js_routes.json
bin/console bazinga:js-translation:dump public/js --format=json
bin/console sylius:install:assets

前端

0/ 管理员

在 ShippingMethod 表单中添加 {{ form_row(form.pickupPointProvider) }}。您可以从插件目录中复制模板覆盖

From: [shop_dir] vendor/asdoria/sylius-pickup-point-plugin/src/Resources/views/bundles/SyliusAdminBundle/*
To: [shop_dir] templates/bundles/SyliusAdminBundle/*

1/ 步骤

  1. templates/bundles/SyliusShopBundle/Checkout/selectShipping.html.twig 中,放置具有类 react-pickup-point 的 react 实例元素,以及具有 data-pkp-locale="{{ app.request.locale }}" 属性的 locale
{% block content %}
[...]

<div class="react-pickup-point"
     data-pkp-locale="{{ app.request.locale }}"
     data-pkp-height="500px"
     data-pkp-height-mobile="250px"></div>
{% endblock %}
  1. templates/bundles/SyliusShopBundle/Checkout/SelectShipping/_shipment.html.twig 中,放置具有类 react-pickup-point-input-hidden<input type="hidden">
{% form_theme form.pickupPointId '@SetonoSyliusPickupPointPlugin/Form/theme.html.twig' %}

<div>
    {{ form_errors(form.method) }}

    {% for key, choice_form in form.method %}
        {% set fee = form.method.vars.shipping_costs[choice_form.vars.value] %}
        {% set method = form.method.vars.choices[key].data %}
        {% include '@SyliusShop/Checkout/SelectShipping/_choice.html.twig' with {'form': choice_form, 'method': method, 'fee': fee} %}
    {% else %}
        {% include '@SyliusShop/Checkout/SelectShipping/_unavailable.html.twig' %}
    {% endfor %}

    {#
    <div class="react-pickup-point" data-pkp-height="500px"></div>
    #}

    {% if form.method|length %}
        {{ form_widget(form.pickupPointId, {'attr': {'class': 'react-pickup-point-input-hidden'}}) }}
        {{- form_errors(form.pickupPointId) -}}
    {% endif %}
</div>
  1. 在您的 JS 上下文中,您必须在 webpack 中创建一个新的入口点
.addEntry('pickup-point', [
    './assets/shop/js/app/pickup-point.js'
])
  1. templates/bundles/SyliusShopBundle/Checkout/selectShipping.html.twig 中,调用 javascripts 和 stylesheets 事件,并在其他脚本之后调用 pickup-point 脚本
{% block stylesheets %}
    {{ parent() }}
    {{ sylius_template_event('asdoria.pickup.point.stylesheets') }}
{% endblock %}

{% block javascripts %}
    {{ parent() }}
    {{ sylius_template_event('asdoria.pickup.point.javascripts') }}
    {{ encore_entry_script_tags('pickup-point', null, 'shop') }}
{% endblock %}
  1. 创建文件 assets/shop/js/app/pickup-point.js
document.addEventListener('DOMContentLoaded', async () => {
    const providersWithPickupPoint = [...document.querySelectorAll('input.input-shipping-method[data-pickup-point-provider]')]
    if (!providersWithPickupPoint.length) return

    const providerCheckedByDefault = providersWithPickupPoint.find(providerHTML => providerHTML.checked)

    const paramsForEventBus = {}

    if (providerCheckedByDefault) {
        const elToTeleportPickupPoint = getElToTeleportPickupPoint(providerCheckedByDefault)

        if (!elToTeleportPickupPoint) return

        paramsForEventBus.providerCode = providerCheckedByDefault.dataset?.pickupPointProvider
        paramsForEventBus.csrfToken    = providerCheckedByDefault.dataset?.csrfToken

        window.asdoriaPickupEventBus.dispatchEvent('EVENT_INSTANCE_PICKUP_POINT', {
            ...paramsForEventBus,
            elToTeleport: elToTeleportPickupPoint
        })
    }

    providersWithPickupPoint.forEach(providerWithPickupPoint => {
        providerWithPickupPoint.addEventListener('change', (e) => {
            const elToTeleportPickupPoint = getElToTeleportPickupPoint(e.target)

            if (!elToTeleportPickupPoint) return

            const instanceAppReact = document.querySelector('.pkp-app')

            paramsForEventBus.providerCode = e.target.dataset?.pickupPointProvider
            paramsForEventBus.csrfToken    = e.target.dataset?.csrfToken

            if (instanceAppReact) {
                window.asdoriaPickupEventBus.dispatchEvent('EVENT_SET_PICKUP_POINT', {
                    ...paramsForEventBus,
                    elToTeleport: elToTeleportPickupPoint
                })

                return
            }

            window.asdoriaPickupEventBus.dispatchEvent('EVENT_INSTANCE_PICKUP_POINT', {
                ...paramsForEventBus,
                elToTeleport: elToTeleportPickupPoint
            })
        })
    })

    const providersWithoutPickupPoint = [...document.querySelectorAll('input.input-shipping-method:not([data-pickup-point-provider])')]

    providersWithoutPickupPoint.forEach(providerWithoutPickupPoint => {
        providerWithoutPickupPoint.addEventListener('change', (e) => {
            window.asdoriaPickupEventBus.dispatchEvent('EVENT_HIDE_PICKUP_POINT')
        })
    })

    updateCurrentPoint()
})

/**
 *
 * @param inputRadio
 * @returns {*|null}
 */
const getElToTeleportPickupPoint = (inputRadio) => {
    const reactParentTeleportPickupPoint = inputRadio.closest('.react-parent-teleport-pickup-point')

    if (!reactParentTeleportPickupPoint) return null

    const elToTeleportPickupPoint = reactParentTeleportPickupPoint.querySelector('.react-teleport-pickup-point')

    if (!elToTeleportPickupPoint) return null

    return elToTeleportPickupPoint
}

const updateCurrentPoint = () => {
    const elInstance = document.querySelector('.react-pickup-point')
    const inputHidden = document.querySelector('.react-pickup-point-input-hidden')

    if (!elInstance || !inputHidden) return

    window.asdoriaPickupEventBus.addEventListener('EVENT_UPDATE_CURRENT_PICKUP_POINT', ({ detail: getCurrentPoint }) => {
        inputHidden.value = getCurrentPoint.code
    })
}
  1. 地图将在当前选择的提供商中传送。要做到这一点,在 templates/bundles/SyliusShopBundle/Checkout/SelectShipping/_choice.html.twig 中,在选择容器中放置类 react-parent-teleport-pickup-point,并在该容器的子 <div> 中放置类 react-teleport-pickup-point
{% import '@SyliusShop/Macro/images.html.twig' as Image %}
{% import '@SyliusShop/Common/Macro/money.html.twig' as money %}

<div class="{% if method.pickupPointProvider is not empty %} react-parent-teleport-pickup-point{% endif %}">
    {{ form_row(form, sylius_test_form_attribute('shipping-method-select')) }}

    [...]

    {% if method.pickupPointProvider is not empty %}
    <div class="react-teleport-pickup-point"></div>
    {% endif %}
</div>
  1. 创建文件 config/routes/js_translation.yaml
bazinga_js_translation:
    resource: "@BazingaJsTranslationBundle/Resources/config/routing/routing.yml"
    prefix: /{_locale}
    requirements:
        _locale: ^[A-Za-z]{2,4}(_([A-Za-z]{4}|[0-9]{3}))?(_([A-Za-z]{2}|[0-9]{3}))?$

2/ 选项

<div class="react-pickup-point"
     data-pkp-height="500px"
     data-pkp-height-mobile="250px"
     data-pkp-zoom="12"
     data-pkp-filter-shop="1"
     data-pkp-zoom-control="0"
     data-pkp-scroll-wheel-zoom="1"
     data-pkp-zoom-control-position="topleft">
    {% if form.method|length %}
    {{ form_row(form.pickupPointId) }}
    {% endif %}
</div>