初始化

This commit is contained in:
2026-03-02 13:44:38 +08:00
commit 05b785083c
677 changed files with 58662 additions and 0 deletions

View File

@@ -0,0 +1,383 @@
<?php
namespace addons\webman\controller;
use addons\webman\model\PlayerTag;
use addons\webman\model\PlayerWithdrawRecord;
use ExAdmin\ui\component\common\Html;
use ExAdmin\ui\component\common\Icon;
use ExAdmin\ui\component\detail\Detail;
use ExAdmin\ui\component\grid\avatar\Avatar;
use ExAdmin\ui\component\grid\badge\Badge;
use ExAdmin\ui\component\grid\card\Card;
use ExAdmin\ui\component\grid\grid\Actions;
use ExAdmin\ui\component\grid\grid\Editable;
use ExAdmin\ui\component\grid\grid\Filter;
use ExAdmin\ui\component\grid\grid\Grid;
use ExAdmin\ui\component\grid\image\Image;
use ExAdmin\ui\component\grid\statistic\Statistic;
use ExAdmin\ui\component\grid\tag\Tag;
use ExAdmin\ui\component\grid\ToolTip;
use ExAdmin\ui\component\layout\layout\Layout;
use ExAdmin\ui\component\layout\Row;
use ExAdmin\ui\support\Request;
use Illuminate\Support\Str;
use support\Cache;
/**
* 提现记录
*/
class WithdrawRecordController
{
protected $model;
public function __construct()
{
$this->model = plugin()->webman->config('database.player_withdraw_record_model');
}
/**
* 提現
* @auth true
*/
public function index(): Grid
{
return Grid::create(new $this->model(), function (Grid $grid) {
$grid->title(admin_trans('player_withdraw_record.title'));
$grid->model()->with(['player', 'channel', 'player.player_extend'])->orderBy('created_at', 'desc');
$exAdminFilter = Request::input('ex_admin_filter', []);
if (!empty($exAdminFilter)) {
if (isset($exAdminFilter['created_at_start']) && !empty($exAdminFilter['created_at_start'])) {
$grid->model()->where('created_at', '>=', $exAdminFilter['created_at_start']);
}
if (isset($exAdminFilter['created_at_end']) && !empty($exAdminFilter['created_at_end'])) {
$grid->model()->where('created_at', '<=', $exAdminFilter['created_at_end']);
}
if (isset($exAdminFilter['finish_time_start']) && !empty($exAdminFilter['finish_time_start'])) {
$grid->model()->where('finish_time', '>=', $exAdminFilter['finish_time_start']);
}
if (isset($exAdminFilter['finish_time_end']) && !empty($exAdminFilter['finish_time_end'])) {
$grid->model()->where('finish_time', '<=', $exAdminFilter['finish_time_end']);
}
if (!empty($exAdminFilter['player']['uuid'])) {
$grid->model()->whereHas('player', function ($query) use ($exAdminFilter) {
$query->where('uuid', 'like', '%' . $exAdminFilter['player']['uuid'] . '%');
});
}
if (!empty($exAdminFilter['player']['name'])) {
$grid->model()->whereHas('player', function ($query) use ($exAdminFilter) {
$query->where('name', 'like', '%' . $exAdminFilter['player']['name'] . '%');
});
}
if (!empty($exAdminFilter['department_id'])) {
$grid->model()->where('department_id', $exAdminFilter['department_id']);
}
if (!empty($exAdminFilter['type'])) {
$grid->model()->where('type', $exAdminFilter['type']);
}
if (!empty($exAdminFilter['status'])) {
$grid->model()->where('status', $exAdminFilter['status']);
}
if (!empty($exAdminFilter['tradeno'])) {
$grid->model()->where('tradeno', $exAdminFilter['tradeno']);
}
}
$query = clone $grid->model();
$totalData = $query->selectRaw(
'ifNull(sum(money), 0) as total_money,
ifNull(sum(IF(type = 6, money,0)), 0) as total_skl_money'
)->first();
$layout = Layout::create();
$layout->row(function (Row $row) use ($totalData) {
$row->gutter([10, 0]);
$row->column(
Card::create([
Row::create()->column(Statistic::create()->title(admin_trans('player_withdraw_record.total_money'))
->value($totalData['total_money'])
->style([
'font-size' => '15px',
'text-align' => 'center'
])),
])->bodyStyle([
'display' => 'flex',
'align-items' => 'center',
'height' => '72px'
])->hoverable()->headStyle(['height' => '0px', 'border-bottom' => '0px', 'min-height' => '0px'])
, 8);
$row->column(
Card::create([
Row::create()->column(Statistic::create()->title(admin_trans('player_withdraw_record.total_inmoney'))
->value(bcadd(bcsub($totalData['total_money'], $totalData['total_skl_money'], 3), bcmul($totalData['total_skl_money'], 1.008, 3), 3))
->style([
'font-size' => '15px',
'text-align' => 'center'
])),
])->bodyStyle([
'display' => 'flex',
'align-items' => 'center',
'height' => '72px'
])->hoverable()->headStyle(['height' => '0px', 'border-bottom' => '0px', 'min-height' => '0px'])
, 8);
})->style(['background' => '#fff']);
$grid->header($layout);
$grid->bordered(true);
$grid->autoHeight();
$grid->column('id', admin_trans('player_withdraw_record.fields.id'))->align('center')->fixed(true);
$grid->column('player.name', admin_trans('player.fields.name'))->display(function ($val, PlayerWithdrawRecord $data) {
$image = (isset($data->player->avatar) && !empty($data->player->avatar)) ? Avatar::create()->src($data->player->avatar) : Avatar::create()->icon(Icon::create('UserOutlined'));
return Html::create()->content([
$image,
Html::div()->content($val)
])->style(['cursor' => 'pointer'])->modal($this->playerDetail([
'phone' => $data->player->phone ?? '',
'name' => $data->player->name ?? '',
'address' => $data->player->player_extend->address ?? '',
'email' => $data->player->player_extend->email ?? '',
'line' => $data->player->player_extend->line ?? '',
'created_at' => isset($data->player->created_at) && !empty($data->player->created_at) ? date('Y-m-d H:i:s', strtotime($data->player->created_at)) : '',
]));
})->align('center')->fixed(true);
$grid->column('player.uuid', admin_trans('player.fields.uuid'))->display(function ($val, PlayerWithdrawRecord $data) {
return $data->player->uuid;
})->align('center')->fixed(true);
$grid->column('tradeno', admin_trans('player_withdraw_record.fields.tradeno'))->copy()->align('center');
$grid->column('money', admin_trans('player_withdraw_record.fields.money'))->display(function ($val, PlayerWithdrawRecord $data) {
return bcdiv($val,$data->rate, 2) . ' ' . ($data->currency == 'TALK' ? 'Q币' : $data->currency);
})->align('center')->sortable();
$grid->column('inmoney', admin_trans('player_recharge_record.fields.inmoney'))->display(function ($val, PlayerWithdrawRecord $data) {
if ($data->type == PlayerWithdrawRecord::TYPE_ESPAYOUT) {
$ratio = 1.005;
} elseif ($data->type == PlayerWithdrawRecord::TYPE_ONEPAYOUT){
$ratio = 1.008;
} elseif ($data->type == PlayerWithdrawRecord::TYPE_SKLPAYOUT){
$ratio = 1.008;
} else {
$ratio = 1;
}
if ($data->currency == 'USDT') {
return bcdiv($val,$data->rate, 2) . ' ' . ($data->currency);
}
return $data->money * $ratio . ' ' . ($data->currency);
})->align('center');
$grid->column('coins', admin_trans('player_withdraw_record.fields.coins'))->align('center');
$grid->column('type', admin_trans('player_withdraw_record.fields.type'))->display(function ($val) {
switch ($val) {
case PlayerWithdrawRecord::TYPE_SELF:
return Tag::create(admin_trans('player_withdraw_record.type.' . $val))
->color('#3b5999');
case PlayerWithdrawRecord::TYPE_ARTIFICIAL:
return Tag::create(admin_trans('player_withdraw_record.type.' . $val))
->color('#cd201f');
case PlayerWithdrawRecord::TYPE_USDT:
return Tag::create(admin_trans('player_withdraw_record.type.' . $val))
->color('#2db7f5');
case PlayerWithdrawRecord::TYPE_SKLPAYOUT:
return Tag::create(admin_trans('player_withdraw_record.type.' . $val))
->color('#108ee9');
default:
return '';
}
})->align('center');
$grid->column('withdraw_setting_info',
admin_trans('player_withdraw_record.player_bank'))->display(function (
$val,
PlayerWithdrawRecord $data
) {
$info = [];
switch ($data->type) {
case PlayerWithdrawRecord::TYPE_USDT:
$info[] = Html::markdown('- ' . admin_trans('channel_recharge_setting.fields.wallet_address') . ': ' . $data->wallet_address);
$info[] = Html::div()->content(Image::create()
->width(40)
->src($data->qr_code));
break;
case PlayerWithdrawRecord::TYPE_SELF:
$info[] = Html::markdown('- ' . admin_trans('player_withdraw_record.fields.account_name') . ': ' . $data->account_name);
$info[] = Html::markdown('- ' . admin_trans('player_withdraw_record.fields.bank_name') . ': ' . $data->bank_name);
$info[] = Html::markdown('- ' . admin_trans('player_withdraw_record.fields.account') . ': ' . $data->account);
break;
}
return Html::create()->content($info);
})->align('left');
$grid->column('status', admin_trans('player_withdraw_record.fields.status'))
->display(function ($value, PlayerWithdrawRecord $data) {
$rejectReason = $data->reject_reason;
switch ($value) {
case PlayerWithdrawRecord::STATUS_SUCCESS:
$tag = Tag::create(admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_SUCCESS))->color('#87d068');
break;
case PlayerWithdrawRecord::STATUS_WAIT:
$tag = Tag::create(admin_trans('player_withdraw_record.status_wait'))->color('#108ee9');
break;
case PlayerWithdrawRecord::STATUS_FAIL:
$tag = Tag::create(admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_FAIL))->color('#f50');
break;
case PlayerWithdrawRecord::STATUS_PENDING_REJECT:
$tag = Tag::create(admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_PENDING_REJECT))->color('#cd201f');
break;
case PlayerWithdrawRecord::STATUS_PENDING_PAYMENT:
$tag = Tag::create(admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_PENDING_PAYMENT))->color('#3b5999');
break;
case PlayerWithdrawRecord::STATUS_CANCEL:
case PlayerWithdrawRecord::STATUS_SYSTEM_CANCEL:
$tag = Tag::create(admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_CANCEL))->color('#2db7f5');
break;
default:
$tag = '';
}
if (!empty($rejectReason)) {
return ToolTip::create(Badge::create(
$tag
)->count('!')->title(''))->title($rejectReason)->color('orange');
} else {
return $tag;
}
})->align('center')->sortable();
$grid->column('channel.name', admin_trans('player_withdraw_record.fields.department_id'))->align('center');
$grid->column('finish_time', admin_trans('player_withdraw_record.fields.finish_time'))->sortable()->align('center');
$grid->column('created_at', admin_trans('player_withdraw_record.fields.created_at'))->sortable()->align('center');
$grid->column('player_tag', admin_trans('player_withdraw_record.fields.player_tag'))
->display(function ($value) {
return $this->handleTagIds($value);
})
->editable(
Editable::checkboxTag()
->options($this->getPlayerTagOptionsFilter())
)->width('150px');
$grid->column('remark', admin_trans('player_withdraw_record.fields.remark'))->display(function ($value) {
return Str::of($value)->limit(20, ' (...)');
})->editable(
(new Editable)->textarea('remark')
->showCount()
->rows(5)
->rule(['max:255' => admin_trans('player_withdraw_record.fields.remark')])
)->width('150px')->align('center');
$grid->hideDelete();
$grid->hideSelection();
$grid->expandFilter();
$grid->actions(function (Actions $actions) {
$actions->hideDel();
$actions->hideEdit();
});
$grid->filter(function (Filter $filter) {
$filter->like()->text('player.uuid')->placeholder(admin_trans('player.fields.uuid'));
$filter->like()->text('player.name')->placeholder(admin_trans('player.fields.name'));
$filter->eq()->select('department_id')
->showSearch()
->style(['width' => '200px'])
->dropdownMatchSelectWidth()
->placeholder(admin_trans('player_withdraw_record.fields.department_id'))
->remoteOptions(admin_url(['addons-webman-controller-ChannelController', 'getDepartmentOptions']));
$filter->eq()->select('type')
->showSearch()
->style(['width' => '200px'])
->dropdownMatchSelectWidth()
->placeholder(admin_trans('player_withdraw_record.fields.type'))
->options([
PlayerWithdrawRecord::TYPE_USDT => admin_trans('player_withdraw_record.type.' . PlayerWithdrawRecord::TYPE_USDT),
PlayerWithdrawRecord::TYPE_SELF => admin_trans('player_withdraw_record.type.' . PlayerWithdrawRecord::TYPE_SELF),
PlayerWithdrawRecord::TYPE_ARTIFICIAL => admin_trans('player_withdraw_record.type.' . PlayerWithdrawRecord::TYPE_ARTIFICIAL),
PlayerWithdrawRecord::TYPE_SKLPAYOUT => admin_trans('player_withdraw_record.type.' . PlayerWithdrawRecord::TYPE_SKLPAYOUT),
]);
$filter->eq()->select('status')
->showSearch()
->style(['width' => '200px'])
->dropdownMatchSelectWidth()
->placeholder(admin_trans('player_withdraw_record.fields.status'))
->options([
PlayerWithdrawRecord::STATUS_WAIT => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_WAIT),
PlayerWithdrawRecord::STATUS_SUCCESS => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_SUCCESS),
PlayerWithdrawRecord::STATUS_FAIL => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_FAIL),
PlayerWithdrawRecord::STATUS_PENDING_PAYMENT => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_PENDING_PAYMENT),
PlayerWithdrawRecord::STATUS_PENDING_REJECT => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_PENDING_REJECT),
PlayerWithdrawRecord::STATUS_CANCEL => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_CANCEL),
PlayerWithdrawRecord::STATUS_SYSTEM_CANCEL => admin_trans('player_withdraw_record.status.' . PlayerWithdrawRecord::STATUS_SYSTEM_CANCEL),
]);
$filter->like()->text('tradeno')->placeholder(admin_trans('player_withdraw_record.fields.tradeno'));
$filter->form()->hidden('created_at_start');
$filter->form()->hidden('created_at_end');
$filter->form()->dateTimeRange('created_at_start', 'created_at_end', '')->placeholder([admin_trans('public_msg.created_at_start'), admin_trans('public_msg.created_at_end')]);
$filter->form()->hidden('finish_time_start');
$filter->form()->hidden('finish_time_end');
$filter->form()->dateTimeRange('finish_time_start', 'finish_time_end', '')->placeholder([admin_trans('player_withdraw_record.fields.finish_time'), admin_trans('player_withdraw_record.fields.finish_time')]);
});
});
}
/**
* 处理标签
* @param array $value
* @return Html
*/
public function handleTagIds(array $value): Html
{
$options = $this->getPlayerTagOptions($value);
$html = Html::create();
foreach ($options as $option) {
$html->content(
Tag::create($option)
->color('success')
);
}
return $html;
}
/**
* 获取玩家标签选项(筛选id)
* @param array $ids
* @return array
*/
public function getPlayerTagOptions(array $ids = []): array
{
$idsStr = json_encode($ids);
$cacheKey = md5("player_tag_options_ids_$idsStr");
if (Cache::has($cacheKey)) {
return Cache::get($cacheKey);
} else {
if (!empty($ids)) {
$data = (new PlayerTag())->whereIn('id', $ids)->select(['name', 'id'])->get()->toArray();
$data = $data ? array_column($data, 'name', 'id') : [];
Cache::set($cacheKey, $data, 24 * 60 * 60);
return $data;
}
return [];
}
}
/**
* 获取玩家标签(筛选id)
* @return array
*/
public function getPlayerTagOptionsFilter(): array
{
$cacheKey = "doc_player_tag_options_filter";
if (Cache::has($cacheKey)) {
return Cache::get($cacheKey);
} else {
$data = (new PlayerTag())->select(['name', 'id'])->get()->toArray();
$data = $data ? array_column($data, 'name', 'id') : [];
Cache::set($cacheKey, $data, 24 * 60 * 60);
return $data;
}
}
/**
* 玩家详情
* @param array $data
* @return Detail
*/
public function playerDetail(array $data): Detail
{
return Detail::create($data, function (Detail $detail) {
$detail->item('name', admin_trans('player.fields.name'));
$detail->item('address', admin_trans('player_extend.fields.address'));
$detail->item('email', admin_trans('player_extend.fields.email'));
$detail->item('phone', admin_trans('player.fields.phone'));
$detail->item('line', admin_trans('player_extend.fields.line'));
$detail->item('created_at', admin_trans('player.fields.created_at'));
})->layout('vertical');
}
}