| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- <?php
- namespace App\Module\Fund\Services;
- use App\Module\Fund\Dto\CurrencyDto;
- use App\Module\Fund\Enums\FUND_CURRENCY_TYPE;
- use App\Module\Fund\Enums\FUND_TYPE;
- use App\Module\Fund\Models\FundConfigModel;
- use App\Module\Fund\Models\FundCurrencyModel;
- use App\Module\System\Services\ConfigService;
- use Illuminate\Support\Facades\Cache;
- use UCore\Helper\Cache as CacheHelper;
- /**
- * 币种服务类
- *
- * 提供币种相关的服务,包括币种信息获取、币种检查等功能
- */
- class CurrencyService
- {
- /**
- * 缓存时间(秒)
- */
- const CACHE_TTL = 3600;
- /**
- * 检查两个账户的币种是否一致
- *
- * @param int $fund_id 账户种类ID1
- * @param int $fund_id2 账户种类ID2
- * @return bool 是否一致
- */
- static public function check($fund_id, $fund_id2): bool
- {
- // 获取两个账户种类对应的币种
- $currency1 = self::getCurrency2ByFundId($fund_id);
- $currency2 = self::getCurrency2ByFundId($fund_id2);
- // 如果任一币种信息获取失败,返回false
- if (!$currency1 || !$currency2) {
- return false;
- }
- // 检查两个币种ID是否一致(使用币种枚举值,不是数据库表ID)
- return $currency1 === $currency2;
- }
- /**
- * 获取账户种类对应的币种
- *
- * @param int $fund_id 账户种类ID
- * @return CurrencyDto|null 币种信息DTO
- */
- static public function getCurrencyByFundId($fund_id)
- {
- // 获取账户种类对应的币种枚举
- $currencyEnum = self::getCurrency2ByFundId($fund_id);
- if (!$currencyEnum) {
- return null;
- }
- // 通过币种枚举查找对应的数据库记录
- $currency = FundCurrencyModel::where('type', $currencyEnum)->first();
- if (!$currency) {
- return null;
- }
- // 转换为DTO
- return CurrencyDto::fromModel($currency);
- }
- /**
- * 账户转币种
- *
- * @param $fund_id
- * @return \App\Module\Fund\Enums\FUND_CURRENCY_TYPE|null
- */
- static public function getCurrency2ByFundId(int $fund_id)
- {
- return FUND_TYPE::typevalue2Currency($fund_id);
- }
- /**
- * 获取币种配置
- *
- * @param int|null $currency_id 币种ID(FUND_CURRENCY_TYPE枚举值),为null时返回所有币种配置
- * @return CurrencyDto|CurrencyDto[] 币种配置DTO或DTO数组
- */
- public function getConfig($currency_id = null)
- {
- if ($currency_id) {
- // 获取指定币种的配置
- return Cache::remember('currency_config_dto_' . $currency_id, self::CACHE_TTL, function () use ($currency_id) {
- $currencyEnum = FUND_CURRENCY_TYPE::tryFrom($currency_id);
- if (!$currencyEnum) {
- return null;
- }
- $currency = FundCurrencyModel::where('type', $currencyEnum)->first();
- if (!$currency) {
- return null;
- }
- return CurrencyDto::fromModel($currency);
- });
- } else {
- // 获取所有币种的配置
- return Cache::remember('currency_config_dto_all', self::CACHE_TTL, function () {
- $currencies = FundCurrencyModel::all();
- $dtoList = [];
- foreach ($currencies as $currency) {
- $dtoList[] = CurrencyDto::fromModel($currency);
- }
- return $dtoList;
- });
- }
- }
- /**
- * 获取币种名称列表
- *
- * @return array 币种ID => 币种名称
- */
- static public function getValueDesc()
- {
- return CacheHelper::cacheCall([ __CLASS__, __FUNCTION__ ], function () {
- $list = FundCurrencyModel::query()->pluck('name', 'id')->toArray();
- return $list;
- }, [], 10, [ ConfigService::CACHE_TAG ]);
- }
- /**
- * 获取币种标识列表
- *
- * @return array 币种ID => 币种标识
- */
- static public function getIdentifications()
- {
- return CacheHelper::cacheCall([ __CLASS__, __FUNCTION__ ], function () {
- $list = FundCurrencyModel::query()->pluck('identification', 'id')->toArray();
- return $list;
- }, [], 10, [ ConfigService::CACHE_TAG ]);
- }
- /**
- * 获取所有币种列表
- *
- * @param bool $refresh 是否刷新缓存
- * @return CurrencyDto[] 币种DTO列表
- */
- static public function getAllCurrencies($refresh = false)
- {
- $cacheKey = 'all_currencies_dto';
- if ($refresh) {
- Cache::forget($cacheKey);
- }
- return Cache::remember($cacheKey, self::CACHE_TTL, function () {
- $currencies = FundCurrencyModel::all();
- $dtoList = [];
- foreach ($currencies as $currency) {
- $dtoList[] = CurrencyDto::fromModel($currency);
- }
- return $dtoList;
- });
- }
- /**
- * 获取币种的精度
- *
- * @param int $currency_id 币种ID(FUND_CURRENCY_TYPE枚举值)
- * @return int 精度(小数位数)
- */
- static public function getCurrencyPrecision($currency_id)
- {
- // 直接通过币种ID(枚举值)获取精度
- $currencyEnum = FUND_CURRENCY_TYPE::tryFrom($currency_id);
- if (!$currencyEnum) {
- return 2; // 默认精度为2
- }
- // 从枚举中获取精度信息
- return $currencyEnum->getPrecision();
- }
- /**
- * 格式化金额显示
- *
- * @param string|int|float $amount 金额(小数形式)
- * @param int $currency_id 币种ID
- * @return string 格式化后的金额
- */
- static public function formatAmount($amount, $currency_id)
- {
- $precision = self::getCurrencyPrecision($currency_id);
- // 确保金额为数值类型
- $numericAmount = is_string($amount) ? (float)$amount : $amount;
- // 根据币种精度格式化金额
- $formattedAmount = number_format($numericAmount, $precision, '.', ',');
- // 获取币种标识(通过币种ID获取)
- $currencyEnum = FUND_CURRENCY_TYPE::tryFrom($currency_id);
- if ($currencyEnum) {
- // 通过枚举查找对应的数据库记录
- $currency = FundCurrencyModel::where('type', $currencyEnum)->first();
- $symbol = $currency ? $currency->identification : '';
- } else {
- $symbol = '';
- }
- return $symbol . ' ' . $formattedAmount;
- }
- /**
- * 验证金额精度是否符合币种要求
- *
- * @param float $amount 用户输入的金额
- * @param int $currency_id 币种ID
- * @return bool 是否符合精度要求
- */
- static public function validateAmountPrecision($amount, $currency_id)
- {
- $precision = self::getCurrencyPrecision($currency_id);
- // 获取小数部分的位数
- $decimalPart = (string)$amount;
- if (strpos($decimalPart, '.') !== false) {
- $decimalDigits = strlen(substr($decimalPart, strpos($decimalPart, '.') + 1));
- return $decimalDigits <= $precision;
- }
- return true; // 整数总是符合要求
- }
- /**
- * 格式化金额到指定精度
- *
- * @param float $amount 金额
- * @param int $currency_id 币种ID
- * @return float 格式化后的金额
- */
- static public function formatAmountToPrecision($amount, $currency_id)
- {
- $precision = self::getCurrencyPrecision($currency_id);
- return round($amount, $precision);
- }
- }
|