This commit is contained in:
2023-01-12 14:48:14 +08:00
parent 5b8901281c
commit 8c05c7a165
51 changed files with 0 additions and 2195 deletions

View File

@@ -1,2 +0,0 @@
.idea
vendor

View File

@@ -1,13 +0,0 @@
<?php
return [
'name' => '提现模块',
'is_chain' => false,//提现账户是否是区块链true 是 false 否
'account' => 'coins',//提现账户
'withdraw_no_counter_length' => 8,
'model' => [
'account_rules' => Modules\User\Models\AccountRule::class,//规则表
'chain_money' => App\Models\DayDataChain::class,//记录金额表
],
];

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateBanksTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraw_banks', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('cover')->nullable();
$table->boolean('status');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraw_banks');
}
}

View File

@@ -1,44 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateWithdrawsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraws', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->index();
$table->unsignedBigInteger('bank_account_id')->nullable()->index();
$table->unsignedBigInteger('alipay_account_id')->nullable()->index();
$table->string('withdraw_no', 32)->comment('提现单号');
$table->decimal('amount')->unsigned(0)->comment('提现金额');
$table->decimal('tax')->unsigned()->comment('手续费');
$table->decimal('take')->unsigned()->comment('实际到账金额');
$table->boolean('status');
$table->boolean('type');
$table->json('source')->nullable();
$table->timestamp('paid_at')->nullable()->comment('付款成功时间');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraws');
}
}

View File

@@ -1,39 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAccountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraw_bank_accounts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('bank_id');
$table->string('name')->comment('收款人姓名');
$table->string('no')->comment('银行卡号');
$table->string('branch_name')->nullable()->comment('支行名称');
$table->string('mobile')->comment('收款人手机号');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraw_bank_accounts');
}
}

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateConfigsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraw_configs', function (Blueprint $table) {
$table->id();
$table->string('name', 100);
$table->string('slug', 100);
$table->string('value', 100);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraw_configs');
}
}

View File

@@ -1,36 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraw_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('withdraw_id')->index();
$table->boolean('status');
$table->string('remark')->nullable();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraw_logs');
}
}

View File

@@ -1,37 +0,0 @@
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAlipayAccountsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('withdraw_alipay_accounts', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->index();
$table->text('name')->comment('支付宝姓名');
$table->text('identity_type')->comment('标识类型:ALIPAY_USER_ID 支付宝的会员ID,ALIPAY_LOGON_ID支付宝登录号支持邮箱和手机号格式');
$table->text('identity')->comment('支付宝账号');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('withdraw_alipay_accounts');
}
}

View File

@@ -1,8 +0,0 @@
<?php
namespace Modules\Withdraw\Events;
class WithdrawAuditPass extends WithdrawEvent
{
}

View File

@@ -1,8 +0,0 @@
<?php
namespace Modules\Withdraw\Events;
class WithdrawAuditReject extends WithdrawEvent
{
}

View File

@@ -1,25 +0,0 @@
<?php
namespace Modules\Withdraw\Events;
use Illuminate\Queue\SerializesModels;
use Modules\Withdraw\Models\Withdraw;
class WithdrawEvent
{
use SerializesModels;
public $withdraw;
/**
* OpenVip constructor.
*
* @param \Modules\Withdraw\Models\Withdraw $withdraw
*/
public function __construct(Withdraw $withdraw)
{
$this->withdraw = $withdraw;
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Admin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use Modules\Withdraw\Models\Account;
class AccountController extends AdminController
{
protected $title = '用户银行账户';
public function grid(): Grid
{
$grid = new Grid(new Account());
$grid->model()->with(['user.info']);
$grid->disableCreateButton();
$grid->actions(function ($actions) {
$actions->disableDelete();
$actions->disableView();
});
$grid->filter(function (Grid\Filter $filter) {
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('user.username', '用户账号');
$filter->like('no', '卡号');
});
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('user.info.nickname', '用户昵称');
});
});
$grid->column('id', '#ID#');
$grid->column('用户')->display(function () {
return $this->user->username."({$this->user->info->nickname})";
});
$grid->column('name', '提款人');
$grid->column('bank.name', '开户行');
$grid->column('no', '卡号');
$grid->column('created_at', '创建时间');
return $grid;
}
}

View File

@@ -1,48 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Admin\Actions;
use Encore\Admin\Actions\RowAction;
use Encore\Admin\Facades\Admin;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Modules\Withdraw\Models\Withdraw;
class WithdrawAudit extends RowAction
{
public $name = '提现审核';
public function handle(Withdraw $withdraw, Request $request)
{
$status = $request->status;
$remark = $request->remark;
try {
if ($status == Withdraw::STATUS_PASS) {
$withdraw->pass($remark);
}
if ($status == Withdraw::STATUS_REJECT) {
$withdraw->reject($remark);
}
return $this->response()->success('操作成功')->refresh();
} catch (\Exception $e) {
return $this->response()->error($e->getMessage())->refresh();
}
}
public function form(Model $model)
{
$this->select('status', '状态')
->options([
Withdraw::STATUS_PASS => '通过',
Withdraw::STATUS_REJECT => '驳回',
])
->required();
$this->text('remark', '说明');
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Admin;
use App\Admin\Traits\WithUploads;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Modules\Withdraw\Models\Bank;
class BankController extends AdminController
{
use WithUploads;
protected $title = '银行列表';
public function grid(): Grid
{
$grid = new Grid(new Bank());
$grid->filter(function (Grid\Filter $filter) {
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('name', '银行名称');
});
});
$grid->column('id', '#ID#');
$grid->column('cover', '图标')->image('', 60, 60);
$grid->column('name', '银行名称');
$grid->column('status', '状态')->switch([
'on' => ['value' => 1, 'text' => '打开', 'color' => 'success'],
'off' => ['value' => 0, 'text' => '关闭', 'color' => 'danger'],
]);
$grid->column('created_at', '创建时间');
return $grid;
}
public function form()
{
$form = new Form(new Bank());
$this->cover($form);
$form->text('name', '银行名称')->required();
$form->switch('status', '是否开启')->default(1);
return $form;
}
}

View File

@@ -1,40 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Admin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Form;
use Encore\Admin\Grid;
use Modules\Withdraw\Models\Config;
class ConfigController extends AdminController
{
protected $title = '配置';
public function grid(): Grid
{
$grid = new Grid(new Config());
$grid->disableFilter();
$grid->column('id', '#ID#');
$grid->column('name', '名称');
$grid->column('slug', '别名');
$grid->column('value', '值');
$grid->column('created_at', '创建时间');
return $grid;
}
public function form(): Form
{
$form = new Form(new Config());
$form->text('name', '名称')->required();
$form->text('slug', '别名')->required();
$form->text('value', '值')->required();
return $form;
}
}

View File

@@ -1,74 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Admin;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Grid;
use Modules\Withdraw\Http\Controllers\Admin\Actions\WithdrawAudit;
use Modules\Withdraw\Models\Withdraw;
use Modules\Withdraw\Selectable\AccountAble;
class WithdrawController extends AdminController
{
protected $title = '提现列表';
protected function grid(): Grid
{
$grid = new Grid(new Withdraw());
$grid->model()->with(['user.info'])->latest();
$grid->disableCreateButton();
$grid->actions(function ($actions) {
$actions->disableDelete();
$actions->disableView();
$actions->disableEdit();
if ($actions->row->canAudit()) {
$actions->add(new WithdrawAudit());
}
});
$grid->filter(function (Grid\Filter $filter) {
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('user.username', '账户');
$filter->equal('status', '状态')->select(Withdraw::STATUS);
$filter->like('bankAccount.branch_name', '开户行');
});
$filter->column(1 / 2, function (Grid\Filter $filter) {
$filter->like('user.info.nickname', '昵称');
$filter->like('bankAccount.no', '卡号');
});
});
$grid->column('id', 'ID');
$grid->column('用户')->display(function () {
return $this->user->username."({$this->user->info->nickname})";
});
$grid->column('提现账号')
->display(function () {
return '查看';
})
->modal('提现账号', AccountAble::class);
$grid->column('amount', '提现金额');
$grid->column('tax', '手续费');
$grid->column('take', '实到金额');
$grid->column('type', '提现类型')
->using(Withdraw::TYPES)
->label(Withdraw::TYPES_LABEL);
$grid->column('status', '状态')
->using(Withdraw::STATUS)
->label([
Withdraw::STATUS_INIT => 'info',
Withdraw::STATUS_PASS => 'success',
Withdraw::STATUS_REJECT => 'danger',
]);
$grid->column('paid_at', '审核时间');
$grid->column('source', '备份数据')->hide();
$grid->column('created_at', '申请时间');
return $grid;
}
}

View File

@@ -1,144 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Jason\Api\Api;
use Modules\Withdraw\Http\Requests\UserBankAccountRequest;
use Modules\Withdraw\Http\Requests\UserEditBankAccountRequest;
use Modules\Withdraw\Http\Resources\Account\UserBankAccountCollection;
use Modules\Withdraw\Http\Resources\Account\UserBankAccountResource;
use Modules\Withdraw\Http\Resources\Bank\BankResource;
use Modules\Withdraw\Models\Account;
use Modules\Withdraw\Models\Bank;
class AccountController extends Controller
{
/**
* Notes: 我的银行账户
*
* @Author: 玄尘
* @Date : 2021/9/26 13:57
* @return JsonResponse
*/
public function index(): JsonResponse
{
$user = Api::user();
$lists = Account::query()->where('user_id', $user->id)->paginate();
return $this->success(new UserBankAccountCollection($lists));
}
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/9/26 14:09
* @return JsonResponse
*/
public function create(): JsonResponse
{
$banks = Bank::where('status', Bank::STATUS_OPEN)->get();
$data = [
'banks' => BankResource::collection($banks),
];
return $this->success($data);
}
/***
* Notes: 提交
*
* @Author: 玄尘
* @Date : 2021/9/26 14:11
* @param UserBankAccountRequest $request
* @return JsonResponse|mixed
*/
public function store(UserBankAccountRequest $request)
{
$user = Api::user();
try {
$user->bankAccounts()->create([
'name' => $request->name,
'mobile' => $request->mobile,
'no' => $request->no,
'branch_name' => $request->branch_name ?? '',
'bank_id' => $request->bank_id,
]);
return $this->success('添加成功');
} catch (\Exception $exception) {
return $this->failed($exception->getMessage());
}
}
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/9/26 14:23
* @param Account $account
*/
public function edit(Account $account): JsonResponse
{
$banks = Bank::where('status', Bank::STATUS_OPEN)->get();
$data = [
'banks' => BankResource::collection($banks),
'info' => new UserBankAccountResource($account),
];
return $this->success($data);
}
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/9/26 14:26
* @param UserEditBankAccountRequest $request
* @param Account $account
* @return JsonResponse|mixed
*/
public function update(UserEditBankAccountRequest $request, Account $account)
{
try {
$account->update([
'name' => $request->name,
'mobile' => $request->mobile,
'no' => $request->no,
'branch_name' => $request->branch_name,
'bank_id' => $request->bank_id,
]);
return $this->success('编辑成功');
} catch (\Exception $exception) {
return $this->failed($exception->getMessage());
}
}
/**
* Notes: 删除
*
* @Author: 玄尘
* @Date : 2021/9/26 15:02
* @param Account $account
* @return JsonResponse
*/
public function destroy(Account $account): JsonResponse
{
$user = Api::user();
if ($account->user->isNot($user)) {
return $this->failed('您没有权限删除');
}
$account->delete();
return $this->success('删除成功');
}
}

View File

@@ -1,155 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Controllers\Api;
use App\Api\Controllers\Controller;
use App\Models\DayDataChain;
use Carbon\Carbon;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Jason\Api\Api;
use Modules\Withdraw\Http\Requests\WithdrawRequest;
use Modules\Withdraw\Http\Resources\Account\UserAlipayAccountResource;
use Modules\Withdraw\Http\Resources\Account\UserBankAccountResource;
use Modules\Withdraw\Http\Resources\Withdraw\WithdrawCollection;
use Modules\Withdraw\Models\Config;
use Modules\Withdraw\Models\Withdraw;
class IndexController extends Controller
{
/**
* Notes: 我的提现记录
*
* @Author: 玄尘
* @Date : 2021/9/26 14:57
*/
public function index(Request $request): JsonResponse
{
$user = Api::user();
$type = $request->type ?? 'day';
$date = $request->date ?? Carbon::now()->format('Y-m-d');
$time = Carbon::parse($date);
switch ($type) {
case 'month':
$timeBetween = [
$time->startOfMonth()->toDateTimeString(),
$time->endOfMonth()->toDateTimeString(),
];
break;
case 'year':
$timeBetween = [
$time->startOfYear()->toDateTimeString(),
$time->endOfYear()->toDateTimeString(),
];
break;
case 'day':
default:
$timeBetween = [
$time->startOfDay()->toDateTimeString(),
$time->endOfDay()->toDateTimeString(),
];
break;
}
$lists = $user->withdraws()
->whereBetween('created_at', $timeBetween)
->latest()
->paginate();
$is_chain = config('withdraw.is_chain', false);
if ($is_chain) {
$all = floatval($user->getStoneFormatBalance());
} else {
$account = config('withdraw.account', 'coins');
$all = $user->account->{$account};
}
$data = [
'all' => $all,
'lists' => new WithdrawCollection($lists),
];
return $this->success($data);
}
/**
* Notes: 提现前置
*
* @Author: 玄尘
* @Date : 2021/1/21 14:21
*/
public function create(Request $request): JsonResponse
{
$user = Api::user();
$is_chain = config('withdraw.is_chain', false);
$bank_account_id = $request->bank_account_id;
$alipay_account_id = $request->alipay_account_id;
if ($bank_account_id) {
$bank_account = $user->bankAccounts()->where('id', $bank_account_id)->first();
} else {
$bank_account = $user->bankAccounts()->first();
}
if ($alipay_account_id) {
$alipay_account = $user->alipayAccounts()->where('id', $alipay_account_id)->first();
} else {
$alipay_account = $user->alipayAccounts()->first();
}
$data = [
'tax' => Config::getValue('tax', 0),
'bank_account' => $bank_account ? new UserBankAccountResource($bank_account) : '',
'alipay_account' => $alipay_account ? new UserAlipayAccountResource($alipay_account) : '',
'bank_accounts' => UserBankAccountResource::collection($user->bankAccounts),
'alipay_accounts' => UserAlipayAccountResource::collection($user->alipayAccounts),
'is_chain' => config('withdraw.is_chain'),
'certification' => (bool) $user->certification,
'types' => Withdraw::TYPES,
];
if ($is_chain) {
$data = array_merge($data, [
'balance' => floatval($user->getStoneFormatBalance()),//账户余额
'cost' => (new DayDataChain())->getStoneValue(),//现金价值
]);
} else {
$account = config('withdraw.account');
$data = array_merge($data, [
'balance' => $user->account->{$account},//账户余额
'cost' => 1,
]);
}
return $this->success($data);
}
/**
* Notes: 提现
*
* @Author: 玄尘
* @Date : 2021/1/21 14:27
* @param WithdrawRequest $request
* @return JsonResponse|mixed
*/
public function store(WithdrawRequest $request)
{
$user = Api::user();
try {
// if (! $user->certification) {
// throw new \Exception('未进行个人认证不可提现');
// }
Withdraw::createInfo($user, $request);
return $this->success('申请提现成功,等待管理员审核');
} catch (\Exception $e) {
return $this->failed($e->getmessage());
}
}
}

View File

@@ -1,35 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserBankAccountRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => 'required',
'no' => ['required', 'unique:withdraw_bank_accounts,no', 'digits_between:16,19'],
// 'branch_name' => 'required',
'mobile' => 'required',
'bank_id' => 'required',
];
}
public function messages(): array
{
return [
'name.required' => '收款人姓名必须填写',
'no.required' => '银行卡号必须填写',
'no.unique' => '此银行卡号已提交过',
'no.integer' => '银行卡号必须是数字',
'no.digits_between' => '银行卡号长度必须在:min ~ :max之间',
'branch_name.required' => '支行名称必须填写',
'mobile.required' => '收款人手机号必须填写',
'bank_id.required' => '银行必须选择',
];
}
}

View File

@@ -1,35 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class UserEditBankAccountRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => 'required',
'no' => ['required', 'digits_between:16,19'],
// 'branch_name' => 'required',
'mobile' => 'required',
'bank_id' => 'required',
];
}
public function messages(): array
{
return [
'name.required' => '收款人姓名必须填写',
'no.required' => '银行卡号必须填写',
'no.unique' => '此银行卡号已提交过',
'no.integer' => '银行卡号必须是数字',
'no.digits_between' => '银行卡号长度必须在:min ~ :max之间',
'branch_name.required' => '支行名称必须填写',
'mobile.required' => '收款人手机号必须填写',
'bank_id.required' => '银行必须选择',
];
}
}

View File

@@ -1,35 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class WithdrawRequest extends FormRequest
{
public function rules(): array
{
return [
'bank_account_id' => ['required_if:type,1'],
'name' => ['required_if:type,2'],
'identity' => ['required_if:type,2'],
'amount' => 'required|numeric',
'type' => 'required|numeric',
];
}
public function messages(): array
{
return [
'bank_account_id.required_if' => '提现账户必须选择',
'amount.required' => '提现金额必须选择',
'amount.numeric' => '提现金额必须填写',
'type.required' => '提现类型必须选择',
'type.numeric' => '提现类型必须填写',
'name.required_if' => '提现人必须填写',
'identity.required_if' => '支付宝账号必须填写',
];
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Account;
use App\Api\Resources\BaseCollection;
class UserAlipayAccountCollection extends BaseCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($info) {
return new UserAlipayAccountResource($info);
}),
'page' => $this->page(),
];
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Account;
use Illuminate\Http\Resources\Json\JsonResource;
class UserAlipayAccountResource extends JsonResource
{
public function toArray($request): array
{
return [
'alipay_account_id' => $this->id,
'name' => $this->name,
'identity_type' => $this->identity_type,
'identity' => $this->identity,
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Account;
use App\Api\Resources\BaseCollection;
class UserBankAccountCollection extends BaseCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($info) {
return new UserBankAccountResource($info);
}),
'page' => $this->page(),
];
}
}

View File

@@ -1,27 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Account;
use Illuminate\Http\Resources\Json\JsonResource;
class UserBankAccountResource extends JsonResource
{
public function toArray($request): array
{
return [
'bank_account_id' => $this->id,
'bank' => [
'id' => $this->bank_id,
'name' => $this->bank->name,
'cover' => $this->bank->cover_url,
],
'name' => $this->name,
'no' => $this->no,
'branch_name' => $this->branch_name,
'mobile' => $this->mobile,
'created_at' => (string) $this->created_at,
];
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Bank;
use Illuminate\Http\Resources\Json\JsonResource;
class BankResource extends JsonResource
{
public function toArray($request): array
{
return [
'id' => $this->id,
'name' => $this->name,
];
}
}

View File

@@ -1,21 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Withdraw;
use App\Api\Resources\BaseCollection;
class WithdrawCollection extends BaseCollection
{
public function toArray($request): array
{
return [
'data' => $this->collection->map(function ($info) {
return new WithdrawResource($info);
}),
'page' => $this->page(),
];
}
}

View File

@@ -1,30 +0,0 @@
<?php
namespace Modules\Withdraw\Http\Resources\Withdraw;
use Illuminate\Http\Resources\Json\JsonResource;
class WithdrawResource extends JsonResource
{
public function toArray($request): array
{
return [
'withdraw_id' => $this->id,
'status' => [
'status' => $this->status,
'status_text' => $this->status_text,
],
'amount' => $this->amount,
'tax' => $this->tax,
'take' => $this->take,
'payment_at' => (string) $this->payment_at,
'way' => '红包提现',
'quantity' => $this->source[config('withdraw.account')] ?? '',
'source' => $this->source,
'create_at' => (string) $this->created_at,
];
}
}

View File

@@ -1,15 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
use Modules\User\Traits\BelongsToUser;
use Modules\Withdraw\Models\Traits\BelongsToBank;
class Account extends Model
{
protected $table = 'withdraw_bank_accounts';
use BelongsToUser, BelongsToBank;
}

View File

@@ -1,23 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
use Modules\User\Traits\BelongsToUser;
class AlipayAccount extends Model
{
protected $table = 'withdraw_alipay_accounts';
use BelongsToUser;
const TYPE_USERID = 'ALIPAY_USER_ID';
const TYPE_LOGONID = 'ALIPAY_LOGON_ID';
const TYPES = [
self::TYPE_USERID => '支付宝的会员ID',
self::TYPE_LOGONID => '支付宝登录号,支持邮箱和手机号格式',
];
}

View File

@@ -1,23 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
use App\Traits\HasCovers;
class Bank extends Model
{
use HasCovers;
protected $table = 'withdraw_banks';
const STATUS_OPEN = 1;
const STATUS_CLOSE = 0;
const STATUS = [
self::STATUS_OPEN => '开启',
self::STATUS_CLOSE => '关闭',
];
}

View File

@@ -1,23 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
class Config extends Model
{
protected $table = 'withdraw_configs';
public static function getValue($slug, $default = 0)
{
$info = Config::query()->where('slug', $slug)->first();
if ($info) {
return $info->value;
} else {
return $default;
}
}
}

View File

@@ -1,12 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
class Log extends Model
{
protected $table = 'withdraw_logs';
}

View File

@@ -1,22 +0,0 @@
<?php
namespace Modules\Withdraw\Models\Traits;
use Modules\Withdraw\Models\Bank;
trait BelongsToBank
{
/**
* Notes: 关联银行
*
* @Author: 玄尘
* @Date: 2021/11/29 16:45
* @return mixed
*/
public function bank()
{
return $this->belongsTo(Bank::class);
}
}

View File

@@ -1,326 +0,0 @@
<?php
namespace Modules\Withdraw\Models\Traits;
use App\Models\DayDataChain;
use Illuminate\Support\Facades\DB;
use Jason\Chain33;
use Modules\Chain\Models\Address;
use Modules\Payment\Facades\Pay;
use Modules\Payment\Models\Traits\WithConfig;
use Modules\Withdraw\Events\WithdrawAuditPass;
use Modules\Withdraw\Events\WithdrawAuditReject;
use Modules\Withdraw\Models\Account;
use Modules\Withdraw\Models\Config;
use Modules\Withdraw\Models\Withdraw;
use Yansongda\Pay\Plugin\Alipay\Fund\TransUniTransferPlugin;
trait WithdrawActions
{
use WithConfig;
/**
* Notes: 通过
*
* @Author: 玄尘
* @Date : 2021/9/26 15:20
* @param string $remark
* @return bool
* @throws \Exception
*/
public function pass(string $remark = ''): bool
{
if (! $this->canAudit()) {
throw new \Exception('该提现记录已经被审核');
}
try {
if ($this->type == self::TYPE_ALIPAY) {
if (! $this->alipayAccount) {
throw new \Exception('未找到支付宝账户');
}
$allPlugins = Pay::alipay()
->mergeCommonPlugins([TransUniTransferPlugin::class]);
$params = [
'out_biz_no' => $this->withdraw_no,
'trans_amount' => $this->take,
'payee_info' => [
'identity' => $this->alipayAccount->identity,
'identity_type' => $this->alipayAccount->identity_type,
'name' => $this->alipayAccount->name,
],
];
$res = Pay::alipay($this->getPayConfig('alipay'))->pay($allPlugins, $params);
if ($res->code != 10000) {
throw new \Exception($res->sub_msg);
}
}
DB::transaction(function () use ($remark) {
$this->status = Withdraw::STATUS_PASS;
$this->paid_at = now();
$this->save();
});
$this->addLog(Withdraw::STATUS_INIT, $remark);
event(new WithdrawAuditPass($this));
return true;
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* Notes: 驳回
*
* @Author: 玄尘
* @Date : 2021/9/26 15:21
* @param string $remark
* @return bool
* @throws \Exception
*/
public function reject(string $remark = ''): bool
{
if (! $this->canAudit()) {
throw new \Exception('该提现记录已经被审核');
}
try {
DB::transaction(function () use ($remark) {
$this->status = Withdraw::STATUS_REJECT;
$this->paid_at = now();
$this->save();
$is_chain = config('withdraw.is_chain', false);
if (! $is_chain) {
$this->user->account->rule('withdraw_in', $this->amount, false, [
'withdraw_id' => $this->id,
]);
} else {
$hash = $this->rejectPick();
$source = [
'reject_hash' => $hash,
];
$this->update(['source' => $source]);
}
$this->addLog(Withdraw::STATUS_REJECT, $remark);
event(new WithdrawAuditReject($this));
});
return true;
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* Notes: 添加记录
*
* @Author: 玄尘
* @Date : 2021/9/27 8:56
* @param $status
* @param string $remark
* @return bool
*/
public function addLog($status, string $remark = ''): bool
{
$this->logs()->create([
'status' => $status,
'remark' => $remark,
]);
return true;
}
/**
* Notes: 创建提现信息
*
* @Author: 玄尘
* @Date : 2021/9/27 10:14
*/
public static function createInfo($user, $params): bool
{
try {
DB::transaction(function () use ($user, $params) {
$type = $params->type ?? 0;
$bank_account_id = $params->bank_account_id ?? 0;
$amount = $params->amount;
$account_name = config('withdraw.account');
$source = [
$account_name => $amount,
];
$cash = $amount;
$is_chain = config('withdraw.is_chain', false);
$balance = $is_chain ? $user->getStoneBalance() : $user->account->{$account_name};
if ($amount > $balance) {
throw new \Exception('提现失败,余额不足');
}
if ($is_chain) {
$cost = (new DayDataChain())->getStoneValue();
$cash = bcmul($cost, $amount, 2);
$source = array_merge($source, ['cost' => $cost,]);
}
$withdraw_min = Config::getValue('min', 1);
if ($withdraw_min > 0 && $cash < $withdraw_min) {
throw new \Exception("提现失败,提现金额必须大于等于{$withdraw_min}");
}
$tax_value = Config::getValue('tax', 0);
$tax = $tax_value ? round($cash * $tax_value / 100, 2) : 0;
$take = $cash - $tax;
if ($type == Withdraw::TYPE_BANK) {
$bank_account = Account::find($bank_account_id);
if (! $bank_account) {
throw new \Exception('提现失败,未找到提现账户信息');
}
if ($bank_account->user->isNot($user)) {
throw new \Exception('提现失败,您不可使用此提现账户');
}
$info = $user->withdraws()->create([
'bank_account_id' => $bank_account_id,
'amount' => $cash,
'tax' => $tax, //手续费
'take' => $take, //实到金额
'source' => $source,
'type' => Withdraw::TYPE_BANK,
]);
} else {
$alipay_account = $user->alipayAccounts()->create([
'name' => $params->name,
'identity' => $params->identity,
'identity_type' => 'ALIPAY_LOGON_ID',
]);
$info = $user->withdraws()->create([
'alipay_account_id' => $alipay_account->id,
'amount' => $cash,
'tax' => $tax, //手续费
'take' => $take, //实到金额
'source' => $source,
'type' => Withdraw::TYPE_ALIPAY,
]);
}
if (! $is_chain) {
$user->account->rule('withdraw_out', -$cash, false, [
'withdraw_id' => $info->id,
]);
} else {
$hash = $info->pick();//转到代持账户
$source = array_merge($source, ['hash' => $hash,]);
$info->update(['source' => $source]);
}
});
return true;
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* Notes: 申请提现时将提现金额转入代持账户
*
* @Author: 玄尘
* @Date : 2021/9/27 10:34
* @return string
* @throws \Exception
*/
public function pick(): string
{
$to_address = Config::getValue('withdraw_addr', '');
if (! $to_address) {
throw new \Exception('提现失败,缺少代持账户信息,请管理人员配置代持账户。');
}
$number = $this->source['coins'] ?? 0;
if (! $number) {
throw new \Exception('提现数据错误');
}
$from_address = $this->user->blockChain->address;
$balance = coinsFormat(Chain33::Balance()->get($from_address)['balance']);
if ($number > $balance) {
throw new \Exception('提现失败,数量不足');
}
try {
$fromAddr = Address::where('address', $from_address)->first();
return Chain33::Transaction()
->coins($to_address, $number * 1e8, $fromAddr->private_key, 0, '用户提现');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/9/27 14:45
* @return string
* @throws \Exception
*/
public function rejectPick(): string
{
$from_address = Config::getValue('withdraw_addr', '');
if (! $from_address) {
throw new \Exception('提现失败,缺少代持账户信息,请管理人员配置代持账户。');
}
$number = $this->source['coins'] ?? 0;
if (! $number) {
throw new \Exception('提现数据错误');
}
$to_address = $this->user->blockChain->address;
$balance = coinsFormat(Chain33::Balance()->get($from_address)['balance']);
if ($number > $balance) {
throw new \Exception('驳回失败,代持账户数量不足');
}
try {
$fromAddr = Address::where('address', $from_address)->first();
return Chain33::Transaction()
->coins($to_address, $number * 1e8, $fromAddr->private_key, 0, '驳回提现');
} catch (\Exception $e) {
throw new \Exception($e->getMessage());
}
}
}

View File

@@ -1,126 +0,0 @@
<?php
namespace Modules\Withdraw\Models;
use App\Models\Model;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Modules\User\Traits\BelongsToUser;
use Modules\Withdraw\Models\Traits\WithdrawActions;
class Withdraw extends Model
{
use BelongsToUser, WithdrawActions;
const STATUS_INIT = 0;
const STATUS_PASS = 1;
const STATUS_REJECT = 2;
const STATUS = [
self::STATUS_INIT => '待审核',
self::STATUS_PASS => '通过',
self::STATUS_REJECT => '驳回',
];
const TYPE_BANK = 1;
const TYPE_ALIPAY = 2;
const TYPES = [
self::TYPE_BANK => '银行卡',
self::TYPE_ALIPAY => '支付宝',
];
const TYPES_LABEL = [
self::TYPE_BANK => 'primary',
self::TYPE_ALIPAY => 'success',
];
protected $casts = [
'source' => 'json',
];
public static function boot()
{
parent::boot();
self::creating(function ($model) {
$time = explode(' ', microtime());
$counter = $model->whereDate('created_at', Carbon::today())->count() + 1;
$len = config('withdraw.withdraw_no_counter_length');
$len = $len < 6 ? 6 : $len;
$len = $len > 16 ? 16 : $len;
$model->withdraw_no = date('YmdHis').
sprintf('%06d', $time[0] * 1e6).
sprintf('%0'.$len.'d', $counter);
$model->status = self::STATUS_INIT;
});
}
/**
* Notes: 关联银行账号
*
* @Author: 玄尘
* @Date : 2021/9/27 8:39
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function bankAccount(): BelongsTo
{
return $this->belongsTo(Account::class);
}
/**
* Notes: 支付宝账号
*
* @Author: 玄尘
* @Date : 2021/11/3 15:58
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function alipayAccount(): BelongsTo
{
return $this->belongsTo(AlipayAccount::class);
}
/**
* Notes: 提现状态
*
* @Author: 玄尘
* @Date : 2021/9/26 15:06
* @return string
*/
public function getStatusTextAttribute(): string
{
return self::STATUS[$this->status] ?? '未知';
}
/**
* Notes: 是否可以审核
*
* @Author: 玄尘
* @Date : 2021/9/26 15:06
* @return bool
*/
public function canAudit(): bool
{
return $this->status == self::STATUS_INIT;
}
/**
* Notes: 操作记录
*
* @Author: 玄尘
* @Date : 2021/9/27 8:53
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function logs(): HasMany
{
return $this->hasMany(Log::class);
}
}

View File

@@ -1,78 +0,0 @@
<?php
namespace Modules\Withdraw\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
class RouteServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected string $moduleName = 'Withdraw';
/**
* The module namespace to assume when generating URLs to actions.
*
* @var string
*/
protected $moduleNamespace = 'Modules\Withdraw\Http\Controllers';
/**
* Called before routes are registered.
* Register any model bindings or pattern based filters.
*
* @return void
*/
public function boot()
{
parent::boot();
}
/**
* Define the routes for the application.
*
* @return void
*/
public function map()
{
$this->mapApiRoutes();
$this->mapAdminRoutes();
}
/**
* Define the "web" routes for the application.
* These routes all receive session state, CSRF protection, etc.
*
* @return void
*/
protected function mapAdminRoutes()
{
Route::as(config('admin.route.as'))
->domain(config('admin.route.domain'))
->middleware(config('admin.route.middleware'))
->namespace($this->moduleNamespace.'\\Admin')
->prefix(config('admin.route.prefix'))
->group(module_path($this->moduleName, 'Routes/admin.php'));
}
/**
* Define the "api" routes for the application.
* These routes are typically stateless.
*
* @return void
*/
protected function mapApiRoutes()
{
Route::as(config('api.route.as'))
->domain(config('api.route.domain'))
->middleware(config('api.route.middleware'))
->namespace($this->moduleNamespace.'\\Api')
->prefix(config('api.route.prefix').'/withdraws')
->group(module_path($this->moduleName, 'Routes/api.php'));
}
}

View File

@@ -1,77 +0,0 @@
<?php
namespace Modules\Withdraw\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Database\Eloquent\Factory;
class WithdrawServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected $moduleName = 'Withdraw';
/**
* @var string $moduleNameLower
*/
protected $moduleNameLower = 'withdraw';
/**
* Boot the application events.
*
* @return void
*/
public function boot()
{
$this->registerConfig();
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->register(RouteServiceProvider::class);
$models = config('withdraw.model');
if ($models) {
foreach ($models as $key => $model) {
$this->app->bind('withdraw.model.'.$key, function ($app) use ($model) {
return (new $model);
});
}
}
}
/**
* Register config.
*
* @return void
*/
protected function registerConfig()
{
$this->publishes([
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower.'.php'),
], 'withdraw-config');
$this->mergeConfigFrom(
module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
);
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return [];
}
}

View File

@@ -1,9 +0,0 @@
# 提现模块
> 1、先发布资源
> 2、启用模块
> 3、修改配置里的 account 提现账户
> 4、修改提现账变规则对应的账户

View File

@@ -1,9 +0,0 @@
@extends('withdraw::layouts.master')
@section('content')
<h1>Hello World</h1>
<p>
This view is loaded from module: {!! config('withdraw.name') !!}
</p>
@endsection

View File

@@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Module Withdraw</title>
{{-- Laravel Mix - CSS File --}}
{{-- <link rel="stylesheet" href="{{ mix('css/withdraw.css') }}"> --}}
</head>
<body>
@yield('content')
{{-- Laravel Mix - JS File --}}
{{-- <script src="{{ mix('js/withdraw.js') }}"></script> --}}
</body>
</html>

View File

@@ -1,13 +0,0 @@
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::group([
'prefix' => 'withdraws',
], function (Router $router) {
$router->resource('info', 'WithdrawController'); //提现管理
$router->resource('banks', 'BankController'); //银行管理
$router->resource('configs', 'ConfigController'); //配置信息
$router->resource('accounts', 'AccountController'); //账户列表
});

View File

@@ -1,15 +0,0 @@
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::group([
'middleware' => config('coupon.route.middleware_auth'),
], function (Router $router) {
$router->resource('accounts', 'AccountController'); //银行账户
$router->resource('index', 'IndexController'); //提现记录
});

View File

@@ -1,49 +0,0 @@
<?php
namespace Modules\Withdraw\Selectable;
use Encore\Admin\Widgets\Table;
use Illuminate\Contracts\Support\Renderable;
use Modules\Withdraw\Models\Withdraw;
class AccountAble implements Renderable
{
public function render($key = null): string
{
$withdraw = Withdraw::find($key);
if ($withdraw->type == Withdraw::TYPE_BANK) {
$account = $withdraw->bankAccount;
$data = [
$account->name,
$account->bank->name,
$account->no,
];
$header = ['提款人', '开户行', '卡号'];
$table = new Table($header, [$data]);
return $table->render();
} elseif ($withdraw->type == Withdraw::TYPE_ALIPAY) {
$account = $withdraw->alipayAccount;
$table = new Table(
[
'姓名',
'支付宝账号',
],
[
[
$account->name,
$account->identity,
],
]
);
return $table->render();
}
}
}

View File

@@ -1,50 +0,0 @@
<?php
namespace Modules\Withdraw\Traits;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Modules\Withdraw\Models\Account;
use Modules\Withdraw\Models\AlipayAccount;
use Modules\Withdraw\Models\Withdraw;
trait HasWithdraws
{
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/11/3 14:42
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function withdraws(): HasMany
{
return $this->hasMany(Withdraw::class);
}
/**
* Notes: description
*
* @Author: 玄尘
* @Date : 2021/11/3 14:42
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function bankAccounts(): HasMany
{
return $this->hasMany(Account::class);
}
/**
* Notes: 支付宝账号
*
* @Author: 玄尘
* @Date : 2021/11/3 14:41
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function alipayAccounts(): HasMany
{
return $this->hasMany(AlipayAccount::class);
}
}

View File

@@ -1,164 +0,0 @@
<?php
namespace Modules\Withdraw;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Schema;
use Modules\Withdraw\Models\Config;
class Withdraw
{
protected static string $mainTitle = '提现管理';
/**
* Notes: 模块初始化要做的一些操作
*
* @Author: 玄尘
* @Date : 2021/9/26 11:23
*/
public static function install()
{
if (! config('withdraw')) {
throw new \Exception('未找到配置项,请先发布资源');
}
Artisan::call('migrate', [
'--path' => 'modules/Withdraw/Database/Migrations',
]);
self::createAdminMenu();
self::addDefaultData();
}
protected static function createAdminMenu()
{
$menu = config('admin.database.menu_model');
$exists = $menu::where('title', self::$mainTitle)->exists();
if (! $exists) {
$main = $menu::create([
'parent_id' => 0,
'order' => 3,
'title' => '提现管理',
'icon' => 'fa-archive',
]);
$main->children()
->create([
'order' => 1,
'title' => '提现列表',
'icon' => 'fa-align-left',
'uri' => 'withdraws/info',
]);
$main->children()
->create([
'order' => 2,
'title' => '配置',
'icon' => 'fa-align-left',
'uri' => 'withdraws/configs',
]);
$main->children()
->create([
'order' => 3,
'title' => '银行列表',
'icon' => 'fa-align-left',
'uri' => 'withdraws/banks',
]);
$main->children()
->create([
'order' => 4,
'title' => '银行账户列表',
'icon' => 'fa-align-left',
'uri' => 'withdraws/accounts',
]);
}
}
/**
* Notes: 卸载模块的一些操作
*
* @Author: 玄尘
* @Date : 2021/9/26 11:24
*/
public static function uninstall()
{
$menu = config('admin.database.menu_model');
$mains = $menu::where('title', self::$mainTitle)->get();
foreach ($mains as $main) {
$main->delete();
}
}
public static function addDefaultData()
{
self::setAccountRule();
self::setDefaultConfig();
}
public static function setDefaultConfig()
{
$configs_data = [
['name' => '手续费', 'slug' => 'tax', 'value' => 0,],
['name' => '最少提现金额', 'slug' => 'min', 'value' => 1,],
['name' => '提现代持账户', 'slug' => 'withdraw_addr', 'value' => 0,],
];
foreach ($configs_data as $data) {
$info = Config::query()->where('slug', $data['slug'])->first();
if (! $info) {
Config::query()->create($data);
}
}
}
public static function setAccountRule()
{
$account_rules = config('withdraw.model.account_rules');
if (Schema::hasTable((new $account_rules)->getTable())) {
$account = config('withdraw.account');
$rules_data = [
[
'title' => '提现',
'name' => 'withdraw_out',
'type' => $account,
'variable' => 0,
'trigger' => 0,
'deductions' => 1,
'remark' => '提现扣除相应账户',
],
[
'title' => '提现驳回',
'name' => 'withdraw_in',
'type' => $account,
'variable' => 0,
'trigger' => 0,
'deductions' => 1,
'remark' => '提现驳回返回提现金额',
],
];
foreach ($rules_data as $data) {
$info = (new $account_rules)::query()->where('name', $data['name'])->first();
if (! $info) {
(new $account_rules)::query()->create($data);
} else {
if ($info->type != $account) {
$info->update([
'type' => $account,
]);
}
}
}
}
}
}

View File

@@ -1,21 +0,0 @@
{
"name": "xuanchen/withdraw-module",
"description": "",
"type": "laravel-module",
"authors": [
{
"name": "Chen.Xuan",
"email": "122383162@qq.com"
}
],
"require": {
},
"extra": {
"module-dir": "modules"
},
"autoload": {
"psr-4": {
"Modules\\Withdraw\\": ""
}
}
}

View File

@@ -1,15 +0,0 @@
{
"name": "Withdraw",
"alias": "withdraw",
"description": "提现",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\Withdraw\\Providers\\WithdrawServiceProvider"
],
"aliases": {},
"files": [],
"version": "1.0.0",
"author": "玄尘",
"requires": []
}

File diff suppressed because one or more lines are too long