MiningMachine.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <?php
  2. namespace app\models\mining;
  3. use app\models\user\User;
  4. use app\models\user\UserLevel;
  5. use app\models\user\UserMoney;
  6. use crmeb\basic\BaseModel;
  7. use crmeb\traits\ModelTrait;
  8. use think\db\Query;
  9. use think\Exception;
  10. class MiningMachine extends BaseModel
  11. {
  12. /**
  13. * 数据表主键
  14. * @var string
  15. */
  16. protected $pk = 'id';
  17. /**
  18. * 模型名称
  19. * @var string
  20. */
  21. protected $name = 'mining_machine';
  22. use ModelTrait;
  23. /**
  24. * @return MiningMachine
  25. */
  26. public static function valid()
  27. {
  28. return self::where('is_del', 0);
  29. }
  30. /**
  31. * @param int $page
  32. * @param int $limit
  33. * @param array $where
  34. * @return array
  35. */
  36. public static function getList(int $page = 1, int $limit = 10, array $where = []): array
  37. {
  38. $money_type = init_money_type();
  39. $model = self::valid();
  40. if (isset($where['get_money_type']) && $where['get_money_type'] != '') $model = $model->where('get_money_type', $where['get_money_type']);
  41. if (isset($where['type']) && $where['type'] != '') $model = $model->where('type', $where['type']);
  42. $count = $model->count();
  43. $data = $model->order('id', 'desc')->page($page, $limit)->select()->each(function ($item) use ($money_type, $where) {
  44. $item['_day_get'] = $item['day_get'] . $money_type[$item['get_money_type']] . '/T';
  45. $item['_cost_money'] = $item['cost_money'] . $money_type[$item['cost_money_type']];
  46. $item['_stand_money'] = $item['stand_money'] . $money_type[$item['get_money_type']];
  47. $item['tags'] = explode(',', $item['tags']);
  48. $item['award_ratio'] = 0;
  49. //$item['service'] = explode(',', $item['tags']);
  50. if (isset($where['uid']) && $where['uid']) {
  51. $uids = User::where('spread_uid', $where['uid'])->column('uid');
  52. $item['award_ratio'] = UserMiningRatio::where('uid', $where['uid'])->where('mid', $item['id'])->value('ratio') ?: 0;
  53. $item['lower_award_ratio'] = UserMiningRatio::where('mid', $item['id'])->where('uid', 'in', $uids)->max('ratio') ?: 0;
  54. $item['user_service_ratio'] = UserMiningService::where('uid', $where['uid'])->where('mid', $item['id'])->value('ratio') ?: $item['service_ratio'];
  55. $item['lower_service_ratio'] = UserMiningService::where('mid', $item['id'])->where('uid', 'in', $uids)->min('ratio') ?: $item['service_ratio'];
  56. }
  57. })->toArray();
  58. return compact('count', 'data');
  59. }
  60. public static function buyMachine($id, $uid, $num)
  61. {
  62. $info = self::valid()->where('id', $id)->find();
  63. // if (bcmod($num, $info['step'], 2) > 0) return self::setErrorInfo('算力值错误');
  64. if ($num < $info['step']) return self::setErrorInfo('垓矿机单次购买算力不小于' . $info['step']);
  65. if (!$info) {
  66. return self::setErrorInfo('矿机已下架或不存在');
  67. }
  68. if ($info['stock'] < $num) {
  69. return self::setErrorInfo('矿机不足');
  70. }
  71. $money_type = init_money_type();
  72. $user_money = UserMoney::initialUserMoney($uid, $info['cost_money_type']);
  73. $user_money_stand = UserMoney::initialUserMoney($uid, $info['get_money_type']);
  74. if ($info['cost_money_type'] == $info['get_money_type']) {
  75. $cost_money = bcadd($info['cost_money'], $info['stand_money'], 8);
  76. $stand_money = 0;
  77. } else {
  78. $cost_money = $info['cost_money'];
  79. $stand_money = $info['stand_money'];
  80. }
  81. $cost_money = bcmul($cost_money, $num);
  82. $stand_money = bcmul($stand_money, $num);
  83. $info['cost_money'] = bcmul($info['cost_money'], $num);
  84. $info['stand_money'] = bcmul($info['stand_money'], $num);
  85. if ($user_money['money'] < $cost_money) {
  86. return self::setErrorInfo('购买矿机所需的' . $money_type[$info['cost_money_type']] . '不足');
  87. }
  88. if ($user_money_stand['money'] < $stand_money) {
  89. return self::setErrorInfo('部署矿机需质押的' . $money_type[$info['stand_money_type']] . '(包含GAS)不足');
  90. }
  91. BaseModel::beginTrans();
  92. try {
  93. $res1 = UserMoney::expendMoney($uid, $info['cost_money_type'], $cost_money, 'buy_machine', '购买矿机', '购买矿机' . $info['name'] . '*' . $num);
  94. $res2 = true;
  95. if ($stand_money > 0)
  96. $res2 = UserMoney::expendMoney($uid, $info['stand_money_type'], $stand_money, 'buy_machine_stand', '部署矿机质押', '部署矿机' . $info['name'] . '*' . $num . ',' . '质押(包含GAS费)');
  97. if ($res1 && $res2) {
  98. $res = UserMiningMachine::create([
  99. 'uid' => $uid,
  100. 'mid' => $id,
  101. 'day_get' => $info['day_get'],
  102. 'get_money_type' => $info['get_money_type'],
  103. 'cost_money' => $info['cost_money'],
  104. 'cost_money_type' => $info['cost_money_type'],
  105. 'stand_money' => $info['stand_money'],
  106. 'add_time' => time(),
  107. 'pay_time' => time(),
  108. 'paid' => 1,
  109. 'num' => $num,
  110. 'mining_end_time' => bcadd(bcadd(time(), bcmul($info['first_step_time'] + $info['third_step_time'] + $info['second_step_time'], 3600 * 24)), bcmul($info['stand_time'], 3600 * 24)),
  111. 'mining_start_time' => bcadd(time(), bcmul($info['stand_time'], 3600 * 24)),
  112. 'second_step_start_time' => bcadd(bcadd(time(), bcmul($info['first_step_time'], 3600 * 24)), bcmul($info['stand_time'], 3600 * 24)),
  113. 'third_step_start_time' => bcadd(bcadd(time(), bcmul($info['first_step_time'] + $info['second_step_time'], 3600 * 24)), bcmul($info['stand_time'], 3600 * 24)),
  114. ]);
  115. if ($res) $res = $res && self::sendRecommendAward($res) && self::bcDec($id, 'stock', $num);
  116. if (!$res) {
  117. return BaseModel::setErrorInfo('购买失败', true);
  118. }
  119. } else {
  120. return BaseModel::setErrorInfo('支付失败', true);
  121. }
  122. $uper = User::getUserInfo($uid);
  123. while ($uper) {
  124. UserLevel::setLevelComplete($uper['uid']);
  125. $uper = User::getUserInfo($uper['spread_uid']);
  126. }
  127. BaseModel::commitTrans();
  128. return true;
  129. } catch (Exception $e) {
  130. return BaseModel::setErrorInfo($e->getMessage(), true);
  131. }
  132. }
  133. public static function sendRecommendAward($order)
  134. {
  135. $user = User::getUserInfo($order['uid']);
  136. $spread = User::getUserInfo($user['spread_uid']);
  137. if (!$spread) return true;
  138. $num = $order['cost_money'];
  139. $money_type = $order['cost_money_type'];
  140. $send = 0;
  141. $res = true;
  142. while ($spread) {
  143. $ratio = UserLevel::getUserLevelInfo(UserLevel::getUserLevel($spread['uid']), 'recommend_award_ratio');
  144. $brokerage = bcmul($num, bcdiv($ratio, 100, 4), 8);
  145. if ($brokerage > $send) {
  146. $res = $res && UserMoney::incomeMoney($spread['uid'], $money_type, bcsub($brokerage, $send, 8), 'buy_machine_spread_brokerage', '推荐佣金', '下级用户' . $user['nickname'] . '(' . $user['uid'] . ')' . '购买矿机' . $order['num'] . 'T,支付' . $order['cost_money'] . $order['cost_money_type'] . '获得推荐奖');
  147. $send = $brokerage;
  148. }
  149. $spread = User::getUserInfo($spread['spread_uid']);
  150. }
  151. return $res;
  152. }
  153. }