diff --git a/beike/Helpers.php b/beike/Helpers.php index 45b73a53..8e6c14ad 100644 --- a/beike/Helpers.php +++ b/beike/Helpers.php @@ -3,6 +3,8 @@ use Beike\Models\Customer; use Beike\Models\AdminUser; use Beike\Repositories\LanguageRepo; +use Beike\Services\CurrencyService; +use Illuminate\Support\Facades\Session; use Illuminate\Support\Str; use TorMorten\Eventy\Facades\Eventy; use Illuminate\Support\Facades\Route; @@ -195,9 +197,12 @@ function locale(): string * @param $price * @return string */ -function currency_format($price): string +function currency_format($price, $currency = '', $value = '', $format = true): string { - return '$' . number_format($price, 2); + if (!$currency) { + $currency = Session::get('currency') ?? system_setting('base.currency'); + } + return CurrencyService::getInstance()->format($price, $currency, $value, $format); } /** diff --git a/beike/Repositories/CurrencyRepo.php b/beike/Repositories/CurrencyRepo.php index f32714dc..63af0455 100644 --- a/beike/Repositories/CurrencyRepo.php +++ b/beike/Repositories/CurrencyRepo.php @@ -66,4 +66,10 @@ class CurrencyRepo { return Currency::query()->get(); } + + public static function enabled() + { + return Currency::query()->where('status', true)->get(); + } + } diff --git a/beike/Repositories/SystemSettingRepo.php b/beike/Repositories/SystemSettingRepo.php index 144dd6d8..c8330e5e 100644 --- a/beike/Repositories/SystemSettingRepo.php +++ b/beike/Repositories/SystemSettingRepo.php @@ -43,6 +43,18 @@ class SystemSettingRepo 'value' => old('locale', system_setting('base.locale', 'zh_cn')), 'description' => '默认语言设置', ], + [ + 'name' => 'currency', + 'label' => '默认货币', + 'type' => 'select', + 'required' => true, + 'options' => [ + ['value' => 'CNY', 'label' => '人民币'], + ['value' => 'USD', 'label' => '美元'] + ], + 'value' => old('currency', system_setting('base.currency', 'USD')), + 'description' => '默认货币设置', + ], [ 'name' => 'admin_name', 'label' => '后台目录', diff --git a/beike/Services/CurrencyService.php b/beike/Services/CurrencyService.php index 76cb072d..54feb664 100644 --- a/beike/Services/CurrencyService.php +++ b/beike/Services/CurrencyService.php @@ -1,12 +1,12 @@ - * @created 2022-07-21 16:29:54 - * @modified 2022-07-21 16:29:54 + * @author TL + * @created 2022-07-28 16:29:54 + * @modified 2022-07-28 16:29:54 */ namespace Beike\Services; @@ -14,195 +14,78 @@ namespace Beike\Services; use Beike\Models\Address; use Beike\Models\TaxRate; use Beike\Models\TaxRule; +use Beike\Repositories\CurrencyRepo; -class TaxService +class CurrencyService { - private $taxRates = array(); - private static $taxRules; + private static $instance; + private $currencies = array(); - const AVAILABLE_TYPES = ['shipping', 'payment', 'store']; - - public function __construct($data = array()) - { - $countryId = system_setting('base.config_country_id'); - $zoneId = system_setting('base.config_zone_id'); - - $shippingAddress = $data['shipping_address'] ?? null; - $paymentAddress = $data['payment_address'] ?? null; - - if ($shippingAddress) { - if ($shippingAddress instanceof Address) { - $this->setShippingAddress($shippingAddress->country_id, $shippingAddress->zone_id); - } elseif ($shippingAddress instanceof \ArrayObject) { - $this->setShippingAddress($countryId, $zoneId); - } else { - $this->setShippingAddress($shippingAddress['country_id'], $shippingAddress['zone_id']); - } - } elseif (system_setting('base.config_tax_default') == 'shipping') { - $this->setShippingAddress($countryId, $zoneId); - } - - if ($paymentAddress) { - if ($paymentAddress instanceof Address) { - $this->setPaymentAddress($paymentAddress->country_id, $paymentAddress->zone_id); - } elseif ($paymentAddress instanceof \ArrayObject) { - $this->setShippingAddress($countryId, $zoneId); - } else { - $this->setPaymentAddress($paymentAddress['country_id'], $paymentAddress['zone_id']); - } - } elseif (system_setting('base.config_tax_default') == 'payment') { - $this->setPaymentAddress($countryId, $zoneId); - } - - $this->setStoreAddress($countryId, $zoneId); - } - - public static function getInstance($data = array()) - { - return new self($data); - } - - private function getTaxRules($type, $countryId, $zoneId) - { - if (self::$taxRules !== null && isset(self::$taxRules["$type-$countryId-$zoneId"])) { - return self::$taxRules["$type-$countryId-$zoneId"]; - } - - $customerGroupId = (int)system_setting('base.config_customer_group_id'); - $sqlBuilder = TaxRule::query() - ->leftJoin('tax_rate', 'tax_rule.tax_rate_id', '=', 'tax_rate.tax_rate_id') - ->join('tax_rate_to_customer_group', 'tax_rate.tax_rate_id', '=', 'tax_rate_to_customer_group.tax_rate_id') - ->leftJoin('zone_to_geo_zone', 'tax_rate.geo_zone_id', '=', 'zone_to_geo_zone.geo_zone_id') - ->leftJoin('geo_zone', 'tax_rate.geo_zone_id', '=', 'geo_zone.geo_zone_id') - ->select('tax_rule.*', 'tax_rate.*') - ->where('tax_rule.based', $type) - ->where('tax_rate_to_customer_group.customer_group_id', $customerGroupId) - ->where('zone_to_geo_zone.country_id', $countryId) - ->where(function ($query) use ($zoneId) { - $query->where('zone_to_geo_zone.zone_id', '=', 0) - ->orWhere('zone_to_geo_zone.zone_id', '=', (int)$zoneId); - }) - ->orderBy('tax_rule.priority'); - $data = $sqlBuilder->get(); - self::$taxRules["$type-$countryId-$zoneId"] = $data; - return $data; - } - - private function setAddress($type, $countryId, $zoneId) - { - if (!in_array($type, self::AVAILABLE_TYPES)) { - throw new \Exception('invalid tax types'); - } - - $data = $this->getTaxRules($type, $countryId, $zoneId); - - foreach ($data as $result) { - $this->taxRates[$result->tax_class_id][$result->tax_rate_id] = array( - 'tax_rate_id' => $result->tax_rate_id, - 'name' => $result->name, - 'rate' => $result->rate, - 'type' => $result->type, - 'priority' => $result->priority - ); + public function __construct() { + foreach (CurrencyRepo::enabled() as $result) { + $this->currencies[$result->code] = $result; } } - public function unsetRates() + public static function getInstance() { - $this->taxRates = array(); + if (!self::$instance) { + self::$instance = new self(); + } + return self::$instance; } - public function setShippingAddress($countryId, $zoneId) + public function format($amount, $currency, $value = '', $format = true) { - $this->setAddress('shipping', $countryId, $zoneId); + $symbol_left = $this->currencies[$currency]->symbol_left; + $symbol_right = $this->currencies[$currency]->symbol_right; + $decimal_place = $this->currencies[$currency]->decimal_place; + + if (!$value) { + $value = $this->currencies[$currency]->value; + } + + $amount = $value ? (float)$amount * $value : (float)$amount; + + $amount = round($amount, (int)$decimal_place); + + if (!$format) { + return $amount; + } + + $string = ''; + if ($amount < 0) { + $string = '-'; + } + + if ($symbol_left) { + $string .= $symbol_left; + } + + $string .= number_format(abs($amount), (int)$decimal_place, __('currency.decimal_point'), __('currency.thousand_point')); + + if ($symbol_right) { + $string .= $symbol_right; + } + + return $string; } - public function setPaymentAddress($countryId, $zoneId) - { - $this->setAddress('payment', $countryId, $zoneId); - } - public function setStoreAddress($countryId, $zoneId) - { - $this->setAddress('store', $countryId, $zoneId); - } - - /** - * $tax = \App\Models\Library\Tax::getInstance(); - * $tax->setShippingAddress(1, 0); - * $tax->calculate(123.45, 9, $tax->config->getValue('config_tax')) - * - * @param $value - * @param $taxClassId - * @param bool|true $calculate - * @return mixed - */ - public function calculate($value, $taxClassId, bool $calculate = true) - { - if ($taxClassId && $calculate) { - $amount = 0; - $taxRates = $this->getRates($value, $taxClassId); - foreach ($taxRates as $taxRate) { - if ($calculate != 'P' && $calculate != 'F') { - $amount += $taxRate['amount']; - } elseif ($taxRate['type'] == $calculate) { - $amount += $taxRate['amount']; - } - } - return $value + $amount; + public function convert($value, $from, $to) { + if (isset($this->currencies[$from])) { + $from = $this->currencies[$from]->value; } else { - return $value; + $from = 1; } - } - public function getTax($value, $taxClassId) - { - $amount = 0; - $taxRates = $this->getRates($value, $taxClassId); - foreach ($taxRates as $taxRate) { - $amount += $taxRate['amount']; - } - return $amount; - } - - public function getRateName($taxRateId) - { - $taxRate = TaxRate::query()->find($taxRateId); - if ($taxRate) { - return $taxRate->name; + if (isset($this->currencies[$to])) { + $to = $this->currencies[$to]->value; } else { - return false; - } - } - - public function getRates($value, $taxClassId) - { - $taxRateData = array(); - - if (isset($this->taxRates[$taxClassId])) { - foreach ($this->taxRates[$taxClassId] as $taxRate) { - if (isset($taxRateData[$taxRate['tax_rate_id']])) { - $amount = $taxRateData[$taxRate['tax_rate_id']]['amount']; - } else { - $amount = 0; - } - - if ($taxRate['type'] == 'F') { - $amount += $taxRate['rate']; - } elseif ($taxRate['type'] == 'P') { - $amount += ($value / 100 * $taxRate['rate']); - } - - $taxRateData[$taxRate['tax_rate_id']] = array( - 'tax_rate_id' => $taxRate['tax_rate_id'], - 'name' => $taxRate['name'], - 'rate' => $taxRate['rate'], - 'type' => $taxRate['type'], - 'amount' => $amount - ); - } + $to = 1; } - return $taxRateData; + return $value * ($to / $from); } + } diff --git a/beike/Shop/Http/Controllers/LanguageController.php b/beike/Shop/Http/Controllers/LanguageController.php index 2ea388f2..74e8fdbd 100644 --- a/beike/Shop/Http/Controllers/LanguageController.php +++ b/beike/Shop/Http/Controllers/LanguageController.php @@ -11,7 +11,7 @@ namespace Beike\Shop\Http\Controllers; -use Beike\Repositories\LanguageRepo; +use Illuminate\Support\Facades\Session; class LanguageController extends Controller { diff --git a/resources/lang/en/currency.php b/resources/lang/en/currency.php new file mode 100644 index 00000000..7e31abd4 --- /dev/null +++ b/resources/lang/en/currency.php @@ -0,0 +1,15 @@ + + * @created 2022-07-28 17:21:38 + * @modified 2022-07-28 17:21:38 + */ +return [ + 'decimal_point' => '.', + 'thousand_point' => ',', + +]; diff --git a/resources/lang/zh-CN/currency.php b/resources/lang/zh-CN/currency.php new file mode 100644 index 00000000..7e31abd4 --- /dev/null +++ b/resources/lang/zh-CN/currency.php @@ -0,0 +1,15 @@ + + * @created 2022-07-28 17:21:38 + * @modified 2022-07-28 17:21:38 + */ +return [ + 'decimal_point' => '.', + 'thousand_point' => ',', + +];