FinanceService.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  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\FinanceModel;
  14. use App\Models\MemberModel;
  15. use App\Services\BaseService;
  16. use App\Services\ConfigService;
  17. use App\Services\RedisService;
  18. use Illuminate\Support\Facades\DB;
  19. /**
  20. * 平台账户(财务)-服务类
  21. * @author laravel开发员
  22. * @since 2020/11/12
  23. * Class ActionLogService
  24. * @package App\Services\Common
  25. */
  26. class FinanceService extends BaseService
  27. {
  28. protected static $instance=null;
  29. /**
  30. * 构造函数
  31. * @author laravel开发员
  32. * @since 2020/11/11
  33. * FinanceService constructor.
  34. */
  35. public function __construct()
  36. {
  37. $this->model = new FinanceModel();
  38. }
  39. /**
  40. * 静态入口
  41. * @return static|null
  42. */
  43. public static function make()
  44. {
  45. if (!self::$instance) {
  46. self::$instance = (new static());
  47. }
  48. return self::$instance;
  49. }
  50. /**
  51. * @param $params
  52. * @param int $pageSize
  53. * @return array
  54. */
  55. public function getDataList($params, $pageSize = 15)
  56. {
  57. $where = ['a.mark' => 1];
  58. $status = isset($params['status'])? $params['status'] : 0;
  59. $type = isset($params['type'])? $params['type'] : 0;
  60. if($status>0){
  61. $where['a.status'] = $status;
  62. }
  63. if($type>0){
  64. $where['a.type'] = $type;
  65. }
  66. $list = $this->model->from('finance as a')
  67. ->where($where)
  68. ->where(function ($query) use($params){
  69. // 日期
  70. $date = isset($params['date']) ? $params['date'] : [];
  71. $start = isset($date[0])? $date[0] : '';
  72. $end = isset($date[1])? $date[1] : '';
  73. $end = $start>=$end? '' : $end;
  74. if ($start) {
  75. $query->where('a.create_time','>=', strtotime($start));
  76. }
  77. if($end){
  78. $query->where('a.create_time','<', strtotime($end));
  79. }
  80. })
  81. ->select(['a.*'])
  82. ->orderBy('a.create_time','desc')
  83. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  84. $list = $list? $list->toArray() :[];
  85. if($list){
  86. foreach($list['data'] as &$item){
  87. $item['create_time'] = $item['create_time']? datetime($item['create_time'],'Y-m-d H.i.s') : '';
  88. }
  89. }
  90. return [
  91. 'pageSize'=> $pageSize,
  92. 'total'=>isset($list['total'])? $list['total'] : 0,
  93. 'list'=> isset($list['data'])? $list['data'] : []
  94. ];
  95. }
  96. /**
  97. * 平台结算
  98. * @param $money
  99. * @param int $changeType 交易类型:1-进账,2-出账
  100. * @param int $type 类型:1-消费,2-佣金,3-充值提现转账,4-退款,99-其他
  101. * @param int $coinType 币种类型: 1-USDT,2-星豆
  102. * @return mixed
  103. */
  104. public function saveLog($userId, $money, $changeType = 1, $type=1, $coinType = 1)
  105. {
  106. $date = date('Y-m-d');
  107. $info = $this->model->where(['user_id'=> $userId,'date'=> $date,'type'=> $type,'mark'=>1])->first();
  108. if(!$info){
  109. $data = ['user_id'=>$userId,'date'=> $date,'type'=>$type,'create_time'=>time(),'update_time'=> time(),'status'=>1];
  110. if($changeType==1){
  111. $data['income'] = $money;
  112. }else{
  113. $data['expend'] = $money;
  114. }
  115. return $this->model->insertGetId($data);
  116. }else{
  117. if($changeType == 1){
  118. $info->income += $money;
  119. }else{
  120. $info->expend += $money;
  121. }
  122. return $info->save();
  123. }
  124. }
  125. /**
  126. * 升级收益结算
  127. * @param $userId 升级用户ID
  128. * @param $userInfo 升级用户信息:parents-上级,points-上级节点,parent_id-推荐人,member_level-升级用户等级
  129. * @param $usdt 升级消费的USDT
  130. * @param $orderNo 升级记录单号
  131. * @param string $remark 升级项目备注说明
  132. * @return bool
  133. */
  134. public function settleBonus($userId, $userInfo, $usdt, $orderNo, $remark='')
  135. {
  136. $parents = isset($userInfo['parents'])? $userInfo['parents'] : ''; // 上级
  137. $points = isset($userInfo['points'])? $userInfo['points'] : ''; // 挂靠节点
  138. $parentId = isset($userInfo['parent_id'])? $userInfo['parent_id'] : 0;
  139. $userLevel = isset($userInfo['member_level'])? $userInfo['member_level'] : 0; // 用户等级
  140. RedisService::set("caches:bonus:temp_{$userId}_{$orderNo}", ['info'=> $userInfo,'usdt'=> $usdt,'remark'=> $remark], 6 * 3600);
  141. if($userLevel<=0){
  142. $this->error = 2607;
  143. return false;
  144. }
  145. DB::beginTransaction();
  146. // TODO 直推奖励结算
  147. if($usdt>0 && $parentId>0){
  148. $parentInfo = MemberModel::where(['id'=> $parentId,'mark'=>1])
  149. ->select(['id','usdt','balance','wait_score'])
  150. ->first();
  151. $rate1 = ConfigService::make()->getConfigByCode('award_push_rate',0);
  152. $rate1 = $rate1>0 && $rate1 <100? $rate1 : 0;
  153. $bonusUsdt1 = moneyFormat($usdt * $rate1/100, 4);
  154. if($parentInfo && $bonusUsdt1>0){
  155. // 账户进账
  156. $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt1}"),'update_time'=>time()];
  157. if(!MemberModel::where(['id'=> $parentId,'mark'=>1])->update($updateData)){
  158. DB::rollBack();
  159. $this->error = 2601;
  160. return false;
  161. }
  162. // 收益明细
  163. $log = [
  164. 'user_id' => $parentId,
  165. 'source_id' => $userId,
  166. 'source_order_no' => $orderNo,
  167. 'type' => 12,
  168. 'coin_type' => 1,
  169. 'user_type'=> 1,
  170. 'money' => $bonusUsdt1,
  171. 'actual_money' => $bonusUsdt1,
  172. 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0,
  173. 'create_time' => time(),
  174. 'update_time' => time(),
  175. 'remark' => $remark,
  176. 'status' => 1,
  177. 'mark' => 1,
  178. ];
  179. if(!AccountLogModel::insertGetId($log)){
  180. DB::rollBack();
  181. $this->error = 2602;
  182. return false;
  183. }
  184. // TODO 平台流水(拨出对应比例USDT)
  185. FinanceService::make()->saveLog(0, $bonusUsdt1, 2);
  186. }
  187. }
  188. // TODO 点对点奖励收益结算 (会员升级数必须小于等于节点会员层数,即按同层给奖励)
  189. $points = $points? explode(',', $points) : [];
  190. $points = array_filter($points);
  191. $pointId = isset($points[$userLevel-1])? $points[$userLevel-1] : 0;
  192. if($points && count($points) >= $userLevel && $pointId>0){
  193. // TODO 当前会员升级为N级,且N层上级节点会员等级>=升级会员等级时奖励点对点奖励(否则等级烧伤)
  194. $pointInfo = MemberModel::where(['id'=> $pointId,'mark'=>1])
  195. ->select(['id','usdt','balance','member_level','wait_score'])
  196. ->first();
  197. $pointLevel = isset($pointInfo['member_level'])? $pointInfo['member_level'] : 0;
  198. $rate2 = ConfigService::make()->getConfigByCode('award_node_rate',0);
  199. $rate2 = $rate2>0 && $rate2 <100? $rate2 : 0;
  200. $bonusUsdt2 = moneyFormat($usdt * $rate2/100, 4);
  201. if($pointInfo && $bonusUsdt2>0){
  202. if($pointLevel>= $userLevel){
  203. // 账户进账
  204. $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt2}"),'update_time'=>time()];
  205. if(!MemberModel::where(['id'=> $pointId,'mark'=>1])->update($updateData)){
  206. DB::rollBack();
  207. $this->error = 2603;
  208. return false;
  209. }
  210. // 收益明细
  211. $log = [
  212. 'user_id' => $parentId,
  213. 'source_id' => $userId,
  214. 'source_order_no' => $orderNo,
  215. 'type' => 14,
  216. 'coin_type' => 1,
  217. 'user_type'=> 1,
  218. 'money' => $bonusUsdt2,
  219. 'actual_money' => $bonusUsdt2,
  220. 'balance' => isset($pointInfo['usdt'])? $pointInfo['usdt'] : 0,
  221. 'create_time' => time(),
  222. 'update_time' => time(),
  223. 'remark' => $remark,
  224. 'status' => 1,
  225. 'mark' => 1,
  226. ];
  227. if(!AccountLogModel::insertGetId($log)){
  228. DB::rollBack();
  229. $this->error = 2604;
  230. return false;
  231. }
  232. // TODO 平台流水(拨出对应比例USDT)
  233. FinanceService::make()->saveLog(0, $bonusUsdt2, 2);
  234. }
  235. // 烧伤明细处理(不进账)
  236. else{
  237. $log = [
  238. 'user_id' => $parentId,
  239. 'source_id' => $userId,
  240. 'source_order_no' => $orderNo,
  241. 'type' => 97,
  242. 'coin_type' => 1,
  243. 'user_type'=> 1,
  244. 'money' => $bonusUsdt2,
  245. 'actual_money' => $bonusUsdt2,
  246. 'balance' => isset($pointInfo['usdt'])? $pointInfo['usdt'] : 0,
  247. 'create_time' => time(),
  248. 'update_time' => time(),
  249. 'remark' => $remark,
  250. 'status' => 1,
  251. 'mark' => 1,
  252. ];
  253. if(!AccountLogModel::insertGetId($log)){
  254. DB::rollBack();
  255. $this->error = 2604;
  256. return false;
  257. }
  258. }
  259. }
  260. }
  261. // TODO 管理奖结算(往上找最近的等级为5的倍数且等级大于升级用户的顺位用户,奖励管理奖)
  262. $parents = $parents? explode(',', $parents) : [];
  263. $parents = array_filter($parents);
  264. if($parents){
  265. $awardIndex = -1;
  266. $logs = []; // 明细和烧伤明细
  267. foreach ($parents as $k => $pid){
  268. $parentInfo = MemberModel::where(['id'=> $parentId,'mark'=>1])
  269. ->select(['id','usdt','balance','member_level','wait_score'])
  270. ->first();
  271. $parentLevel = isset($parentInfo['member_level'])? $parentInfo['member_level'] : 0;
  272. $rate3 = ConfigService::make()->getConfigByCode('award_manage_rate',0);
  273. $rate3 = $rate3>0 && $rate3 <100? $rate3 : 0;
  274. $bonusUsdt3 = moneyFormat($usdt * $rate3/100, 4);
  275. if($parentLevel>= $userLevel && ($parentLevel%5==0)){
  276. $awardIndex = $k;
  277. if($bonusUsdt3>0){
  278. // 账户进账
  279. $updateData = ['usdt'=> DB::raw("usdt + {$bonusUsdt3}"),'update_time'=>time()];
  280. if(!MemberModel::where(['id'=> $pid,'mark'=>1])->update($updateData)){
  281. DB::rollBack();
  282. $this->error = 2605;
  283. return false;
  284. }
  285. // 收益明细
  286. $logs[] = [
  287. 'user_id' => $pid,
  288. 'source_id' => $userId,
  289. 'source_order_no' => $orderNo,
  290. 'type' => 13,
  291. 'coin_type' => 1,
  292. 'user_type'=> 1,
  293. 'money' => $bonusUsdt3,
  294. 'actual_money' => $bonusUsdt3,
  295. 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0,
  296. 'create_time' => time(),
  297. 'update_time' => time(),
  298. 'remark' => $remark,
  299. 'status' => 1,
  300. 'mark' => 1,
  301. ];
  302. }
  303. }
  304. // (已经找到) 剩下的管理奖烧伤
  305. else if($awardIndex>=0){
  306. // 管理烧伤明细
  307. $logs[] = [
  308. 'user_id' => $pid,
  309. 'source_id' => $userId,
  310. 'source_order_no' => $orderNo,
  311. 'type' => 98,
  312. 'coin_type' => 1,
  313. 'user_type'=> 1,
  314. 'money' => $bonusUsdt3,
  315. 'actual_money' => $bonusUsdt3,
  316. 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0,
  317. 'create_time' => time(),
  318. 'update_time' => time(),
  319. 'remark' => $remark,
  320. 'status' => 1,
  321. 'mark' => 1,
  322. ];
  323. }
  324. // 还没找到,即等级条件不满足,等级烧伤
  325. else {
  326. // 等级烧伤明细
  327. $logs[] = [
  328. 'user_id' => $pid,
  329. 'source_id' => $userId,
  330. 'source_order_no' => $orderNo,
  331. 'type' => 97,
  332. 'coin_type' => 1,
  333. 'user_type'=> 1,
  334. 'money' => $bonusUsdt3,
  335. 'actual_money' => $bonusUsdt3,
  336. 'balance' => isset($parentInfo['usdt'])? $parentInfo['usdt'] : 0,
  337. 'create_time' => time(),
  338. 'update_time' => time(),
  339. 'remark' => $remark,
  340. 'status' => 1,
  341. 'mark' => 1,
  342. ];
  343. }
  344. }
  345. if($logs && !AccountLogModel::insert($logs)){
  346. DB::rollBack();
  347. $this->error = 2606;
  348. return false;
  349. }
  350. }
  351. DB::commit();
  352. $this->error = 2608;
  353. return true;
  354. }
  355. /**
  356. * 任务算力奖励
  357. * @param $userId 用户ID
  358. * @param $power 算力
  359. * @param $type 类型
  360. * @param int $sourceId 任务ID
  361. * @param string $remark 备注说明
  362. * @return false
  363. */
  364. public function settleTaskPower($userId, $power, $type, $sourceId=0, $remark='')
  365. {
  366. if($power<=0){
  367. $this->error = 2014;
  368. return false;
  369. }
  370. $userInfo = MemberModel::where(['id'=> $userId, 'status'=>1,'mark'=>1])
  371. ->select(['id','nickname','usdt','power_num','status'])
  372. ->first();
  373. $userPower = isset($userInfo['power_num'])? $userInfo['power_num'] : 0;
  374. if(empty($userInfo) || $userId<=0)
  375. {
  376. $this->error = 1041;
  377. return false;
  378. }
  379. DB::beginTransaction();
  380. // 更新账户算力
  381. $updateData = ['power_num'=> DB::raw("power_num + {$power}"),'update_time'=>time()];
  382. if(!MemberModel::where(['id'=> $userId])->update($updateData)){
  383. DB::rollBack();
  384. $this->error = 1042;
  385. return false;
  386. }
  387. // 明细
  388. $orderNo = get_order_num('TS');
  389. $log = [
  390. 'user_id' => $userId,
  391. 'source_id' => $sourceId,
  392. 'source_order_no' => $orderNo,
  393. 'type' => $type?$type:99,
  394. 'coin_type' => 3,
  395. 'user_type'=> 1,
  396. 'money' => $power,
  397. 'actual_money' => $power,
  398. 'balance' => $userPower,
  399. 'create_time' => time(),
  400. 'update_time' => time(),
  401. 'remark' => $remark? $remark : '算力奖励',
  402. 'status' => 1,
  403. 'mark' => 1,
  404. ];
  405. if (!AccountLogModel::insertGetId($log)) {
  406. $this->error = 2407;
  407. DB::rollBack();
  408. return false;
  409. }
  410. DB::commit();
  411. // 站内消息
  412. $dateTime = date('Y-m-d H:i:s');
  413. MessageService::make()->pushMessage($userId, $log['remark'] , "您在{$dateTime}(UTC+8){$log['remark']}{$power}算力已到账,请及时查看账户!!!",3);
  414. }
  415. }