user
parent
cf537656bd
commit
bdce01ac8e
16
README.md
16
README.md
|
|
@ -106,3 +106,19 @@ $menus = [
|
|||
| source_id | bigint | null | - | 来源(多态关联) |
|
||||
| created_at | timestamp | null | - | 创建时间 |
|
||||
| updated_at | timestamp | null | - | 更新时间 |
|
||||
|
||||
## 收货地址: user_address
|
||||
|
||||
| column | type | nullable | default | comment |
|
||||
| - | - | - | - | - |
|
||||
| id | bigint | not null | - | 主键 |
|
||||
| user_id | bigint | not null | - | 外键关联 users.id |
|
||||
| contact_name | varchar(191) | not null | - | 联系人 |
|
||||
| phone | varchar(191) | not null | - | 电话 |
|
||||
| address | varchar(191) | not null | - | 地址 |
|
||||
| province_id | bigint | null | - | 所属地区 |
|
||||
| city_id | bigint | null | - | 所属地区 |
|
||||
| area_id | bigint | null | - | 所属地区 |
|
||||
| is_default | int | not null | 0 | 默认地址 |
|
||||
| created_at | timestamp | null | - | 创建时间 |
|
||||
| updated_at | timestamp | null | - | 更新时间 |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('user_withdraw', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('user_id')->comment('申请人');
|
||||
$table->decimal('amount', 12, 2)->comment('提现数量');
|
||||
$table->decimal('balance', 12, 2)->comment('剩余');
|
||||
$table->unsignedInteger('status')->default(0)->comment('状态');
|
||||
$table->json('payee')->nullable()->comment('收款账户');
|
||||
$table->json('payer')->nullable()->comment('打款账户');
|
||||
$table->string('reason')->nullable()->comment('原因');
|
||||
$table->string('remarks')->nullable()->comment('备注');
|
||||
$table->timestamp('finish_at')->nullable()->comment('完成时间');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('user_withdraw');
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
|
||||
];
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'labels' => [
|
||||
'withdraw' => '提现管理',
|
||||
'Withdraw' => '提现管理',
|
||||
],
|
||||
'fields' => [
|
||||
'balance' => '余额',
|
||||
'amount' => '提现数量',
|
||||
'payee' => '收款账户',
|
||||
'payer' => '打款账户',
|
||||
'remarks' => '备注',
|
||||
'status' => '状态',
|
||||
'user_id' => '申请人',
|
||||
'user' => [
|
||||
'phone' => '申请人'
|
||||
],
|
||||
'created_at' => '申请时间',
|
||||
'finish_at' => '完成时间',
|
||||
'reason' => '失败原因',
|
||||
]
|
||||
];
|
||||
|
|
@ -12,4 +12,6 @@ Route::group([
|
|||
|
||||
Route::resource('users', UserController::class)->names('dcat.admin.users');
|
||||
Route::resource('user-balance', UserBalanceController::class)->names('dcat.admin.user_balance');
|
||||
|
||||
Route::resource('withdraw', WithdrawController::class)->names('dcat.admin.withdraw')->only(['index', 'show']);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,5 +26,8 @@ Route::group([
|
|||
|
||||
Route::get('address/default', [AddressController::class, 'default']);
|
||||
Route::apiResource('address', AddressController::class);
|
||||
|
||||
Route::post('withdraw/{id}/cancel', [WithdrawController::class, 'cancel']);
|
||||
Route::apiResource('withdraw', WithdrawController::class)->only(['index', 'show', 'store']);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Action\Withdraw;
|
||||
|
||||
use Dcat\Admin\Grid\BatchAction;
|
||||
use Dcat\Admin\Widgets\Modal;
|
||||
use Peidikeji\User\Form\Withdraw\CheckForm;
|
||||
|
||||
class BatchCheck extends BatchAction
|
||||
{
|
||||
protected $title = '审核';
|
||||
|
||||
protected function html()
|
||||
{
|
||||
$form = CheckForm::make()->payload(['remarks' => '']);
|
||||
return Modal::make()
|
||||
->lg()
|
||||
->title($this->title)
|
||||
->body($form)
|
||||
->onLoad($this->getModalScript())
|
||||
->button($this->title);
|
||||
}
|
||||
|
||||
protected function getModalScript()
|
||||
{
|
||||
// 弹窗显示后往隐藏的id表单中写入批量选中的行ID
|
||||
return <<<JS
|
||||
// 获取选中的ID数组
|
||||
var key = {$this->getSelectedKeysScript()}
|
||||
|
||||
$('#batch-check-id').val(key);
|
||||
JS;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Action\Withdraw;
|
||||
|
||||
use Dcat\Admin\Grid\RowAction;
|
||||
use Dcat\Admin\Widgets\Modal;
|
||||
use Peidikeji\User\Form\Withdraw\CheckForm;
|
||||
|
||||
class RowCheck extends RowAction
|
||||
{
|
||||
protected $title = '审核';
|
||||
|
||||
protected function html()
|
||||
{
|
||||
$model = $this->row();
|
||||
$form = CheckForm::make()->payload(['remarks' => $model->remarks ?: '', 'id' => $model->id]);
|
||||
return Modal::make()
|
||||
->lg()
|
||||
->title($this->title)
|
||||
->body($form)
|
||||
->button($this->title);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Enums;
|
||||
|
||||
enum WithdrawStatus: int
|
||||
{
|
||||
case None = 0;
|
||||
case Processing = 1;
|
||||
case Success = 2;
|
||||
case Fail = 3;
|
||||
case Cancel = 4;
|
||||
|
||||
public static function options()
|
||||
{
|
||||
return [
|
||||
self::None->value => '待处理',
|
||||
self::Processing->value => '处理中',
|
||||
self::Success->value => '成功',
|
||||
self::Fail->value => '失败',
|
||||
self::Cancel->value => '已取消',
|
||||
];
|
||||
}
|
||||
|
||||
public function color()
|
||||
{
|
||||
return match ($this) {
|
||||
static::None => 'warning',
|
||||
static::Processing => 'secondary',
|
||||
static::Success => 'success',
|
||||
static::Fail => 'danger',
|
||||
static::Cancel => 'secondary',
|
||||
default => 'dark',
|
||||
};
|
||||
}
|
||||
|
||||
public function text()
|
||||
{
|
||||
return data_get(self::options(), $this->value);
|
||||
}
|
||||
|
||||
public function label()
|
||||
{
|
||||
$color = $this->color();
|
||||
|
||||
$name = $this->text();
|
||||
|
||||
return "<span class='label bg-${color}'>{$name}</span>";
|
||||
}
|
||||
|
||||
public function dot()
|
||||
{
|
||||
$color = $this->color();
|
||||
|
||||
$name = $this->text();
|
||||
|
||||
return "<i class='fa fa-circle text-$color'> {$name}</span>";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Exceptions;
|
||||
|
||||
use Dcat\Admin\Traits\JsonResponse;
|
||||
use Exception;
|
||||
|
||||
class WitdrawException extends Exception
|
||||
{
|
||||
use JsonResponse;
|
||||
|
||||
protected $code = 400;
|
||||
|
||||
public function report()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function render($request)
|
||||
{
|
||||
return $this->error($this->message, $this->code);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Filters;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use EloquentFilter\ModelFilter;
|
||||
|
||||
class WithdrawFilter extends ModelFilter
|
||||
{
|
||||
public function user($v)
|
||||
{
|
||||
$this->where('user_id', $v);
|
||||
}
|
||||
|
||||
public function status($v)
|
||||
{
|
||||
$this->whereIn('status', is_array($v) ? $v : explode(',', $v));
|
||||
}
|
||||
|
||||
public function createdStart($v)
|
||||
{
|
||||
$time = Carbon::createFromTimestamp(strtotime($v));
|
||||
$this->where('created_at', '>=', $time);
|
||||
}
|
||||
|
||||
public function createdEnd($v)
|
||||
{
|
||||
$time = Carbon::createFromTimestamp(strtotime($v));
|
||||
$this->where('created_at', '<=', $time);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Form\Withdraw;
|
||||
|
||||
use Dcat\Admin\Contracts\LazyRenderable;
|
||||
use Dcat\Admin\Traits\LazyWidget;
|
||||
use Dcat\Admin\Widgets\Form;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Peidikeji\User\Enums\WithdrawStatus;
|
||||
use Peidikeji\User\Models\UserWithdraw;
|
||||
use Peidikeji\User\WithdrawService;
|
||||
|
||||
class CheckForm extends Form implements LazyRenderable
|
||||
{
|
||||
use LazyWidget;
|
||||
|
||||
protected $buttons = ['reset' => false, 'submit' => true];
|
||||
|
||||
public function handle(array $input)
|
||||
{
|
||||
$ids = $input['id'] ? explode(',', $input['id']) : null;
|
||||
if (!$ids) {
|
||||
$ids = [$this->payload['id']];
|
||||
}
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
foreach(UserWithdraw::where('status', WithdrawStatus::None)->get() as $info) {
|
||||
if ($input['status'] == WithdrawStatus::Success->value) {
|
||||
WithdrawService::make()->success($info);
|
||||
} else {
|
||||
WithdrawService::make()->fail($info, ['reason' => $input['reason']]);
|
||||
}
|
||||
$info->update(['remarks' => $input['remarks']]);
|
||||
}
|
||||
DB::commit();
|
||||
return $this->response()->success('操作成功')->refresh();
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
return $this->response()->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public function form()
|
||||
{
|
||||
$options = WithdrawStatus::options();
|
||||
$this->radio('status')->options(Arr::only($options, [WithdrawStatus::Success->value, WithdrawStatus::Fail->value]))->required();
|
||||
$this->text('reason');
|
||||
$this->text('remarks');
|
||||
$this->hidden('id')->attribute('id', 'batch-check-id');
|
||||
}
|
||||
|
||||
public function default()
|
||||
{
|
||||
return [
|
||||
'remarks' => $this->payload['remarks'],
|
||||
'status' => WithdrawStatus::Success->value
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Http\Admin;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Dcat\Admin\Admin;
|
||||
use Dcat\Admin\Grid;
|
||||
use Dcat\Admin\Grid\Displayers\Actions;
|
||||
use Dcat\Admin\Grid\Filter;
|
||||
use Dcat\Admin\Grid\Tools\BatchActions;
|
||||
use Dcat\Admin\Show;
|
||||
use Dcat\Admin\Http\Controllers\AdminController;
|
||||
use Peidikeji\User\Action\Withdraw\BatchCheck;
|
||||
use Peidikeji\User\Action\Withdraw\RowCheck;
|
||||
use Peidikeji\User\Enums\WithdrawStatus;
|
||||
use Peidikeji\User\Models\UserWithdraw;
|
||||
|
||||
class WithdrawController extends AdminController
|
||||
{
|
||||
protected $translation = 'dcat-admin-user::withdraw';
|
||||
|
||||
protected function grid()
|
||||
{
|
||||
return Grid::make(UserWithdraw::with(['user']), function (Grid $grid) {
|
||||
$grid->model()->sort();
|
||||
|
||||
$grid->rowSelector()->disable(function ($row) {
|
||||
return $row->status !== WithdrawStatus::None;
|
||||
});
|
||||
$grid->column('user.phone');
|
||||
$grid->column('amount');
|
||||
$grid->column('status')->display(fn() => $this->status->label());
|
||||
$grid->column('created_at');
|
||||
|
||||
$grid->filter(function (Filter $filter) {
|
||||
$filter->panel();
|
||||
$filter->equal('user_id')->select()->ajax('api/users?_paginate=1')->width(3);
|
||||
$filter->equal('status')->select(WithdrawStatus::options())->width(3);
|
||||
$filter->whereBetween('created_at', function ($q) {
|
||||
$start = data_get($this->input, 'start');
|
||||
$start = $start ? Carbon::createFromFormat('Y-m-d', $start) : null;
|
||||
$end = data_get($this->input, 'end');
|
||||
$end = $end ? Carbon::createFromFormat('Y-m-d', $end) : null;
|
||||
if ($start) {
|
||||
if ($end) {
|
||||
$q->whereBetween('created_at', [$start, $end]);
|
||||
}
|
||||
$q->where('created_at', '>=', $start);
|
||||
} else if ($end) {
|
||||
$q->where('created_at', '<=', $end);
|
||||
}
|
||||
})->date()->width(6);
|
||||
});
|
||||
|
||||
$grid->showRowSelector();
|
||||
$grid->disableCreateButton();
|
||||
$grid->disableDeleteButton();
|
||||
$grid->disableEditButton();
|
||||
$grid->disableBatchDelete();
|
||||
|
||||
$user = Admin::user();
|
||||
$grid->actions(function (Actions $actions) use ($user) {
|
||||
$row = $actions->row;
|
||||
if ($user->can('dcat.admin.withdraw.check') && $row->status === WithdrawStatus::None) {
|
||||
$actions->append(new RowCheck());
|
||||
}
|
||||
});
|
||||
|
||||
$grid->batchActions(function (BatchActions $actions) use ($user) {
|
||||
if ($user->can('dcat.admin.withdraw.check')) {
|
||||
$actions->add(new BatchCheck());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected function detail($id)
|
||||
{
|
||||
return Show::make($id, UserWithdraw::with(['user']), function (Show $show) {
|
||||
|
||||
$show->field('user_id')->as(fn() => $this->user?->phone);
|
||||
$show->field('amount');
|
||||
$show->field('balance');
|
||||
$show->field('status')->as(fn() => $this->status->label())->unescape();
|
||||
$show->field('created_at');
|
||||
$show->field('finish_at');
|
||||
$show->field('reason');
|
||||
$show->field('remarks');
|
||||
|
||||
$show->disableEditButton();
|
||||
$show->disableDeleteButton();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Http\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Peidikeji\User\Http\Resources\WithdrawResource;
|
||||
use Peidikeji\User\WithdrawService;
|
||||
|
||||
class WithdrawController extends Controller
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
$user = auth('api')->user();
|
||||
|
||||
$query = $user->withdraws()->filter($request->all());
|
||||
|
||||
$list = $query->paginate($request->input('per_page'));
|
||||
|
||||
return $this->json(WithdrawResource::collection($list));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$user = auth('api')->user();
|
||||
$info = $user->withdraws()->findOrFail($id);
|
||||
|
||||
return $this->json(WithdrawResource::make($info));
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
$user = auth('api')->user();
|
||||
$request->validate([
|
||||
'amount' => 'numeric|gt:0|lte:' . floatval($user->balance)
|
||||
], [
|
||||
'amount.gt' => '提现数量必须大于 0',
|
||||
'amount.lte' => '余额不足'
|
||||
]);
|
||||
$amount = $request->input('amount');
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$info = WithdrawService::make()->apply($user, $amount);
|
||||
DB::commit();
|
||||
return $this->success('申请成功', WithdrawResource::make($info));
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function cancel($id)
|
||||
{
|
||||
$user = auth('api')->user();
|
||||
$info = $user->withdraws()->findOrFail($id);
|
||||
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
WithdrawService::make()->cancel($info);
|
||||
DB::commit();
|
||||
return $this->success('取消成功');
|
||||
} catch (\Exception $e) {
|
||||
DB::rollBack();
|
||||
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class WithdrawResource extends JsonResource
|
||||
{
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'balance' => floatval($this->balance),
|
||||
'amount' => floatval($this->amount),
|
||||
'payee' => $this->payee,
|
||||
'payer' => $this->payer,
|
||||
'remarks' => $this->remarks,
|
||||
'status' => $this->status,
|
||||
'status_text' => $this->status->text(),
|
||||
'user_id' => $this->id,
|
||||
'finish_at' => $this->finish_at?->timestamp,
|
||||
'reason' => $this->reason,
|
||||
'created_at' => $this->created_at?->timestamp,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -75,6 +75,11 @@ class User extends Authenticatable
|
|||
return $this->hasMany(UserCoupon::class, 'user_id');
|
||||
}
|
||||
|
||||
public function withdraws()
|
||||
{
|
||||
return $this->hasMany(UserWithdraw::class, 'user_id');
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->latest('id');
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ use Peidikeji\Region\Models\Region;
|
|||
|
||||
class UserAddress extends Model
|
||||
{
|
||||
protected $table = 'user_address';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id', 'contact_name', 'phone', 'address', 'province_id', 'city_id', 'area_id', 'is_default',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User\Models;
|
||||
|
||||
use Dcat\Admin\Traits\HasDateTimeFormatter;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Peidikeji\User\Enums\WithdrawStatus;
|
||||
use Peidikeji\User\Filters\WithdrawFilter;
|
||||
|
||||
class UserWithdraw extends Model
|
||||
{
|
||||
use HasDateTimeFormatter;
|
||||
use Filterable;
|
||||
|
||||
protected $table = 'user_withdraw';
|
||||
|
||||
protected $fillable = ['balance', 'amount', 'payee', 'payer', 'remarks', 'status', 'user_id', 'finish_at', 'reason'];
|
||||
|
||||
protected $casts = [
|
||||
'status' => WithdrawStatus::class,
|
||||
'payee' => 'json',
|
||||
'payer' => 'json',
|
||||
];
|
||||
|
||||
protected $dates = ['finish_at'];
|
||||
|
||||
protected $attributes = [
|
||||
'status' => WithdrawStatus::None
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'user_id');
|
||||
}
|
||||
|
||||
public function modelFilter()
|
||||
{
|
||||
return WithdrawFilter::class;
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->latest('created_at');
|
||||
}
|
||||
}
|
||||
|
|
@ -32,6 +32,7 @@ class UserServiceProvider extends ServiceProvider
|
|||
['id' => 1, 'parent_id' => 0, 'title' => '用户模块', 'icon' => 'feather icon-user', 'uri' => ''],
|
||||
['id' => 2, 'parent_id' => 1, 'title' => '用户管理', 'icon' => '', 'uri' => '/users'],
|
||||
['id' => 3, 'parent_id' => 1, 'title' => '余额流水', 'icon' => '', 'uri' => '/user-balance'],
|
||||
['id' => 4, 'parent_id' => 1, 'title' => '提现管理', 'icon' => '', 'uri' => '/withdraw'],
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
namespace Peidikeji\User;
|
||||
|
||||
use Peidikeji\User\Enums\WithdrawStatus;
|
||||
use Peidikeji\User\Exceptions\WitdrawException;
|
||||
use Peidikeji\User\Models\UserWithdraw;
|
||||
|
||||
class WithdrawService
|
||||
{
|
||||
public static function make(): static
|
||||
{
|
||||
return new static();
|
||||
}
|
||||
|
||||
public function apply($user, $amount, $data = [])
|
||||
{
|
||||
// 扣除余额
|
||||
$user->decrement('balance', $amount);
|
||||
$balance = $user->balance;
|
||||
|
||||
// 添加申请记录
|
||||
$info = $user->withdraws()->create([
|
||||
'balance' => $balance,
|
||||
'amount' => $amount,
|
||||
'payee' => data_get($data, 'payee')
|
||||
]);
|
||||
|
||||
// 添加流水记录
|
||||
$user->balanceLogs()->create([
|
||||
'user_name' => $user->phone,
|
||||
'amount' => 0-$amount,
|
||||
'balance' => $balance,
|
||||
'cate' => '提现',
|
||||
'description' => '申请提现, 扣除余额',
|
||||
'source_id' => $info->id,
|
||||
'source_type' => (new UserWithdraw())->getMorphClass()
|
||||
]);
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public function cancel(UserWithdraw $info)
|
||||
{
|
||||
if ($info->status !== WithdrawStatus::None) {
|
||||
throw new WitdrawException('申请已处理, 无法取消');
|
||||
}
|
||||
|
||||
$info->update(['status' => WithdrawStatus::Cancel]);
|
||||
|
||||
$this->refund($info);
|
||||
}
|
||||
|
||||
public function refund(UserWithdraw $info)
|
||||
{
|
||||
$user = $info->user;
|
||||
$amount = $info->amount;
|
||||
// 退回余额
|
||||
$user->increment('balance', $amount);
|
||||
$balance = $user->balance;
|
||||
|
||||
$cate = match($info->status) {
|
||||
WithdrawStatus::Cancel => '提现',
|
||||
WithdrawStatus::Fail => '提现',
|
||||
default => '提现'
|
||||
};
|
||||
$description = match($info->status) {
|
||||
WithdrawStatus::Cancel => '取消提现申请, 退回余额',
|
||||
WithdrawStatus::Fail => $info->reason,
|
||||
default => '退回余额'
|
||||
};
|
||||
|
||||
// 添加流水记录
|
||||
$user->balanceLogs()->create([
|
||||
'user_name' => $user->phone,
|
||||
'amount' => $amount,
|
||||
'balance' => $balance,
|
||||
'cate' => $cate,
|
||||
'description' => $description,
|
||||
'source_id' => $info->id,
|
||||
'source_type' => $info->getMorphClass()
|
||||
]);
|
||||
}
|
||||
|
||||
public function success(UserWithdraw $info, $time = null)
|
||||
{
|
||||
if ($info->status !== WithdrawStatus::None) {
|
||||
throw new WitdrawException('申请已处理');
|
||||
}
|
||||
$info->update([
|
||||
'status' => WithdrawStatus::Success,
|
||||
'finish_at' => $time ?: now(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 申请失败
|
||||
*
|
||||
* @param UserWithdraw $info
|
||||
* @param array $options 其他参数(reason)
|
||||
*/
|
||||
public function fail(UserWithdraw $info, $options = [])
|
||||
{
|
||||
if ($info->status !== WithdrawStatus::None) {
|
||||
throw new WitdrawException('申请已处理');
|
||||
}
|
||||
$info->update([
|
||||
'status' => WithdrawStatus::Fail,
|
||||
'reason' => data_get($options, 'reason'),
|
||||
'finish_at' => data_get($options, 'finish_at', now())
|
||||
]);
|
||||
|
||||
$this->refund($info);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue