CurrencyService.php 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <?php
  2. namespace App\Module\Fund\Services;
  3. use App\Module\Fund\Dto\CurrencyDto;
  4. use App\Module\Fund\Models\FundConfigModel;
  5. use App\Module\Fund\Models\FundCurrencyModel;
  6. use App\Module\System\Services\ConfigService;
  7. use Illuminate\Support\Facades\Cache;
  8. use UCore\Helper\Cache as CacheHelper;
  9. /**
  10. * 币种服务类
  11. *
  12. * 提供币种相关的服务,包括币种信息获取、币种检查等功能
  13. */
  14. class CurrencyService
  15. {
  16. /**
  17. * 缓存时间(秒)
  18. */
  19. const CACHE_TTL = 3600;
  20. /**
  21. * 检查两个账户的币种是否一致
  22. *
  23. * @param int $fund_id 账户种类ID1
  24. * @param int $fund_id2 账户种类ID2
  25. * @return bool 是否一致
  26. */
  27. static public function check($fund_id, $fund_id2): bool
  28. {
  29. // 获取两个账户种类对应的币种
  30. $currency1 = self::getCurrencyByFundId($fund_id);
  31. $currency2 = self::getCurrencyByFundId($fund_id2);
  32. // 如果任一币种信息获取失败,返回false
  33. if (!$currency1 || !$currency2) {
  34. return false;
  35. }
  36. // 检查两个币种ID是否一致
  37. return $currency1->id === $currency2->id;
  38. }
  39. /**
  40. * 获取账户种类对应的币种
  41. *
  42. * @param int $fund_id 账户种类ID
  43. * @return CurrencyDto|null 币种信息DTO
  44. */
  45. static public function getCurrencyByFundId($fund_id)
  46. {
  47. // 获取账户种类信息
  48. $fundConfig = FundConfigModel::find($fund_id);
  49. if (!$fundConfig) {
  50. return null;
  51. }
  52. // 从账户种类信息中获取币种ID
  53. $currencyId = $fundConfig->currency_id ?? null;
  54. if (!$currencyId) {
  55. return null;
  56. }
  57. // 获取币种信息
  58. $currency = FundCurrencyModel::find($currencyId);
  59. if (!$currency) {
  60. return null;
  61. }
  62. // 转换为DTO
  63. return CurrencyDto::fromModel($currency);
  64. }
  65. /**
  66. * 获取币种配置
  67. *
  68. * @param int|null $currency_id 币种ID,为null时返回所有币种配置
  69. * @return CurrencyDto|CurrencyDto[] 币种配置DTO或DTO数组
  70. */
  71. public function getConfig($currency_id = null)
  72. {
  73. if ($currency_id) {
  74. // 获取指定币种的配置
  75. return Cache::remember('currency_config_dto_' . $currency_id, self::CACHE_TTL, function () use ($currency_id) {
  76. $currency = FundCurrencyModel::find($currency_id);
  77. if (!$currency) {
  78. return null;
  79. }
  80. return CurrencyDto::fromModel($currency);
  81. });
  82. } else {
  83. // 获取所有币种的配置
  84. return Cache::remember('currency_config_dto_all', self::CACHE_TTL, function () {
  85. $currencies = FundCurrencyModel::all();
  86. $dtoList = [];
  87. foreach ($currencies as $currency) {
  88. $dtoList[] = CurrencyDto::fromModel($currency);
  89. }
  90. return $dtoList;
  91. });
  92. }
  93. }
  94. /**
  95. * 获取币种名称列表
  96. *
  97. * @return array 币种ID => 币种名称
  98. */
  99. static public function getValueDesc()
  100. {
  101. return CacheHelper::cacheCall([__CLASS__, __FUNCTION__], function () {
  102. $list = FundCurrencyModel::query()->pluck('name', 'id')->toArray();
  103. return $list;
  104. }, [], 10, [ConfigService::CACHE_TAG]);
  105. }
  106. /**
  107. * 获取币种标识列表
  108. *
  109. * @return array 币种ID => 币种标识
  110. */
  111. static public function getIdentifications()
  112. {
  113. return CacheHelper::cacheCall([__CLASS__, __FUNCTION__], function () {
  114. $list = FundCurrencyModel::query()->pluck('identification', 'id')->toArray();
  115. return $list;
  116. }, [], 10, [ConfigService::CACHE_TAG]);
  117. }
  118. /**
  119. * 根据币种标识获取币种信息
  120. *
  121. * @param string $identification 币种标识
  122. * @return CurrencyDto|null 币种信息DTO
  123. */
  124. static public function getCurrencyByIdentification($identification)
  125. {
  126. return Cache::remember('currency_dto_by_identification_' . $identification, self::CACHE_TTL, function () use ($identification) {
  127. $currency = FundCurrencyModel::where('identification', $identification)->first();
  128. if (!$currency) {
  129. return null;
  130. }
  131. return CurrencyDto::fromModel($currency);
  132. });
  133. }
  134. /**
  135. * 获取所有币种列表
  136. *
  137. * @param bool $refresh 是否刷新缓存
  138. * @return CurrencyDto[] 币种DTO列表
  139. */
  140. static public function getAllCurrencies($refresh = false)
  141. {
  142. $cacheKey = 'all_currencies_dto';
  143. if ($refresh) {
  144. Cache::forget($cacheKey);
  145. }
  146. return Cache::remember($cacheKey, self::CACHE_TTL, function () {
  147. $currencies = FundCurrencyModel::all();
  148. $dtoList = [];
  149. foreach ($currencies as $currency) {
  150. $dtoList[] = CurrencyDto::fromModel($currency);
  151. }
  152. return $dtoList;
  153. });
  154. }
  155. /**
  156. * 获取币种的精度
  157. *
  158. * @param int $currency_id 币种ID
  159. * @return int 精度(小数位数)
  160. */
  161. static public function getCurrencyPrecision($currency_id)
  162. {
  163. $currency = FundCurrencyModel::find($currency_id);
  164. if (!$currency) {
  165. return 2; // 默认精度为2
  166. }
  167. // 从data1字段中获取精度信息
  168. if (!empty($currency->data1)) {
  169. $data = json_decode($currency->data1, true);
  170. if (isset($data['precision'])) {
  171. return (int)$data['precision'];
  172. }
  173. }
  174. return 2; // 默认精度为2
  175. }
  176. /**
  177. * 格式化金额显示
  178. *
  179. * @param int $amount 金额(整数形式)
  180. * @param int $currency_id 币种ID
  181. * @return string 格式化后的金额
  182. */
  183. static public function formatAmount($amount, $currency_id)
  184. {
  185. $precision = self::getCurrencyPrecision($currency_id);
  186. $divisor = pow(10, $precision);
  187. // 将整数形式的金额转换为带小数的形式
  188. $formattedAmount = number_format($amount / $divisor, $precision, '.', ',');
  189. // 获取币种标识
  190. $currency = FundCurrencyModel::find($currency_id);
  191. $symbol = $currency ? $currency->identification : '';
  192. return $symbol . ' ' . $formattedAmount;
  193. }
  194. /**
  195. * 将用户输入的金额转换为系统存储的整数形式
  196. *
  197. * @param float $amount 用户输入的金额
  198. * @param int $currency_id 币种ID
  199. * @return int 系统存储的整数形式金额
  200. */
  201. static public function convertToStorageAmount($amount, $currency_id)
  202. {
  203. $precision = self::getCurrencyPrecision($currency_id);
  204. $multiplier = pow(10, $precision);
  205. return (int)round($amount * $multiplier);
  206. }
  207. /**
  208. * 将系统存储的整数形式金额转换为实际金额
  209. *
  210. * @param int $storageAmount 系统存储的整数形式金额
  211. * @param int $currency_id 币种ID
  212. * @return float 实际金额
  213. */
  214. static public function convertFromStorageAmount($storageAmount, $currency_id)
  215. {
  216. $precision = self::getCurrencyPrecision($currency_id);
  217. $divisor = pow(10, $precision);
  218. return $storageAmount / $divisor;
  219. }
  220. }