6
0
Fork 0

添加账户相关接口

release
vine_liutk 2021-12-28 15:25:50 +08:00
parent c7f88e3d53
commit ab77655c45
18 changed files with 347 additions and 8 deletions

View File

@ -0,0 +1,17 @@
<?php
namespace App\Endpoint\Api\Filters;
use EloquentFilter\ModelFilter;
class BalanceLogFilter extends ModelFilter
{
public function action($action)
{
switch ($action) {
case 'transfer'://转账
$this->onlyTransfer();
break;
}
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Endpoint\Api\Filters;
use EloquentFilter\ModelFilter;
class WalletLogFilter extends ModelFilter
{
public function action($action)
{
switch ($action) {
case 'withdraw-balance'://提现到余额明细
$this->onlyWithdrawBalance();
break;
}
}
}

View File

@ -3,6 +3,7 @@
namespace App\Endpoint\Api\Http\Controllers\Account;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\UserBalanceResource;
use App\Endpoint\Api\Http\Resources\UserInfoResource;
use App\Endpoint\Api\Http\Resources\UserWalletResource;
use App\Models\UserInfo;
@ -26,6 +27,7 @@ class UserController extends Controller
'user_info' => UserInfoResource::make($user->userInfo),
'is_vip' => $user->isVip(),
'wallet' => UserWalletResource::make($user->wallet),
'balance' => UserBalanceResource::make($user->balance),
]);
}

View File

@ -3,19 +3,26 @@
namespace App\Endpoint\Api\Http\Controllers\Account;
use App\Endpoint\Api\Http\Controllers\Controller;
use App\Endpoint\Api\Http\Resources\BalanceLogResource;
use App\Endpoint\Api\Http\Resources\DistributionPreIncomeResource;
use App\Endpoint\Api\Http\Resources\WalletLogResource;
use App\Exceptions\BizException;
use App\Exceptions\InvalidPaySerialNumberException;
use App\Exceptions\PayPasswordIncorrectException;
use App\Exceptions\WalletNotEnoughException;
use App\Helpers\Paginator as PaginatorHelper;
use App\Models\BalanceLog;
use App\Models\Order;
use App\Models\PayLog;
use App\Models\User;
use App\Models\WalletLog;
use App\Models\WalletToBankLog;
use App\Rules\PhoneNumber;
use App\Services\BalanceService;
use App\Services\PayService;
use App\Services\WalletService;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Throwable;
@ -32,7 +39,7 @@ class WalletController extends Controller
{
return response()->json([
'distribution_pre' => $request->user()->distributionPreIncomes()->pending()->sum('total_revenue'),
'wallet_balance'=> $request->user()->wallet?->balance ?? 0,
'wallet_balance'=> $request->user()->wallet?->balance_format ?? 0,
]);
}
@ -64,7 +71,7 @@ class WalletController extends Controller
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$walletLogs = $request->user()->walletLogs()
$walletLogs = $request->user()->walletLogs()->filter($request->all())
->latest('id')
->simplePaginate($perPage);
@ -78,6 +85,13 @@ class WalletController extends Controller
*/
public function balanceLogs(Request $request)
{
$perPage = PaginatorHelper::resolvePerPage('per_page', 20, 50);
$walletLogs = $request->user()->balanceLogs()->filter($request->all())
->latest('id')
->simplePaginate($perPage);
return BalanceLogResource::collection($walletLogs);
}
/**
@ -141,4 +155,127 @@ class WalletController extends Controller
return response()->noContent();
}
/**
* 提现到银行
*
* @return void
*/
public function walletToBank(Request $request, WalletService $walletService)
{
$input = $request->validate([
'amount' => ['bail', 'required', 'int', 'min:1'],
'wallet_password' => ['bail', 'required', 'filled', 'string', 'size:6'],
]);
$user = $request->user();
//校验安全密码
if (! $user->wallet?->verifyPassword($input['wallet_password'])) {
throw new PayPasswordIncorrectException();
}
if (is_null($user->bank)) {
throw new BizException('请先绑定设置银行卡');
}
try {
DB::beginTransaction();
//生成提现记录
$log = WalletToBankLog::create([
'user_id' =>$user->id,
'bank_name' => $user->bank->bank_name,
'bank_number' => $user->bank->bank_number,
'bank_description' => $user->bank->bank_description,
'username' => $user->bank->real_name,
'amount'=> Arr::get($input, 'amount', 0),
]);
//减去用户可提金额
$walletService->changeBalance($user, -Arr::get($input, 'amount', 0), WalletLog::ACTION_WITHDRAW_BANK, '提现-银行卡', $log);
DB::commit();
} catch (WalletNotEnoughException $th) {
DB::rollBack();
throw new BizException('可提金额不足');
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('系统繁忙,请稍后再试');
}
return response()->noContent();
}
/**
* 提现到余额
*
* @param Request $request
* @return void
*/
public function walletToBalance(Request $request, WalletService $walletService, BalanceService $balanceService)
{
$input = $request->validate([
'amount' => ['bail', 'required', 'int', 'min:1'],
'wallet_password' => ['bail', 'required', 'filled', 'string', 'size:6'],
]);
$user = $request->user();
//校验安全密码
if (! $user->wallet?->verifyPassword($input['wallet_password'])) {
throw new PayPasswordIncorrectException();
}
try {
DB::beginTransaction();
//余额添加
$log = $balanceService->changeBalance($user, Arr::get($input, 'amount', 0), BalanceLog::ACTION_WALLET_IN, '可提-转入');
//减去用户可提金额
$walletService->changeBalance($user, -Arr::get($input, 'amount', 0), WalletLog::ACTION_WITHDRAW_BALACNE, '提现-余额', $log);
DB::commit();
} catch (WalletNotEnoughException $th) {
DB::rollBack();
throw new BizException('可提金额不足');
} catch (Throwable $th) {
DB::rollBack();
report($th);
throw new BizException('系统繁忙,请稍后再试');
}
return response()->noContent();
}
/**
* 余额转账
*
* @return void
*/
public function balanceTransfer(Request $request, BalanceService $balanceService)
{
$input = $request->validate([
'phone' => ['bail', 'required', new PhoneNumber()],
'amount' => ['bail', 'required', 'int', 'min:1'],
'wallet_password' => ['bail', 'required', 'filled', 'string', 'size:6'],
]);
//判断转账对象是否存在
$toUser = User::where('phone', '=', $input['phone'])->first();
if (is_null($toUser)) {
throw new BizException('转账对象不存在');
}
$user = $request->user();
try {
DB::beginTransaction();
//转出对象
$log = $balanceService->changeBalance($user, -Arr::get($input, 'amount', 0), BalanceLog::ACTION_TRANSFER_OUT, '转出-'.$toUser->phone);
//转入对象
$balanceService->changeBalance($toUser, Arr::get($input, 'amount', 0), BalanceLog::ACTION_TRANSFER_IN, $toUser->phone.'-转入', $log);
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
report($th);
}
return response()->noContent();
}
}

View File

@ -17,8 +17,8 @@ class WalletPasswordController extends Controller
public function reset(Request $request)
{
$input = $request->validate([
'old_password' => ['bail', 'filled', 'string', 'min:6', 'max:6'],
'new_password' => ['bail', 'required', 'string', 'min:6', 'max:6'],
'old_password' => ['bail', 'filled', 'string', 'size:6'],
'new_password' => ['bail', 'required', 'string', 'size:6'],
]);
$wallet = $request->user()->wallet;

View File

@ -0,0 +1,23 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class BalanceLogResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'remarks' => $this->remarks,
'created_at' => $this->created_at->format('y-m-d H:i'),
'change_balance' => $this->change_balance_format,
];
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Endpoint\Api\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class UserBalanceResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
if (is_null($this->resource)) {//没有钱包数据时默认数据
return [
'balance'=> '0.00',
// 'total_expenses'=> $this->total_expenses,
// 'total_revenue' => $this->total_revenue,
// 'withdrawable' => $this->withdrawable,
];
}
return [
'balance'=>$this->balance_format,
// 'total_expenses'=> $this->total_expenses,
// 'total_revenue' => $this->total_revenue,
// 'withdrawable' => $this->withdrawable,
];
}
}

View File

@ -16,7 +16,7 @@ class UserWalletResource extends JsonResource
{
if (is_null($this->resource)) {//没有钱包数据时默认数据
return [
// 'balance'=>$this->balance,
'balance'=> '0.00',
// 'total_expenses'=> $this->total_expenses,
// 'total_revenue' => $this->total_revenue,
// 'withdrawable' => $this->withdrawable,
@ -24,7 +24,7 @@ class UserWalletResource extends JsonResource
];
}
return [
// 'balance'=>$this->balance,
'balance'=>$this->balance_format,
// 'total_expenses'=> $this->total_expenses,
// 'total_revenue' => $this->total_revenue,
// 'withdrawable' => $this->withdrawable,

View File

@ -17,7 +17,7 @@ class WalletLogResource extends JsonResource
return [
'remarks' => $this->remarks,
'created_at' => $this->created_at->format('y-m-d H:i'),
'change_balance' => $this->change_balance,
'change_balance' => $this->change_balance_format,
];
}
}

View File

@ -91,7 +91,11 @@ Route::group([
Route::get('wallet', [WalletController::class, 'index']);
Route::get('wallet/distribution-logs', [WalletController::class, 'distributionLogs']);
Route::get('wallet/wallet-logs', [WalletController::class, 'walletLogs']);
Route::get('wallet/balance-logs', [WalletController::class, 'balanceLogs']);
Route::post('wallet/pay', [WalletController::class, 'pay']);
Route::post('wallet/wallet-to-bank', [WalletController::class, 'walletToBank']);
Route::post('wallet/wallet-to-balance', [WalletController::class, 'walletToBalance']);
Route::post('wallet/balance-transfer', [WalletController::class, 'balanceTransfer']);
//银行卡
Route::get('user-bank', [UserBankController::class, 'show']);

View File

@ -33,4 +33,9 @@ class Balance extends Model
protected $casts = [
'transferable' => 'bool',
];
public function getBalanceFormatAttribute()
{
return trim_trailing_zeros(bcdiv($this->attributes['balance'], 100, 2));
}
}

View File

@ -2,13 +2,19 @@
namespace App\Models;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Model;
class BalanceLog extends Model
{
use Filterable;
public const ACTION_ORDER_PAID = 1;
public const ACTION_ORDER_CANCELLED = 2;
public const ACTION_ORDER_AFTER_SALE = 3;
public const ACTION_WALLET_IN = 4;
public const ACTION_TRANSFER_OUT = 5;
public const ACTION_TRANSFER_IN = 6;
/**
* @var array
@ -23,6 +29,16 @@ class BalanceLog extends Model
'remarks',
];
/**
* 转账记录
*
* @return void
*/
public function scopeOnlyTransfer($query)
{
return $query->whereIn('action', [self::ACTION_TRANSFER_OUT, self::ACTION_TRANSFER_IN]);
}
/**
* 获取变动金额
*

View File

@ -45,6 +45,11 @@ class Wallet extends Model
'withdrawable' => 'bool',
];
public function getBalanceFormatAttribute()
{
return trim_trailing_zeros(bcdiv($this->attributes['balance'], 100, 2));
}
/**
* 设置此用户的安全密码
*

View File

@ -2,13 +2,18 @@
namespace App\Models;
use EloquentFilter\Filterable;
use Illuminate\Database\Eloquent\Model;
class WalletLog extends Model
{
use Filterable;
public const ACTION_ORDER_PAID = 1;
public const ACTION_ORDER_CANCELLED = 2;
public const ACTION_ORDER_AFTER_SALE = 3;
public const ACTION_WITHDRAW_BANK = 4;
public const ACTION_WITHDRAW_BALACNE = 5;
/**
* @var array
@ -23,6 +28,16 @@ class WalletLog extends Model
'remarks',
];
/**
* 提现到余额的明细
*
* @param [type] $query
*/
public function scopeOnlyWithdrawBalance($query)
{
return $query->where('action', '=', self::ACTION_WITHDRAW_BALACNE);
}
/**
* 获取变动金额
*

View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class WalletToBankLog extends Model
{
use HasFactory;
use HasDateTimeFormatter;
/**
* @var array
*/
protected $fillable = [
'user_id',
'bank_name',
'bank_number',
'bank_description',
'username',
'amount',
];
}

View File

@ -38,6 +38,8 @@ class AppServiceProvider extends ServiceProvider
'order' => \App\Models\Order::class,
'order_refund_log' => \App\Models\OrderRefundLog::class,
'after_sale' => \App\Models\AfterSale::class,
'wallet_to_bank_log' => \App\Models\WalletToBankLog::class,
'balance_log' => \App\Models\BalanceLog::class,
]);
JsonResource::withoutWrapping();

View File

@ -60,7 +60,7 @@ class BalanceService
]);
}
$user->balanceLogs()->create([
return $user->balanceLogs()->create([
'loggable_id' => $loggable?->id,
'loggable_type' => $loggable?->getMorphClass(),
'before_balance' => $beforeBalance,

View File

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateWalletToBankLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('wallet_to_bank_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('用户ID');
$table->string('bank_name')->comment('收款银行');
$table->string('bank_number')->comment('收款银行卡号');
$table->string('bank_description')->comment('收款银行开户行');
$table->string('username')->comment('持卡人');
$table->unsignedBigInteger('amount')->comment('提现金额:分');
$table->unsignedTinyInteger('status')->default(0)->comment('状态0未处理1成功2失败');
$table->string('remarks')->nullable()->comment('备注');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('wallet_to_bank_logs');
}
}