Currency.php 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. public function init()
  56. {
  57. parent::init();
  58. // init default and base currency
  59. $this->defaultCurrency = Yii::$app->store->get('base_info', 'default_currency');
  60. $this->baseCurrecy = Yii::$app->store->get('base_info', 'base_currency');
  61. // init all currency
  62. $currencys = Yii::$app->store->get('currency');
  63. if (is_array($currencys)) {
  64. foreach ($currencys as $currency) {
  65. $currency_code = $currency['currency_code'];
  66. $currency_symbol = $currency['currency_symbol'];
  67. $currency_rate = $currency['currency_rate'];
  68. $this->currencys[$currency_code] = [
  69. 'rate' => $currency_rate,
  70. 'symbol' => $currency_symbol
  71. ];
  72. }
  73. }
  74. }
  75. /**
  76. * @param $currencyCode | string 货币简码,譬如USD,RMB等
  77. * @return array
  78. * 如果不传递参数,得到所有的货币
  79. * 如果传递参数,得到的是当前货币的信息。
  80. */
  81. protected function actionGetCurrencys($currencyCode = '')
  82. {
  83. if (!$this->_currencys) {
  84. foreach ($this->currencys as $code => $info) {
  85. $this->_currencys[$code] = [
  86. 'code' => $code,
  87. 'rate' => $info['rate'],
  88. 'symbol' => $info['symbol'],
  89. ];
  90. }
  91. }
  92. if ($currencyCode) {
  93. if (isset($this->_currencys[$currencyCode])) {
  94. return $this->_currencys[$currencyCode];
  95. } else {
  96. $currencyCode = $this->defaultCurrency;
  97. return $this->_currencys[$currencyCode];
  98. }
  99. }
  100. return $this->_currencys;
  101. }
  102. /**
  103. * 得到当前货币的符号,譬如¥ $ 等。
  104. * 如果当前的货币在配置中找不到,则会强制改成默认货币
  105. */
  106. protected function actionGetCurrentSymbol()
  107. {
  108. if (isset($this->currencys[$this->getCurrentCurrency()]['symbol'])) {
  109. return $this->currencys[$this->getCurrentCurrency()]['symbol'];
  110. }
  111. }
  112. /**
  113. * @param $currencyCode | 货币简码
  114. * 得到货币的符号,譬如¥ $ 等。
  115. */
  116. protected function actionGetSymbol($currencyCode)
  117. {
  118. if (isset($this->currencys[$currencyCode]['symbol'])) {
  119. return $this->currencys[$currencyCode]['symbol'];
  120. }
  121. }
  122. /**
  123. * property $price|Float ,默认货币的价格
  124. * Get current currency price. price format is two decimal places,
  125. * if current currency is not find in object variable $currencys(maybe change config in online shop,but current user session is effective),
  126. * current currency will set defaultCurrency, origin price will be return.
  127. * 通过传递默认货币的价格,得到当前货币的价格。
  128. */
  129. protected function actionGetCurrentCurrencyPrice($price)
  130. {
  131. $currencyCode = $this->getCurrentCurrency();
  132. $currencyPrice = $this->getCurrencyPrice($price, $currencyCode);
  133. if ($currencyPrice) {
  134. return $currencyPrice;
  135. }
  136. /*
  137. * 如果上面出现错误,当前的货币在货币配置中找不到,则会使用默认货币
  138. * 这种情况可能出现在货币配置调整的过程中,找不到则会被强制改成默认货币。
  139. */
  140. $this->setCurrentCurrency($this->baseCurrecy);
  141. return $price;
  142. }
  143. /**
  144. * property $price|Float ,默认货币的价格
  145. * property $currencyCode|String,货币简码,譬如 USD
  146. * 根据基础货币,得到相应货币的价格
  147. */
  148. protected function actionGetCurrencyPrice($price, $currencyCode)
  149. {
  150. if (isset($this->currencys[$currencyCode]['rate'])) {
  151. $rate = $this->currencys[$currencyCode]['rate'];
  152. if ($rate) {
  153. return bcmul($price, $rate, 2);
  154. }
  155. }
  156. }
  157. /**
  158. * @param $current_price | Float 当前货币下的价格
  159. * @return 基础货币下的价格
  160. * 通过当前的货币价格得到基础货币的价格,这是一个反推的过程,
  161. * 需要特别注意的是:这种反推方法换算得到的基础货币的价格,和原来的基础货币价格,
  162. * 可能有0.01的误差,因为默认货币换算成当前货币的算法为小数点后两位进一法得到的。
  163. */
  164. protected function actionGetBaseCurrencyPrice($current_price, $current_currency = '')
  165. {
  166. if (!$current_currency) {
  167. $current_currency = $this->getCurrentCurrency();
  168. }
  169. if (isset($this->currencys[$current_currency]['rate'])) {
  170. $rate = $this->currencys[$current_currency]['rate'];
  171. if ($rate) {
  172. return bcdiv($current_price, $rate, 2);
  173. }
  174. }
  175. }
  176. /**
  177. * @param $currencyCode | 货币简码
  178. * 初始化货币信息,在service Store bootstrap(Yii::$app->store->bootstrap()), 中会被调用
  179. * 1. 如果 $this->defaultCurrency 和 $this->baseCurrecy 没有设置,将会报错。
  180. * 2. 如果 传递参数$currencyCode为空,则会使用默认货币
  181. */
  182. protected function actionInitCurrency($currencyCode = '')
  183. {
  184. if (!$this->defaultCurrency) {
  185. throw new InvalidConfigException('defautlt currency must config');
  186. }
  187. if (!$this->baseCurrecy) {
  188. throw new InvalidConfigException('base currency must config');
  189. }
  190. if (!$this->getCurrentCurrency()) {
  191. if (!$currencyCode) {
  192. $currencyCode = $this->defaultCurrency;
  193. }
  194. $this->setCurrentCurrency($currencyCode);
  195. }
  196. }
  197. /**
  198. * @param $currencyCode | String , 货币简码,如果参数$currencyCode为空,则取当前的货币简码
  199. * @return array
  200. * 得到货币的详细信息,数据格式如下:
  201. * [
  202. * 'code' => $code ,
  203. * 'rate' => $rate ,
  204. * 'symbol' => $symbol ,
  205. * ]
  206. */
  207. protected function actionGetCurrencyInfo($currencyCode = '')
  208. {
  209. if (!$currencyCode) {
  210. $currencyCode = $this->getCurrentCurrency();
  211. }
  212. return $this->getCurrencys($currencyCode);
  213. }
  214. /**
  215. * 得到当前的货币。
  216. */
  217. protected function actionGetCurrentCurrency()
  218. {
  219. if (!$this->_currentCurrencyCode) {
  220. $this->_currentCurrencyCode = Yii::$service->session->get(self::CURRENCY_CURRENT);
  221. }
  222. return $this->_currentCurrencyCode;
  223. }
  224. /**
  225. * @param $currencyCode | String, 当前的货币简码
  226. * 设置当前的货币。
  227. */
  228. protected function actionSetCurrentCurrency($currencyCode)
  229. {
  230. if (!$this->isCorrectCurrency($currencyCode)) {
  231. $currencyCode = $this->defaultCurrency;
  232. }
  233. if ($currencyCode) {
  234. Yii::$service->session->set(self::CURRENCY_CURRENT, $currencyCode);
  235. $this->_currentCurrencyCode = $currencyCode;
  236. return true;
  237. }
  238. }
  239. /**
  240. * @param $currency | String 货币简码
  241. * @return bool
  242. * 检测当前传递的货币简码,是否在配置中存在,如果存在则返回true
  243. */
  244. protected function isCorrectCurrency($currencyCode)
  245. {
  246. if (isset($this->currencys[$currencyCode])) {
  247. return true;
  248. } else {
  249. return false;
  250. }
  251. }
  252. public function setCurrentCurrency2CNY()
  253. {
  254. return $this->setCurrentCurrency('CNY');
  255. }
  256. }