Files
webman-buildadmin/app/admin/controller/order/AdminWithdrawOrder.php

280 lines
9.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\admin\controller\order;
use app\common\controller\Backend;
use app\common\service\AdminWalletService;
use support\think\Db;
use support\Response;
use Throwable;
use Webman\Http\Request as WebmanRequest;
/**
* 管理员提现记录(审核)
*/
class AdminWithdrawOrder extends Backend
{
protected array $noNeedPermission = ['stats', 'approve', 'reject'];
protected ?object $model = null;
protected bool $modelValidate = false;
protected string|array $quickSearchField = ['id', 'order_no', 'receive_account', 'remark'];
protected string|array $defaultSortField = ['id' => '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(__('Please use approve/reject buttons to review'));
}
$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(__('This withdraw order has already been reviewed'));
}
$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(__('Approved'));
}
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(__('Please provide reject reason'));
}
$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(__('This withdraw order has already been reviewed'));
}
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(__('Rejected'));
}
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));
}
}