SettlementService.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. namespace App\Services;
  3. use App\Constants\StepStatus;
  4. use App\Exceptions\MessageException;
  5. use App\Models\BalanceLog;
  6. use App\Models\Config;
  7. use App\Models\Room;
  8. use App\Models\RoomUser;
  9. use App\Models\User;
  10. use App\Models\Wallet;
  11. use Illuminate\Support\Facades\Cache;
  12. use Illuminate\Support\Facades\Storage;
  13. use Telegram\Bot\Api;
  14. //结算相关
  15. class SettlementService
  16. {
  17. private $telegram;
  18. public function __construct()
  19. {
  20. $this->telegram = new Api(config('services.telegram.token'));
  21. }
  22. //用户提交结算数据
  23. public function submitSettle($chatId, $score, $messageId = null)
  24. {
  25. if (!preg_match('/^-?\d+$/', $score)) {
  26. return [
  27. 'status' => false,
  28. 'data' => [[
  29. 'chat_id' => $chatId,
  30. 'text' => '输入错误,请发送结算分数',
  31. 'reply_to_message_id' => $messageId
  32. ]]
  33. ];
  34. }
  35. $score = intval($score);
  36. $ru = RoomUser::whereIn('status', [2, 3])
  37. ->where('member_id', $chatId)->first();
  38. if (!$ru) {
  39. return [
  40. 'status' => false,
  41. 'data' => [['chat_id' => $chatId, 'text' => '没有待结算的对局']]
  42. ];
  43. }
  44. $ru->status = 3;
  45. $ru->score = $score;
  46. $ru->save();
  47. $list = RoomUser::where('status', 3)
  48. ->where('room_id', $ru->room_id)
  49. ->orderBy('score', 'desc')->get();
  50. $count = RoomUser::where('room_id', $ru->room_id)->count();
  51. if (count($list) == $count) {
  52. $totalAmount = RoomUser::where('status', 3)
  53. ->where('room_id', $ru->room_id)->sum('score');
  54. if ($totalAmount != 0) {
  55. $text = "❌经过系统结算,盈利额与亏损\n";
  56. $text .= "额度无法匹配,无法进行结算,\n";
  57. $text .= "请检查战绩是否正确,如果错误\n";
  58. $text .= "请重新输入正确的战绩!\n\n";
  59. $text .= "您输入的战绩如下:\n";
  60. $arr = [];
  61. foreach ($list as $item) {
  62. $str = $text . "--------------------------------\n";
  63. $str .= "房间号:{$item->room_id}\n";
  64. $str .= "用户:{$item->game_id}\n";
  65. $str .= "战绩:{$item->score}\n";
  66. $arr[] = [
  67. 'chat_id' => $item->member_id,
  68. 'text' => $str
  69. ];
  70. }
  71. return ['status' => false, 'data' => $arr];
  72. }
  73. //抽佣比例
  74. $brokerage = Config::where('field', 'brokerage')->first();
  75. $brokerage = $brokerage->val;
  76. $room = Room::where('room_id', $ru->room_id)->first();
  77. $room->status = 3;
  78. $room->save();
  79. $maxScore = 0;
  80. foreach ($list as $index => $item) {
  81. $a = bcmul($item->score, $room->base_score, 0);
  82. if ($index == 0) $maxScore = $item->score;
  83. //最赢着
  84. if ($item->score == $maxScore) {
  85. $item->brokerage = bcmul($a, $brokerage, 10);
  86. $item->real_score = bcsub($a, $item->brokerage, 10);
  87. }//
  88. //其余人员
  89. else {
  90. $item->brokerage = 0;
  91. $item->real_score = $a;
  92. }
  93. $item->status = 4;
  94. $item->save();
  95. $wallet = Wallet::where('member_id', $item->member_id)->first();
  96. $available_balance = $wallet->available_balance;
  97. // $user = User::where('member_id', $item->member_id)->first();
  98. $usdt = bcadd($available_balance, $item->real_score, 10);
  99. if ($usdt < 0) {
  100. $ttt = floatval($available_balance);
  101. $rr = "❌结算失败\n";
  102. $rr .= "您的余额不足\n\n";
  103. $rr .= "钱包余额:{$ttt} USDT\n";
  104. $ttt = floatval($item->real_score);
  105. $rr .= "结算金额:{$ttt} USDT\n";
  106. $rr .= "请充值后重新进行结算";
  107. $keyboard = [[
  108. ['text' => '➕充值', 'callback_data' => "topup@@topup"],
  109. ]];
  110. $errorMsg = json_encode([
  111. 'chat_id' => $item->member_id,
  112. 'text' => $rr,
  113. 'reply_markup' => json_encode(['inline_keyboard' => $keyboard])
  114. ]);
  115. throw new MessageException($errorMsg, 400);
  116. }
  117. $wallet->available_balance = $usdt;
  118. $wallet->save();
  119. $newRoomId = RoomService::resetRoomId($item->room_id);
  120. BalanceLogService::addLog(
  121. $item->member_id,
  122. $item->real_score,
  123. $available_balance,
  124. $wallet->available_balance,
  125. '结算',
  126. $item->id,
  127. '',
  128. $newRoomId
  129. );
  130. }
  131. $arr = [];
  132. foreach ($list as $item) {
  133. $text = "✅ 所有用户已经上传并且输入战绩结果,系统计算完毕!如果有纠纷,余额已变动,请及时联系在线客服\n";
  134. $text .= "🗂 {$room->game_name} {$room->participants}人 {$room->rounds}局\n";
  135. $text .= "房间号:{$room->room_id}\n";
  136. $text .= "底分:{$room->base_score} USDT\n";
  137. $text .= "-------------------------------------\n";
  138. foreach ($list as $item1) {
  139. $text .= "用户:{$item1->first_name}({$item1->game_id})\n";
  140. $text .= "战绩:{$item1->score}\n";
  141. $temp = floatval($item1->real_score);
  142. $text .= "盈亏:{$temp} USDT\n";
  143. $temp = floatval($item1->brokerage);
  144. if ($temp > 0) $text .= "抽佣:{$temp} USDT\n";
  145. $text .= "-------------------------------------\n";
  146. }
  147. $arr[] = [
  148. 'chat_id' => $item->member_id,
  149. 'text' => $text
  150. ];
  151. }
  152. return ['status' => true, 'data' => $arr];
  153. }
  154. $keyboard = [[
  155. ['text' => '返回', 'callback_data' => "games@@home{$ru->room_id}"],
  156. ]];
  157. $score = $score >= 0 ? "+{$score}" : $score;
  158. Cache::delete(get_step_key($chatId));
  159. return ['status' => false, 'data' => [[
  160. 'chat_id' => $chatId,
  161. 'text' => "🏆用户(ID:{$chatId})已上传战绩,并输入结果:\n{$score}。请等待其余用户完成上传,系统将在所有\n人输入后进行结算。",
  162. 'reply_markup' => json_encode(['inline_keyboard' => $keyboard])
  163. ]]];
  164. }
  165. //用户点击结算游戏
  166. public function settle($roomId, $chatId, $messageId)
  167. {
  168. $ru = RoomUser::where('room_id', $roomId)
  169. ->whereIn('status', [2, 3])
  170. ->where('member_id', $chatId)->first();
  171. if (!$ru) return ['chat_id' => $chatId, 'text' => '❌游戏未开始或已结束', 'message_id' => $messageId];
  172. $keyboard = [[
  173. ['text' => '返回', 'callback_data' => "games@@home{$roomId}"],
  174. ]];
  175. Cache::put(get_step_key($chatId), StepStatus::INPUT_IMAGE);
  176. return [
  177. 'chat_id' => $chatId,
  178. 'text' => "‼️ 请务必上传战绩截图!如出现纠纷,系统将以截图\n作为处理依据。若未上传战绩截图,产生的纠纷责任\n将由您自行承担。",
  179. // 'message_id' => $messageId,
  180. // 'reply_markup' => json_encode(['inline_keyboard' => $keyboard])
  181. ];
  182. }
  183. //用户发送结算截图
  184. public function photo($photo, $chatId)
  185. {
  186. $file = $this->telegram->getFile(['file_id' => $photo['file_id']]);
  187. $filePath = $file->getFilePath();
  188. $token = config('services.telegram.token');
  189. $file_url = "https://api.telegram.org/file/bot{$token}/{$filePath}";
  190. $file_info = pathinfo($file_url);
  191. $roomUser = RoomUser::whereIn('status', [2, 3])
  192. ->where('member_id', $chatId)->first();
  193. if ($roomUser) {
  194. $roomId = $roomUser->room_id;
  195. $save_path = storage_path("app/public/images/{$roomId}/");
  196. if (!is_dir($save_path)) {
  197. mkdir($save_path, 0777, true);
  198. }
  199. $fileName = "{$chatId}.{$file_info['extension']}";
  200. $save_path .= $fileName;
  201. file_put_contents($save_path, file_get_contents($file_url));
  202. $path = Storage::url("images/{$roomId}/" . $fileName);
  203. $roomUser->screenshot = $path;
  204. $roomUser->save();
  205. $text = "✅ 已收到您的战绩截图。请根据结果输入战绩分数:\n";
  206. $text .= "如果盈利 10,输入 10\n";
  207. $text .= "如果亏损 10,输入 -10\n";
  208. $text .= "系统将在所有人输入战绩后进行结算。";
  209. Cache::put(get_step_key($chatId), StepStatus::INPUT_SCORE);
  210. $keyboard = [[
  211. ['text' => '返回', 'callback_data' => "games@@home{$roomId}"],
  212. ]];
  213. return [
  214. 'chat_id' => $chatId,
  215. 'text' => $text,
  216. // 'reply_markup' => json_encode(['inline_keyboard' => $keyboard])
  217. ];
  218. }
  219. return false;
  220. }
  221. }