sebastiansulinski/laravel-currency

Laravel 9+ 的货币组件

v3.2.0 2023-12-09 10:24 UTC

This package is auto-updated.

Last update: 2024-09-09 12:11:30 UTC


README

安装

使用 Composer 安装此包

composer require sebastiansulinski/laravel-currency

服务提供者和外观

要使用 IOC 容器,请将 SSD\Currency\CurrencyServiceProvider 添加到 config/app.phpproviders 部分的列表

'providers' => [
    ...

    SSD\Currency\CurrencyServiceProvider::class

]

要使用它作为外观,请将其添加到 aliases

'aliases' => [
    ...

    'Currency'  => SSD\Currency\CurrencyFacade::class
]

现在运行

php artisan vendor:publish

这将在以下结构下添加一个新文件 config/currency.php

<?php

return [
    "key" => "currency",
    "default" => \SSD\Currency\Currencies\GBP::code(),
    "currencies" => [
        \SSD\Currency\Currencies\GBP::class,
        \SSD\Currency\Currencies\USD::class,
        \SSD\Currency\Currencies\EUR::class,
    ],
    "value_as_integer" => false,
];
  • key 被用作会话密钥,用于存储当前选定的货币。
  • default 指定默认货币代码。
  • currencies 包含可用货币的列表。
  • value_as_integer 指示您的价格是存储为整数还是浮点数/十进制。

提供者

该包包含两个实现/提供者

  • SSD\Currency\Providers\CookieProvider,它将选定的货币存储在加密的 cookie 中
  • SSD\Currency\Providers\SessionProvider,它将使用默认会话驱动程序存储选定的货币

您可以通过

  • 扩展 SSD\Currency\Providers\BaseProvider 来创建额外的提供者

新提供者需要实现 3 个方法 - 这些是: getsetis。请参阅 SSD\Currency\Providers\CookieProvider 以获得更好的理解。

一旦您有了新的实现,请创建新的 ServiceProvider 并将其替换为 config/app.php

添加更多货币

该包包含 3 种货币:GBPUSDEUR

如果您想添加更多,首先创建一个新的货币类,该类

  • 扩展 SSD\Currency\Currencies\BaseCurrency

例如,日本日元的实现(假设您将货币放在 App\Components\Currencies 命名空间下)

<?php 

namespace App\Components\Currencies;

use SSD\Currency\Currencies\BaseCurrency;

class JPY extends BaseCurrency
{
    /**
     * Get symbol.
     *
     * @return string
     */
    public static function symbol(): string
    {
        return '¥';
    }

    /**
     * Get code.
     *
     * @return string
     */
    public static function code(): string
    {
        return 'JPY';
    }
}

现在,为了能够使用它,您需要将其添加到 config/currency.php 文件中

<?php

return [
    "key" => "currency",
    "default" => \SSD\Currency\Currencies\GBP::code(),
    "currencies" => [
        \SSD\Currency\Currencies\GBP::class,
        \SSD\Currency\Currencies\USD::class,
        \SSD\Currency\Currencies\EUR::class,
        \App\Components\Currencies\JPY::class,
    ],
    "value_as_integer" => false,
];

值后面有货币符号的货币

某些货币将符号放在值后面。要表示它,您可以覆盖方法 BaseCurrency::symbolAfterValue,如果需要在符号和值之间留出空格,则可以使用 BaseCurrency::symbolSpace

<?php 

namespace App\Components\Currencies;

use SSD\Currency\Currencies\BaseCurrency;

class PLN extends BaseCurrency
{
    /**
     * Get symbol.
     *
     * @return string
     */
    public static function symbol(): string
    {
        return '';
    }

    /**
     * Get code.
     *
     * @return string
     */
    public static function code(): string
    {
        return 'PLN';
    }

    /**
     * Determine if symbol should be placed after the value.
     *
     * @return bool
     */
    protected static function symbolAfterValue(): bool
    {
        return true;
    }

    /**
     * Determine if there is a space between symbol and the value.
     *
     * @return bool
     */
    protected static function symbolSpace(): bool
    {
        return true;
    }
}

上面的类现在将返回 75.00 zł(使用 withSymbol 方法),以及 75.00 zł PLN(使用 withSymbolAndCode 方法)。

使用示例

显示货币的最常见方式是将其显示为可点击的按钮或作为表单 select 菜单,以下我将演示。

首先,让我们创建一个包含所有选项的表单选择元素。我们可以使用 Currency 外观或简单地从容器中拉取 currency 使用 app('currency')

<form>
    <select id="currency">
        @foreach(app('currency')->options() as $option)
            <option 
                value="/currency/{{ $option->value }}"
                {{ app('currency')->selected($option->value) }}
            >{{ $option->label }}</option>
        @endforeach
    </select>
</form>

现在我们需要一些 JavaScript,以便当 change 事件发生时,调用给定的路由,其中控制器的操作设置新的货币,页面刷新以反映该更改。

只需使用 JavaScript 将 change 事件绑定到 select 元素即可

// vanilla JavaScript
(document.getElementById('currency')).addEventListener('change', function (event) {
    window.location.href = event.target.value;
});

// or using jQuery
$('#currency').on('change', function () {
    window.location.href = $(this).val();
});

接下来,我们需要添加具有动作的控制器和路由

// app/Http/routes.php

Route::get('currency/{currency_id}', 'CurrencyController@set');
// app/Http/Controllers/CurrencyController.php

<?php 

namespace App\Http\Controllers;

use Illuminate\Http\JsonResponse;

use Currency;

class CurrencyController extends Controller
{
    /**
     * Set currency cookie.
     *
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function set($id)
    {
        Currency::set($id);

        return new JsonResponse(['success' => true]);
    }
}

现在,如果您想根据选定的货币显示价格,请确保您的模型可以提供给定项目的以下格式的价格数组

[
    'GBP' => 10.00,
    'EUR' => 11.56,
    'USD' => 17.60,
    'JPY' => 18.50
]

// or if you're using prices as integers

[
    'GBP' => 1000,
    'EUR' => 1156,
    'USD' => 1760,
    'JPY' => 1850
]

假设我们的 Product 模型有一个 prices() 方法,它将返回上述格式的数组。要使用它与货币,现在您可以简单地调用

/**
 * Array of prices.
 *
 * @return array
 */
public function prices()
{
    return [
        'GBP' => $this->price_gbp,
        'EUR' => $this->price_usd,
        'USD' => $this->price_eur,
        'JPY' => $this->price_jpy
    ];
}

/**
 * Price formatted with the currency symbol.
 *
 * @return string
 */
public function priceDisplay()
{
    return Currency::withSymbol($this->prices(), null, 2);
}

priceDisplay() 方法将返回带有货币符号的价格,例如 £10.00(取决于当前选定的货币)。

格式化方法

在我们的 Currency 对象实例/外观上提供了以下方法

  • decimal($values, $currency = null, $decimal_points = 2):获取值并以十进制格式返回。
  • integer($values, $currency = null):获取值作为整数,即 20.53 将变为 20,但 2053 将保持为 2053
  • withSymbol($values, $currency = null, $decimal_points = null):获取值并在开始处带有货币符号返回。
  • withCode($values, $currency = null, $decimal_points = null):获取值并在末尾带有货币代码返回。
  • withSymbolAndCode($values, $currency = null, $decimal_points = null):获取值并在其中带有货币符号和代码返回。

上述四种方法接受 3 个参数(只有 integer 方法接受前两个)

  • $values:可以是上面的数组或单个浮点数/整数
  • $currency:货币代码 - 默认为 null,此时将从 cookie 中获取货币 - 否则,您可以指定要使用的货币。
  • $decimal_points:返回值时要保留的小数位数。

更多方法

  • options():返回一个 SSD\Currency\Option 的数组 - 每个代表一种货币。SSD\Currency\Option 有两个属性 valuelabel
  • selected($currency):与 select option 元素一起使用,以将给定选项设置为 selected="selected" 如果它是当前设置。
  • get():获取当前选定的货币。
  • set($currency):设置货币。
  • is($currency):检查传递的货币参数是否为当前选定的货币。