'desc']; protected string|array $orderGuarantee = ['id' => 'desc']; protected array $withJoinTable = ['admin', 'channel', 'reviewAdmin']; protected function initController(WebmanRequest $request): ?Response { $this->model = new \app\common\model\AdminWithdrawOrder(); return null; } protected function _index(): Response { if ($this->request && $this->request->get('select')) { return $this->select($this->request); } list($where, $alias, $limit, $order) = $this->queryBuilder(); $table = strtolower($this->model->getTable()); $mainShort = $alias[$table] ?? ''; if ($mainShort !== '' && $this->auth && !$this->auth->isSuperAdmin()) { $where[] = [$mainShort . '.channel_id', 'in', $this->getCurrentAdminChannelIds()]; } $res = $this->model ->withJoin($this->withJoinTable, $this->withJoinType) ->with($this->withJoinTable) ->visible([ 'admin' => ['username'], 'channel' => ['name'], 'reviewAdmin' => ['username'], ]) ->alias($alias) ->where($where) ->order($order) ->paginate($limit); $list = $res->items(); foreach ($list as $idx => $item) { $list[$idx]['can_review'] = $this->canReviewOrder(is_array($item) ? $item : []) ? 1 : 0; } return $this->success('', [ 'list' => $list, 'total' => $res->total(), 'remark' => get_route_remark(), ]); } protected function _edit(): Response { $pk = $this->model->getPk(); $id = $this->request ? ($this->request->post($pk) ?? $this->request->get($pk)) : null; if ($id === null || $id === '') { return $this->error(__('Parameter error')); } if ($this->request && $this->request->method() === 'POST') { return $this->error('请使用通过/拒绝按钮审核'); } $row = $this->loadWithRelations(intval(strval($id))); if (!$row) { return $this->error(__('Record not found')); } if (!$this->canReviewOrder($row)) { return $this->error(__('You have no permission')); } return $this->success('', ['row' => $row]); } public function approve(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $id = intval(strval($request->post('id', 0))); if ($id <= 0) { return $this->error(__('Parameter error')); } $order = Db::name('admin_withdraw_order')->where('id', $id)->find(); if (!is_array($order)) { return $this->error(__('Record not found')); } if (!$this->canReviewOrder($order)) { return $this->error(__('You have no permission')); } if (intval($order['status'] ?? 0) !== 0) { return $this->error('该提现订单已审核'); } $remark = trim((string) $request->post('remark', '')); Db::startTrans(); try { AdminWalletService::approveWithdraw($order, intval($this->auth->id), $remark); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success('审核通过'); } public function reject(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } if ($request->method() !== 'POST') { return $this->error(__('Parameter error')); } $id = intval(strval($request->post('id', 0))); if ($id <= 0) { return $this->error(__('Parameter error')); } $remark = trim((string) $request->post('remark', '')); if ($remark === '') { return $this->error('请填写拒绝原因'); } $order = Db::name('admin_withdraw_order')->where('id', $id)->find(); if (!is_array($order)) { return $this->error(__('Record not found')); } if (!$this->canReviewOrder($order)) { return $this->error(__('You have no permission')); } if (intval($order['status'] ?? 0) !== 0) { return $this->error('该提现订单已审核'); } Db::startTrans(); try { AdminWalletService::rejectWithdraw($order, intval($this->auth->id), $remark); Db::commit(); } catch (Throwable $e) { Db::rollback(); return $this->error($e->getMessage()); } return $this->success('审核拒绝完成'); } public function stats(WebmanRequest $request): Response { $response = $this->initializeBackend($request); if ($response !== null) { return $response; } $query = Db::name('admin_withdraw_order'); if ($this->auth && !$this->auth->isSuperAdmin()) { $query->where('channel_id', 'in', $this->getCurrentAdminChannelIds()); } $rows = $query->field(['status', 'amount', 'actual_amount'])->select()->toArray(); $total = count($rows); $pending = 0; $approved = 0; $rejected = 0; $totalAmount = '0.00'; $pendingAmount = '0.00'; $approvedAmount = '0.00'; foreach ($rows as $row) { $status = intval($row['status'] ?? 0); $amount = bcadd(strval($row['amount'] ?? '0'), '0', 2); $actual = bcadd(strval($row['actual_amount'] ?? '0'), '0', 2); $totalAmount = bcadd($totalAmount, $amount, 2); if ($status === 0) { $pending++; $pendingAmount = bcadd($pendingAmount, $amount, 2); } elseif ($status === 1) { $approved++; $approvedAmount = bcadd($approvedAmount, $actual, 2); } elseif ($status === 2) { $rejected++; } } return $this->success('', [ 'total_count' => $total, 'pending_count' => $pending, 'approved_count' => $approved, 'rejected_count' => $rejected, 'total_amount' => $totalAmount, 'pending_amount' => $pendingAmount, 'approved_amount' => $approvedAmount, ]); } private function loadWithRelations(int $id): ?array { $row = $this->model ->withJoin($this->withJoinTable, $this->withJoinType) ->with($this->withJoinTable) ->visible([ 'admin' => ['username'], 'channel' => ['name'], 'reviewAdmin' => ['username'], ]) ->where($this->model->getTable() . '.id', $id) ->find(); return $row ? $row->toArray() : null; } private function canReviewOrder(array $order): bool { if (!$this->auth) { return false; } if ($this->auth->isSuperAdmin()) { return true; } $channelId = intval($order['channel_id'] ?? 0); if ($channelId <= 0) { return false; } $allowed = $this->getCurrentAdminChannelIds(); return in_array($channelId, $allowed, true); } /** * 当前管理员可审核的渠道(优先取自身 channel_id,同时兼容角色组继承链上的 channel_id) * * @return int[] */ private function getCurrentAdminChannelIds(): array { $uid = intval($this->auth->id ?? 0); if ($uid <= 0) { return [0]; } $channelIds = []; $selfChannelId = intval(Db::name('admin')->where('id', $uid)->value('channel_id') ?? 0); if ($selfChannelId > 0) { $channelIds[] = $selfChannelId; } $groupIds = Db::name('admin_group_access')->where('uid', $uid)->column('group_id'); if ($groupIds !== []) { $groupIds = array_values(array_unique(array_merge($groupIds, $this->auth->getAdminChildGroups()))); $rows = Db::name('admin_group') ->field(['id', 'channel_id']) ->where('id', 'in', $groupIds) ->whereNotNull('channel_id') ->select() ->toArray(); foreach ($rows as $row) { $cid = intval($row['channel_id'] ?? 0); if ($cid > 0) { $channelIds[] = $cid; } } } return $channelIds === [] ? [0] : array_values(array_unique($channelIds)); } }