PriceService.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | LARAVEL8.0 框架 [ LARAVEL ][ RXThinkCMF ]
  4. // +----------------------------------------------------------------------
  5. // | 版权所有 2017~2021 LARAVEL研发中心
  6. // +----------------------------------------------------------------------
  7. // | 官方网站: http://www.laravel.cn
  8. // +----------------------------------------------------------------------
  9. // | Author: laravel开发员 <laravel.qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace App\Services\Api;
  12. use App\Models\AccountLogModel;
  13. use App\Models\MemberModel;
  14. use App\Models\NoticeModel;
  15. use App\Models\PriceModel;
  16. use App\Models\PtAccountModel;
  17. use App\Services\BaseService;
  18. use App\Services\RedisService;
  19. use Illuminate\Support\Facades\DB;
  20. /**
  21. * 价格服务-服务类
  22. * @author laravel开发员
  23. * @since 2020/11/11
  24. * @package App\Services\Api
  25. */
  26. class PriceService extends BaseService
  27. {
  28. // 静态对象
  29. protected static $instance = null;
  30. /**
  31. * 构造函数
  32. * @author laravel开发员
  33. * @since 2020/11/11
  34. * NoticeService constructor.
  35. */
  36. public function __construct()
  37. {
  38. $this->model = new PriceModel();
  39. }
  40. /**
  41. * 静态入口
  42. */
  43. public static function make()
  44. {
  45. if (!self::$instance) {
  46. self::$instance = new static();
  47. }
  48. return self::$instance;
  49. }
  50. /**
  51. * 当前价格
  52. * @param int $type 1-数字资产,2-绿色积分
  53. * @param false $refresh
  54. * @return array|mixed|string
  55. */
  56. public function getTodayPrice($type=1, $refresh=false)
  57. {
  58. $cacheKey = "caches:prices:today_price_{$type}";
  59. $data = RedisService::get($cacheKey);
  60. $price = isset($data['price'])?$data['price']: '0.00';
  61. if($data && $price && !$refresh){
  62. return floatval($price);
  63. }
  64. $data = $this->model->where(['type'=>$type,'status'=>1,'mark'=>1])
  65. ->orderBy('date','desc')
  66. ->first();
  67. $data = $data?$data->toArray() : [];
  68. $price = isset($data['price'])?$data['price']: '0.00';
  69. if($data && $price){
  70. RedisService::set($cacheKey, $data, rand(300,600));
  71. }
  72. return floatval($price);
  73. }
  74. /**
  75. * 是否已经更新过
  76. * @param $date
  77. * @param int $type
  78. * @return array|bool
  79. */
  80. public function getPriceData($date,$type=1)
  81. {
  82. $cacheKey = "caches:prices:data_{$type}_{$date}";
  83. if(RedisService::get($cacheKey)){
  84. return true;
  85. }
  86. $data = $this->model->where(['date'=>$date,'type'=>$type,'status'=>1,'mark'=>1])
  87. ->orderBy('date','desc')
  88. ->first();
  89. $data = $data?$data->toArray() : [];
  90. $price = isset($data['price'])?$data['price']: '0.00';
  91. if($data && $price){
  92. RedisService::set($cacheKey, $data, rand(300,600));
  93. }
  94. return $data;
  95. }
  96. /**
  97. * 更新价格
  98. * @param int $type 1-资产
  99. * @return array|false
  100. */
  101. public function updatePrice($type=1)
  102. {
  103. try {
  104. if($type==1){
  105. $date = date('Y-m-d', strtotime(date('Y-m-d')) - 86400);
  106. $lastDate = date('Y-m-d', strtotime($date) - 86400);
  107. $cacheKey = "caches:prices:update_{$type}:".$date;
  108. if(RedisService::get($cacheKey)){
  109. $this->error = '价格已更新';
  110. return false;
  111. }
  112. // 是否已经更新过
  113. if($this->getPriceData($date, $type)){
  114. $this->error = '价格已更新';
  115. return false;
  116. }
  117. // 平台账户
  118. $ptAccount = PtAccountModel::where(['mark'=>1])->first();
  119. $accountId = isset($ptAccount['id'])?$ptAccount['id'] : 0;
  120. if(empty($ptAccount) || $accountId<=0){
  121. $ptAccount = ['balance'=>0,'property'=>10000,'pool_total'=>100,'create_time'=>time()];
  122. $accountId = PtAccountModel::insertGetId($ptAccount);
  123. }
  124. // 昨日价格
  125. $lastPrice = $this->getTodayPrice($type);
  126. // 昨日全网资产
  127. $lastPropertyTotal = isset($ptAccount['last_property'])?$ptAccount['last_property']:0;
  128. $ptProperty = isset($ptAccount['property'])?$ptAccount['property']:0; // 平台初始资产
  129. // 今日新增资产
  130. $todayPropertyTotal = 0;
  131. $todayProperty = AccountLogModel::where(['date'=>$date,'type'=>8,'account_type'=>2,'mark'=>1])->sum('money');
  132. if($todayProperty>=0){
  133. // 当日全网资产衰减后
  134. $propertyTotalByReduce = moneyFormat($lastPropertyTotal * 0.99,6);
  135. // 当日全网总资产
  136. $todayPropertyTotal = moneyFormat($propertyTotalByReduce + $todayProperty, 6);
  137. }else if($lastPrice<=0){
  138. // 当日全网总资产
  139. $todayPropertyTotal = $ptProperty;
  140. }
  141. // 平台底池总金额
  142. $poolTotal = isset($ptAccount['pool_total'])?$ptAccount['pool_total']:0;
  143. $todayPoolTotal = isset($ptAccount['today_pool'])?$ptAccount['today_pool']:0;
  144. // 当日价格
  145. $price = $todayPropertyTotal>0?moneyFormat($poolTotal/$todayPropertyTotal, 6) : 0;
  146. if($price>0){
  147. $data = [
  148. 'type'=>$type,
  149. 'price'=> $price,
  150. 'last_price'=> isset($lastPriceData['price'])?$lastPriceData['price'] : 0,
  151. 'pool_total'=>$poolTotal,
  152. 'today_pool'=>$todayPoolTotal,
  153. 'last_property'=>$lastPropertyTotal,
  154. 'today_property'=>$todayProperty,
  155. 'property_total'=>$todayPropertyTotal,
  156. 'date'=>$date,
  157. 'create_time'=>time(),
  158. 'status'=>1,
  159. ];
  160. DB::beginTransaction();
  161. if(!$logId = $this->model->insertGetId($data)){
  162. DB::rollBack();
  163. $this->error = '更新资产价格失败';
  164. return false;
  165. }
  166. $updateData = [
  167. 'property_price'=> $price,
  168. 'last_property'=> $lastPropertyTotal,
  169. 'today_property'=> 0,
  170. 'today_pool'=> 0,
  171. 'update_time'=>time()
  172. ];
  173. if(!PtAccountModel::where(['id'=>$accountId])->update($updateData)){
  174. DB::rollBack();
  175. $this->error = '更新平台账户数据失败';
  176. return false;
  177. }
  178. DB::commit();
  179. $data['id'] = $logId;
  180. RedisService::set($cacheKey, $data, 600);
  181. RedisService::clear("caches:prices:data_{$type}_{$date}");
  182. $this->error = '更新资产价格成功';
  183. return ['date'=>$date,'price'=>$price,'pool_total'=>$poolTotal,'property'=>$todayPropertyTotal];
  184. }else{
  185. $this->error = '今日资产价格无需更新';
  186. return false;
  187. }
  188. }
  189. $this->error = '更新资产价格失败';
  190. return false;
  191. } catch (\Exception $exception){
  192. $this->error = "更新资产每日价格失败:".$exception->getMessage();
  193. return false;
  194. }
  195. }
  196. }