Currency.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /*
  3. * FecShop file.
  4. *
  5. * @link http://www.fecshop.com/
  6. * @copyright Copyright (c) 2016 FecShop Software LLC
  7. * @license http://www.fecshop.com/license/
  8. */
  9. namespace fecshop\services\page;
  10. use fecshop\services\Service;
  11. use Yii;
  12. use yii\base\InvalidConfigException;
  13. /**
  14. * Page Currency services 货币部分
  15. * @author Terry Zhao <2358269014@qq.com>
  16. * @since 1.0
  17. */
  18. class Currency extends Service
  19. {
  20. const CURRENCY_CURRENT = 'currency_current';
  21. /**
  22. * 该变量用于:在配置文件中,配置所有的货币参数。
  23. * 格式如下:
  24. * [
  25. * 'USD' => [
  26. * 'rate' => 1,
  27. * 'symbol' => '$',
  28. * ],
  29. * 'RMB' => [
  30. * 'rate' => 6.3,
  31. * 'symbol' => 'гд',
  32. * ],
  33. * ].
  34. */
  35. public $currencys;
  36. /**
  37. * 基础货币,产品的价格,填写的都是基础货币的价格。
  38. * 该值需要在配置文件中进行配置.
  39. */
  40. public $baseCurrecy;
  41. /**
  42. * 网站的默认货币,需要注意的是,默认货币不要和基础货币混淆,举例:
  43. * 后台产品统一使用的美元填写产品价格,但是我的网站前端的默认货币为人民币。
  44. * 该值需要在配置文件中进行配置.
  45. */
  46. public $defaultCurrency = 'USD';
  47. /**
  48. * 当前的货币简码
  49. */
  50. protected $_currentCurrencyCode;
  51. /**
  52. * 根据配置,保存所有货币的配置信息。
  53. */
  54. protected $_currencys;
  55. /**
  56. * @param $currencyCode | string 货币简码,譬如USD,RMB等
  57. * @return array
  58. * 如果不传递参数,得到所有的货币
  59. * 如果传递参数,得到的是当前货币的信息。
  60. */
  61. protected function actionGetCurrencys($currencyCode = '')
  62. {
  63. if (!$this->_currencys) {
  64. foreach ($this->currencys as $code => $info) {
  65. $this->_currencys[$code] = [
  66. 'code' => $code,
  67. 'rate' => $info['rate'],
  68. 'symbol' => $info['symbol'],
  69. ];
  70. }
  71. }
  72. if ($currencyCode) {
  73. return $this->_currencys[$currencyCode];
  74. }
  75. return $this->_currencys;
  76. }
  77. /**
  78. * 得到当前货币的符号,譬如¥ $ 等。
  79. * 如果当前的货币在配置中找不到,则会强制改成默认货币
  80. */
  81. protected function actionGetCurrentSymbol()
  82. {
  83. if (isset($this->currencys[$this->getCurrentCurrency()]['symbol'])) {
  84. return $this->currencys[$this->getCurrentCurrency()]['symbol'];
  85. }
  86. }
  87. /**
  88. * @param $currencyCode | 货币简码
  89. * 得到货币的符号,譬如¥ $ 等。
  90. */
  91. protected function actionGetSymbol($currencyCode)
  92. {
  93. if (isset($this->currencys[$currencyCode]['symbol'])) {
  94. return $this->currencys[$currencyCode]['symbol'];
  95. }
  96. }
  97. /**
  98. * property $price|Float ,默认货币的价格
  99. * Get current currency price. price format is two decimal places,
  100. * if current currency is not find in object variable $currencys(maybe change config in online shop,but current user session is effective),
  101. * current currency will set defaultCurrency, origin price will be return.
  102. * 通过传递默认货币的价格,得到当前货币的价格。
  103. */
  104. protected function actionGetCurrentCurrencyPrice($price)
  105. {
  106. $currencyCode = $this->getCurrentCurrency();
  107. $currencyPrice = $this->getCurrencyPrice($price, $currencyCode);
  108. if ($currencyPrice) {
  109. return $currencyPrice;
  110. }
  111. /*
  112. * 如果上面出现错误,当前的货币在货币配置中找不到,则会使用默认货币
  113. * 这种情况可能出现在货币配置调整的过程中,找不到则会被强制改成默认货币。
  114. */
  115. $this->setCurrentCurrency($this->baseCurrecy);
  116. return $price;
  117. }
  118. /**
  119. * property $price|Float ,默认货币的价格
  120. * property $currencyCode|String,货币简码,譬如 USD
  121. * 根据基础货币,得到相应货币的价格
  122. */
  123. protected function actionGetCurrencyPrice($price, $currencyCode)
  124. {
  125. if (isset($this->currencys[$currencyCode]['rate'])) {
  126. $rate = $this->currencys[$currencyCode]['rate'];
  127. if ($rate) {
  128. return bcmul($price, $rate, 2);
  129. }
  130. }
  131. }
  132. /**
  133. * @param $current_price | Float 当前货币下的价格
  134. * @return 基础货币下的价格
  135. * 通过当前的货币价格得到基础货币的价格,这是一个反推的过程,
  136. * 需要特别注意的是:这种反推方法换算得到的基础货币的价格,和原来的基础货币价格,
  137. * 可能有0.01的误差,因为默认货币换算成当前货币的算法为小数点后两位进一法得到的。
  138. */
  139. protected function actionGetBaseCurrencyPrice($current_price, $current_currency = '')
  140. {
  141. if (!$current_currency) {
  142. $current_currency = $this->getCurrentCurrency();
  143. }
  144. if (isset($this->currencys[$current_currency]['rate'])) {
  145. $rate = $this->currencys[$current_currency]['rate'];
  146. if ($rate) {
  147. return bcdiv($current_price, $rate, 2);
  148. }
  149. }
  150. }
  151. /**
  152. * @param $currencyCode | 货币简码
  153. * 初始化货币信息,在service Store bootstrap(Yii::$app->store->bootstrap()), 中会被调用
  154. * 1. 如果 $this->defaultCurrency 和 $this->baseCurrecy 没有设置,将会报错。
  155. * 2. 如果 传递参数$currencyCode为空,则会使用默认货币
  156. */
  157. protected function actionInitCurrency($currencyCode = '')
  158. {
  159. if (!$this->defaultCurrency) {
  160. throw new InvalidConfigException('defautlt currency must config');
  161. }
  162. if (!$this->baseCurrecy) {
  163. throw new InvalidConfigException('base currency must config');
  164. }
  165. if (!$this->getCurrentCurrency()) {
  166. if (!$currencyCode) {
  167. $currencyCode = $this->defaultCurrency;
  168. }
  169. $this->setCurrentCurrency($currencyCode);
  170. }
  171. }
  172. /**
  173. * @param $currencyCode | String , 货币简码,如果参数$currencyCode为空,则取当前的货币简码
  174. * @return array
  175. * 得到货币的详细信息,数据格式如下:
  176. * [
  177. * 'code' => $code ,
  178. * 'rate' => $rate ,
  179. * 'symbol' => $symbol ,
  180. * ]
  181. */
  182. protected function actionGetCurrencyInfo($currencyCode = '')
  183. {
  184. if (!$currencyCode) {
  185. $currencyCode = $this->getCurrentCurrency();
  186. }
  187. return $this->getCurrencys($currencyCode);
  188. }
  189. /**
  190. * 得到当前的货币。
  191. */
  192. protected function actionGetCurrentCurrency()
  193. {
  194. if (!$this->_currentCurrencyCode) {
  195. $this->_currentCurrencyCode = Yii::$service->session->get(self::CURRENCY_CURRENT);
  196. }
  197. return $this->_currentCurrencyCode;
  198. }
  199. /**
  200. * @param $currencyCode | String, 当前的货币简码
  201. * 设置当前的货币。
  202. */
  203. protected function actionSetCurrentCurrency($currencyCode)
  204. {
  205. if (!$this->isCorrectCurrency($currencyCode)) {
  206. $currencyCode = $this->defaultCurrency;
  207. }
  208. if ($currencyCode) {
  209. Yii::$service->session->set(self::CURRENCY_CURRENT, $currencyCode);
  210. $this->_currentCurrencyCode = $currencyCode;
  211. return true;
  212. }
  213. }
  214. /**
  215. * @param $currency | String 货币简码
  216. * @return bool
  217. * 检测当前传递的货币简码,是否在配置中存在,如果存在则返回true
  218. */
  219. protected function isCorrectCurrency($currencyCode)
  220. {
  221. if (isset($this->currencys[$currencyCode])) {
  222. return true;
  223. } else {
  224. return false;
  225. }
  226. }
  227. public function setCurrentCurrency2CNY()
  228. {
  229. return $this->setCurrentCurrency('CNY');
  230. }
  231. }