PriceService.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  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. // 更新今日价格
  83. if(date('H:i')<= '10:00'){
  84. $this->updatePrice($type);
  85. }
  86. $cacheKey = "caches:prices:data_{$type}_{$date}";
  87. if(RedisService::get($cacheKey)){
  88. return true;
  89. }
  90. $data = $this->model->where(['date'=>$date,'type'=>$type,'status'=>1,'mark'=>1])
  91. ->orderBy('date','desc')
  92. ->first();
  93. $data = $data?$data->toArray() : [];
  94. $price = isset($data['price'])?$data['price']: '0.00';
  95. if($data && $price){
  96. RedisService::set($cacheKey, $data, rand(300,600));
  97. }
  98. return $data;
  99. }
  100. /**
  101. * 更新价格
  102. * @param int $type 1-资产
  103. * @return array|false
  104. */
  105. public function updatePrice($type=1)
  106. {
  107. try {
  108. if($type==1){
  109. $date = date('Y-m-d', strtotime(date('Y-m-d')) - 86400);
  110. $cacheKey = "caches:prices:update_{$type}:".$date;
  111. if(RedisService::get($cacheKey)){
  112. $this->error = '价格已更新';
  113. return false;
  114. }
  115. // 是否已经更新过
  116. if($this->getPriceData($date, $type)){
  117. $this->error = '价格已更新';
  118. return false;
  119. }
  120. // 平台账户
  121. $ptAccount = PtAccountModel::where(['mark'=>1])->first();
  122. $accountId = isset($ptAccount['id'])?$ptAccount['id'] : 0;
  123. if(empty($ptAccount) || $accountId<=0){
  124. $ptAccount = ['balance'=>0,'property'=>10000,'pool_total'=>100,'create_time'=>time()];
  125. $accountId = PtAccountModel::insertGetId($ptAccount);
  126. }
  127. // 昨日价格
  128. $lastPrice = $this->getTodayPrice($type);
  129. // 昨日全网资产
  130. $lastProperty = isset($ptAccount['last_property'])?$ptAccount['last_property']:0;
  131. $ptProperty = isset($ptAccount['property'])?$ptAccount['property']:0; // 平台初始资产
  132. // 今日新增资产
  133. $todayPropertyTotal = 0;
  134. $todayProperty = AccountLogModel::where(['date'=>$date,'type'=>8,'account_type'=>2,'mark'=>1])->sum('money');
  135. if($todayProperty>=0){
  136. // 当日全网资产衰减后
  137. $lastProperty = floatval($lastProperty)>0?$lastProperty:$ptProperty;
  138. $propertyTotalByReduce = moneyFormat($lastProperty * 0.99,6);
  139. // 当日全网总资产
  140. $todayPropertyTotal = moneyFormat($propertyTotalByReduce + $todayProperty, 6);
  141. }else if($lastPrice<=0){
  142. // 当日全网总资产
  143. $todayPropertyTotal = $ptProperty;
  144. }
  145. // 平台底池总金额
  146. $poolTotal = isset($ptAccount['pool_total'])?$ptAccount['pool_total']:0;
  147. $todayPoolTotal = isset($ptAccount['today_pool'])?$ptAccount['today_pool']:0;
  148. // 当日价格
  149. $price = $todayPropertyTotal>0?moneyFormat($poolTotal/$todayPropertyTotal, 6) : 0;
  150. if($price>0){
  151. $data = [
  152. 'type'=>$type,
  153. 'price'=> $price,
  154. 'last_price'=> isset($lastPriceData['price'])?$lastPriceData['price'] : 0,
  155. 'pool_total'=>$poolTotal,
  156. 'today_pool'=>$todayPoolTotal,
  157. 'last_property'=>$lastProperty,
  158. 'today_property'=>$todayProperty,
  159. 'property_total'=>$todayPropertyTotal,
  160. 'date'=>$date,
  161. 'updated_at'=> date('Y-m-d H:i:s'),
  162. 'create_time'=>time(),
  163. 'status'=>1,
  164. ];
  165. DB::beginTransaction();
  166. if(!$logId = $this->model->insertGetId($data)){
  167. DB::rollBack();
  168. $this->error = '更新资产价格失败';
  169. return false;
  170. }
  171. $updateData = [
  172. 'property_price'=> $price,
  173. 'last_property'=> $todayPropertyTotal,
  174. 'today_property'=> 0,
  175. 'today_pool'=> 0,
  176. 'update_time'=>time()
  177. ];
  178. if(!PtAccountModel::where(['id'=>$accountId])->update($updateData)){
  179. DB::rollBack();
  180. $this->error = '更新平台账户数据失败';
  181. return false;
  182. }
  183. DB::commit();
  184. $data['id'] = $logId;
  185. RedisService::set($cacheKey, $data, 600);
  186. RedisService::clear("caches:prices:today_price_{$type}");
  187. RedisService::clear("caches:prices:data_{$type}_{$date}");
  188. $this->error = '更新资产价格成功';
  189. return ['date'=>$date,'price'=>$price,'pool_total'=>$poolTotal,'property'=>$todayPropertyTotal];
  190. }else{
  191. $this->error = '今日资产价格无需更新';
  192. return false;
  193. }
  194. }
  195. $this->error = '更新资产价格失败';
  196. return false;
  197. } catch (\Exception $exception){
  198. $this->error = "更新资产每日价格失败:".$exception->getMessage();
  199. return false;
  200. }
  201. }
  202. }