bank = new Bank(); } public function index(): void { $rawStart = request()->param('start/s'); $start = $rawStart ? strtotime($rawStart) : strtotime('today'); $rawEnd = request()->param('end/s'); $end = $rawEnd ? strtotime("$rawEnd +1 day") : strtotime('tomorrow'); if ($start > $end) { list($start, $end) = [$end, $start]; } $bankList = Bank::field([ 'id', 'bank_name', 'bank_account', 'current_balance', 'safe_alert', 'label_color', 'weigh', // 子查询:入款总额 "(SELECT SUM(money/100) FROM ba_user_money_log WHERE bank_id = ba_bank.id AND type in (1,3) and create_time BETWEEN {$start} AND {$end}) AS total_fund_in", // 子查询:出款总额 "(SELECT SUM(money/100) FROM ba_user_money_log WHERE bank_id = ba_bank.id AND type in (2,4) and create_time BETWEEN {$start} AND {$end}) AS total_fund_out", // 子查询:入款次数 "(SELECT COUNT(*) FROM ba_user_money_log WHERE bank_id = ba_bank.id AND type in (1,3) and create_time BETWEEN {$start} AND {$end}) AS count_fund_in", // 子查询:出款次数 "(SELECT COUNT(*) FROM ba_user_money_log WHERE bank_id = ba_bank.id AND type in (2,4) and create_time BETWEEN {$start} AND {$end}) AS count_fund_out", ]) ->where('status', 1) ->order('weigh', 'desc') ->order('id', 'desc') ->select() ->toArray(); foreach ($bankList as &$bank) { $bank['total_fund_in'] = (float)$bank['total_fund_in']; $bank['total_fund_out'] = (float)$bank['total_fund_out']; $bank['count_fund_in'] = (int)$bank['count_fund_in']; $bank['count_fund_out'] = (int)$bank['count_fund_out']; } unset($bank); $customer = Db::name('user_money_log')->field([ // 1. 总进款 (type = 1) 'ROUND(SUM(CASE WHEN type = 1 THEN money/100 ELSE 0 END), 2) AS total_deposit', // 2. 总出款 (type = 2) 'ROUND(SUM(CASE WHEN type = 2 THEN money/100 ELSE 0 END), 2) AS total_withdraw', // 3. 总进款次数 (type = 1 的记录总数) 'COUNT(CASE WHEN type = 1 THEN 1 END) AS count_deposit', // 4. 总出款次数 (type = 2 的记录总数) 'COUNT(CASE WHEN type = 2 THEN 1 END) AS count_withdraw', // 5. 活跃玩家数 (去重计算有多少个不同的 user_id 产生了流水) 'COUNT(DISTINCT user_id) AS active_player', //6. 首次充值 'COUNT(CASE WHEN label = 1 THEN 1 END) AS first_deposit', 'ROUND(SUM(CASE WHEN label = 2 THEN money/100 ELSE 0 END), 2) AS unclaim_amount', 'COUNT(CASE WHEN label = 2 THEN 1 END) AS unclaim_receipt', ]) ->whereBetweenTime('create_time', $start, $end) ->whereNull('created_by') ->find(); $customerData = [ 'total_deposit' => (float)($customer['total_deposit'] ?? 0), 'total_withdraw' => (float)($customer['total_withdraw'] ?? 0), 'count_deposit' => (int)($customer['count_deposit'] ?? 0), 'count_withdraw' => (int)($customer['count_withdraw'] ?? 0), 'active_player' => (int)($customer['active_player'] ?? 0), 'first_deposit' => (int)($customer['first_deposit'] ?? 0), 'unclaim_amount' => (float)($customer['unclaim_amount'] ?? 0), 'unclaim_receipt' => (int)($customer['unclaim_receipt'] ?? 0), ]; $limit = request()->param('limit/d') ?? 15; $bindFields = [ 'user' => ['jk_username'], 'bank' => ['bank_name'], 'admin' => ['id', 'username'], ]; $transaction = UserMoneyLog::withJoin($bindFields, 'left') ->with([ 'scoreLog' => function($query) { $query->field(['money_log_id', 'game_type', 'score']); } ]) ->whereBetweenTime('user_money_log.create_time', $start, $end) ->order('id', 'desc') ->paginate($limit); $transactionList = $transaction->items(); foreach ($transactionList as &$item) { $item['user_name'] = $item['user']['jk_username'] ?? ''; $item['bank_name'] = $item['bank']['bank_name'] ?? ''; $item['created_by'] = $item['admin']['username'] ?? 'WEBHOOK'; unset($item['user'], $item['bank'], $item['admin']); } unset($item); $transactionTotal = Db::name('user_money_log')->field([ // 1. 总进款 (type = 1) 'ROUND(SUM(CASE WHEN type = 1 THEN money/100 ELSE 0 END), 2) AS total_fund_in', // 2. 总出款 (type = 2) 'ROUND(SUM(CASE WHEN type = 2 THEN money/100 ELSE 0 END), 2) AS total_fund_out', ]) ->whereBetweenTime('create_time', $start, $end) ->find(); $this->success('', [ 'bank' => $bankList, 'customer' => $customerData, 'transaction'=> [ 'list' => $transactionList, 'count' => $transaction->total(), 'current_page' => $transaction->currentPage(), 'last_page' => $transaction->lastPage(), 'total_deposit' => (float)($transactionTotal['total_fund_in'] ?? 0), 'total_withdraw' => (float)($transactionTotal['total_fund_out'] ?? 0), ], ]); } public function bankTransact(): void { $data = $this->request->post(); if (!$data) { $this->error(__('Parameter %s can not be empty', [''])); } $money = isset($data['money']) ? (int)$data['money'] : 0; $bankFromId = isset($data['bank_from']) ? (int)$data['bank_from'] : 0; $bankToId = isset($data['bank_to']) ? (int)$data['bank_to'] : 0; if ($money <= 0) { $this->error(__('转账金额必须大于 0')); } if ($bankFromId === $bankToId) { $this->error(__('转出银行和转入银行不能相同')); } $adminId = $this->auth->getInfo()['id'] ?? null; \think\facade\Db::startTrans(); try { $bankFrom = Bank::where('id', $bankFromId)->where('status', 1)->lock(true)->find(); if (!$bankFrom) { throw new ValidateException('转出银行账户不存在或已被禁用'); } if ($bankFrom->current_balance < $money) { throw new ValidateException("转出银行【{$bankFrom->bank_name}】余额不足"); } $bankTo = Bank::where('id', $bankToId)->where('status', 1)->lock(true)->find(); if (!$bankTo) { throw new ValidateException('转入银行账户不存在或已被禁用'); } // 5. 更新转出银行账户余额 $bankFrom->current_balance -= $money; $bankFrom->save(); $logFrom = new UserMoneyLog(); $logFrom->save([ 'user_id' => 0, 'money' => $money, 'before' => $bankFrom->current_balance + $money, 'after' => $bankFrom->current_balance, 'type' => 4, 'bank_id' => $bankFromId, 'created_by' => $adminId, 'memo' => $data['remark'], 'category' => 2, 'create_time' => time() ]); $bankTo->current_balance += $money; $bankTo->save(); $logTo = new UserMoneyLog(); $logTo->save([ 'user_id' => 0, 'money' => $money, 'before' => $bankTo->current_balance - $money, 'after' => $bankTo->current_balance, 'type' => 3, 'bank_id' => $bankToId, 'created_by' => $adminId, 'memo' => $data['remark'], 'category' => 2, 'create_time' => time() ]); \think\facade\Db::commit(); $isCommitSuccess = true; } catch (ValidateException $e) { \think\facade\Db::rollback(); $this->error($e->getMessage()); } catch (Throwable $e) { \think\facade\Db::rollback(); trace($e->getMessage(), 'error'); $this->error(__('No rows were added')); } if ($isCommitSuccess) { $this->success(__('Added successfully')); } } public function newTransact(): void { if ($this->request->isPost()) { $data = $this->request->post(); if (!$data) { $this->error(__('Parameter %s can not be empty', [''])); } $result = false; $data = $this->excludeFields($data); $bank = Bank::where('id', $data['bank_id'])->where('status', 1)->lock(true)->find(); if (!$bank) { throw new ValidateException('银行账户不存在或已被禁用'); } if (in_array($data['type'], [2,4])) { $bank->current_balance -= $data['money']; } else { $bank->current_balance += $data['money']; } $bank->save(); $user_id = User::where('jk_username', $data['user_name'])->value('id'); if (!$user_id) { $this->error(__("The user can't find it", [''])); } $data['user_id'] = $user_id; $userMoneyLog = new UserMoneyLog(); $userMoneyLog->startTrans(); try { $data['created_by'] = $this->auth->getInfo()['id']; $result = $userMoneyLog->save($data); $userMoneyLog->commit(); } catch (Throwable $e) { $userMoneyLog->rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(__('Added successfully')); } else { $this->error(__('No rows were added')); } } } public function logHistory($id): void { $bindFields = [ 'admin' => ['id','username'], ]; $history = MoneyLogHistory::withJoin($bindFields, 'left') ->where('money_log_id', $id) ->select(); if (!empty($history)) { foreach ($history as &$item) { $item['admin_name'] = $item['admin']['username'] ?? ''; unset($item['admin']); } unset($item); } $this->success('', $history); } public function editTransact(): void { $userMoneyLog = new UserMoneyLog(); $pk = $userMoneyLog->getPk(); $id = $this->request->param($pk); $row = $userMoneyLog->find($id); if (!$row) { $this->error(__('Record not found')); } if ($this->request->isPost()) { $data = $this->request->post(); if (!$data) { $this->error(__('Parameter %s can not be empty', [''])); } $result = false; $userMoneyLog->startTrans(); try { $result = $row->save($data); $userMoneyLog->commit(); } catch (Throwable $e) { $userMoneyLog->rollback(); $this->error($e->getMessage()); } if ($result !== false) { $this->success(__('Update successful')); } else { $this->error(__('No rows updated')); } return; } $this->success('', [ 'row' => $row ]); } public function delTransact($id): void { $result = false; try { $result = Db::table('ba_user_money_log')->delete($id); } catch (Throwable $e) { $this->error(__('%d records and files have been deleted', [1]) . $e->getMessage()); } if ($result) { $this->success(__('%d records and files have been deleted', [1])); } else { $this->error(__('No rows were deleted')); } } }