MemberNodeService.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  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\MemberLevelModel;
  14. use App\Models\MemberModel;
  15. use App\Models\MemberNodeModel;
  16. use App\Models\MemberSettingModel;
  17. use App\Services\BaseService;
  18. use App\Services\ConfigService;
  19. use App\Services\RedisService;
  20. use Illuminate\Support\Facades\DB;
  21. /**
  22. * 节点会员服务管理-服务类
  23. * @author laravel开发员
  24. * @since 2020/11/11
  25. * @package App\Services\Common
  26. */
  27. class MemberNodeService extends BaseService
  28. {
  29. protected static $instance=null;
  30. /**
  31. * 构造函数
  32. * @author laravel开发员
  33. * @since 2020/11/11
  34. * MemberSettingService constructor.
  35. */
  36. public function __construct()
  37. {
  38. $this->model = new MemberNodeModel();
  39. }
  40. /**
  41. * 静态入口
  42. * @return static|null
  43. */
  44. public static function make()
  45. {
  46. if (!self::$instance) {
  47. self::$instance = (new static());
  48. }
  49. return self::$instance;
  50. }
  51. /**
  52. * 列表数据
  53. * @param $params
  54. * @param int $pageSize
  55. * @return array
  56. */
  57. public function getDataList($params, $pageSize = 15, $field = '', $userId=0)
  58. {
  59. $where = ['a.mark' => 1,'a.status'=>1];
  60. $field = $field? $field : 'lev_a.id,lev_a.name,lev_a.price,lev_a.upgrade_level_id,lev_b.global_bonus_rate,lev_a.limit_num,lev_a.box_num,lev_a.score_rate,lev_a.remark,lev_a.status';
  61. $sortType = isset($params['sort_type']) ? $params['sort_type'] : 1;
  62. $order = 'id asc';
  63. if($sortType == 1){
  64. $order = 'lev_a.id asc';
  65. }
  66. $list = $this->model->from('member_nodes as a')
  67. ->leftJoin('member_level as b','b.id','=','a.upgrade_level_id')
  68. ->where($where)
  69. ->selectRaw($field)
  70. ->orderByRaw($order)
  71. ->paginate($pageSize > 0 ? $pageSize : 9999999);
  72. $list = $list ? $list->toArray() : [];
  73. if ($list) {
  74. foreach ($list['data'] as &$item) {
  75. $item['level_box_num'] = (int)MemberLevelModel::where('id','<=', $item['upgrade_level_id'])->where(['status'=>1,'mark'=>1])->sum('box_num');
  76. // 是否已购买
  77. $buyLogId = AccountLogModel::where(['user_id'=> $userId,'source_id'=>$item['id'],'type'=>4,'status'=>1,'mark'=>1])->value('id');
  78. $item['buy_status'] = $buyLogId? 1 : 0;
  79. }
  80. }
  81. return [
  82. 'pageSize' => $pageSize,
  83. 'total' => isset($list['total']) ? $list['total'] : 0,
  84. 'list' => isset($list['data']) ? $list['data'] : []
  85. ];
  86. }
  87. /**
  88. * 购买节点
  89. * @param $userId 用户ID
  90. * @param $params 节点参数:id-节点ID,pay_password-交易密码
  91. * @return bool
  92. */
  93. public function buyNode($userId, $params)
  94. {
  95. $nodeId = isset($params['id'])? intval($params['id']) : 0;
  96. $payPassword = isset($params['pay_password'])? trim($params['pay_password']) : '';
  97. if($nodeId<=0){
  98. $this->error = 2014;
  99. return false;
  100. }
  101. $cacheKey = "caches:members:nodes:buy_{$userId}_{$nodeId}";
  102. if(RedisService::get($cacheKey.'_lock')){
  103. $this->error = 1034;
  104. return false;
  105. }
  106. $nodeInfo = $this->model->from('member_nodes as a')
  107. ->leftJoin('member_level as b','b.id','=','a.upgrade_level_id')
  108. ->where(['a.id'=> $nodeId,'a.status'=>1,'a.mark'=>1])
  109. ->select(['a.*','b.name as level_name'])
  110. ->first();
  111. $price = isset($nodeInfo['price'])? floatval($nodeInfo['price']) : 0;
  112. $boxNum = isset($nodeInfo['box_num'])? intval($nodeInfo['box_num']) : 0;
  113. $upgradeLevelId = isset($nodeInfo['upgrade_level_id'])? intval($nodeInfo['upgrade_level_id']) : 0;
  114. $nodeName = isset($nodeInfo['name'])? $nodeInfo['name'] : '';
  115. $levelName = isset($nodeInfo['level_name'])? $nodeInfo['level_name'] : '';
  116. if(empty($nodeInfo) || $price<=0){
  117. $this->error = 2501;
  118. return false;
  119. }
  120. $userInfo = MemberModel::where(['id'=> $userId,'mark'=>1])
  121. ->select(['id','nickname','usdt','wait_score','parents','points','parent_id','member_level','power_num','trc_url','pay_password','status'])
  122. ->first();
  123. $status = isset($userInfo['status'])? $userInfo['status'] : 0;
  124. $userUsdt = isset($userInfo['usdt'])? $userInfo['usdt'] : 0;
  125. $userPayPassword = isset($userInfo['pay_password'])? $userInfo['pay_password'] : '';
  126. $userWaitScore = isset($userInfo['wait_score'])? $userInfo['wait_score'] : 0;
  127. $userPowerNum = isset($userInfo['power_num'])? $userInfo['power_num'] : 0;
  128. if(empty($userInfo) || $status != 1){
  129. $this->error = 2024;
  130. return false;
  131. }
  132. // 是否已经购买过
  133. if(AccountLogModel::where(['user_id'=> $userId,'source_id'=>$nodeId,'type'=>4,'status'=>1,'mark'=>1])->value('id')){
  134. $this->error = 2502;
  135. return false;
  136. }
  137. // USDT余额是否足够
  138. if($userUsdt < $price){
  139. $this->error = 2035;
  140. return false;
  141. }
  142. // 交易密码
  143. if(empty($userPayPassword)){
  144. $this->error = 1040;
  145. return false;
  146. }
  147. if($userPayPassword != get_password($payPassword)){
  148. $this->error = 2038;
  149. return false;
  150. }
  151. // 购买明细
  152. RedisService::set($cacheKey, $params, rand(2,3));
  153. $orderNo = get_order_num('VN');
  154. DB::beginTransaction();
  155. $log = [
  156. 'user_id' => $userId,
  157. 'source_id' => $nodeId,
  158. 'source_order_no' => $orderNo,
  159. 'type' => 4,
  160. 'coin_type' => 1,
  161. 'user_type'=> 1,
  162. 'money' => -$price,
  163. 'actual_money' => -$price,
  164. 'balance' => $userUsdt,
  165. 'create_time' => time(),
  166. 'update_time' => time(),
  167. 'remark' => "购买{$nodeName}",
  168. 'status' => 1,
  169. 'mark' => 1,
  170. ];
  171. if(!AccountLogModel::insertGetId($log)){
  172. DB::rollBack();
  173. $this->error = 2029;
  174. RedisService::clear($cacheKey);
  175. return false;
  176. }
  177. // 待返积分明细
  178. $xdPrice = ConfigService::make()->getConfigByCode('xd_price',100);
  179. $xdPrice = $xdPrice>0 && $xdPrice<=10000? $xdPrice : 100;
  180. $waitScoreRate = ConfigService::make()->getConfigByCode('node_award_score_rate', 200);
  181. $waitScoreRate = $waitScoreRate>0 && $waitScoreRate<=1000? $waitScoreRate : 0;
  182. $waitScore = moneyFormat($price * $xdPrice * $waitScoreRate/100, 2);
  183. if($waitScore>0){
  184. $log = [
  185. 'user_id' => $userId,
  186. 'source_id' => $nodeId,
  187. 'source_order_no' => $orderNo,
  188. 'type' => 9,
  189. 'coin_type' => 5,
  190. 'user_type'=> 1,
  191. 'money' => $waitScore,
  192. 'actual_money' => $waitScore,
  193. 'balance' => $userWaitScore,
  194. 'create_time' => time(),
  195. 'update_time' => time(),
  196. 'remark' => "购买{$nodeName}",
  197. 'status' => 1,
  198. 'mark' => 1,
  199. ];
  200. if(!AccountLogModel::insertGetId($log)){
  201. DB::rollBack();
  202. $this->error = 2029;
  203. RedisService::clear($cacheKey);
  204. return false;
  205. }
  206. }
  207. // 算力明细
  208. $powerNum = $price;
  209. $log = [
  210. 'user_id' => $userId,
  211. 'source_id' => $nodeId,
  212. 'source_order_no' => $orderNo,
  213. 'type' => 9,
  214. 'coin_type' => 3,
  215. 'user_type'=> 1,
  216. 'money' => $powerNum,
  217. 'actual_money' => $powerNum,
  218. 'balance' => $userPowerNum,
  219. 'create_time' => time(),
  220. 'update_time' => time(),
  221. 'remark' => "购买{$nodeName}",
  222. 'status' => 1,
  223. 'mark' => 1,
  224. ];
  225. if(!AccountLogModel::insertGetId($log)){
  226. DB::rollBack();
  227. $this->error = 2029;
  228. RedisService::clear($cacheKey);
  229. return false;
  230. }
  231. // 账户
  232. $updateData = [
  233. 'usdt'=> DB::raw("usdt - {$price}"), // 扣除USDT
  234. 'supper_point'=>$nodeId,
  235. 'member_level'=> $upgradeLevelId, // 直达等级
  236. 'box_num'=>DB::raw("box_num + {$boxNum}"), // 奖励盲盒数量
  237. 'wait_score'=>DB::raw("wait_score + {$waitScore}"), // 奖励盲盒数量
  238. 'power_num'=>DB::raw("power_num + {$powerNum}"), // 奖励盲盒数量
  239. 'update_time'=>time()
  240. ];
  241. if(!MemberModel::where(['id'=> $userId])->update($updateData)){
  242. DB::rollBack();
  243. $this->error = 2036;
  244. RedisService::clear($cacheKey);
  245. return false;
  246. }
  247. // 消息
  248. $dateTime = date('Y-m-d H:i:s');
  249. $levelTip = $upgradeLevelId>0? ",并升级为{$levelName}" :'';
  250. MessageService::make()->pushMessage($userId,"购买{$nodeName}成功","您在{$dateTime}(UTC+8)成功支付{$price}USDT购买【{$nodeName}】{$levelTip}。",3);
  251. DB::commit();
  252. // 算力统计
  253. AccountLogService::make()->saveCount($userId, $powerNum, 1);
  254. // 业绩统计
  255. AccountLogService::make()->saveCount($userId, $price, 2);
  256. // 结算收益奖励
  257. FinanceService::make()->settleBonus($userId, $userInfo, $price, $orderNo, "购买{$nodeName}");
  258. $this->error = 2503;
  259. RedisService::clear($cacheKey);
  260. return true;
  261. }
  262. /**
  263. * 节点详情信息
  264. * @param $nodeId 节点ID
  265. * @return array|mixed
  266. */
  267. public function getNodeInfo($nodeId)
  268. {
  269. $cacheKey = "caches:nodes:info:{$nodeId}";
  270. $data = RedisService::get($cacheKey);
  271. if($data){
  272. return $data;
  273. }
  274. $data = $this->model->where(['id'=>$nodeId,'mark'=>1,'status'=>1])
  275. ->select(['id','name','price','score_rate','box_num'])
  276. ->first();
  277. $data = $data?$data->toArray() : [];
  278. if($data){
  279. RedisService::set($cacheKey, $data, rand(3600,7200));
  280. }
  281. return $data;
  282. }
  283. }