余额支付
parent
0fb25292f5
commit
e56998ff39
|
|
@ -5,15 +5,18 @@ namespace App\Endpoint\Api\Http\Controllers\Account;
|
||||||
use App\Endpoint\Api\Http\Controllers\Controller;
|
use App\Endpoint\Api\Http\Controllers\Controller;
|
||||||
use App\Endpoint\Api\Http\Resources\DistributionPreIncomeResource;
|
use App\Endpoint\Api\Http\Resources\DistributionPreIncomeResource;
|
||||||
use App\Endpoint\Api\Http\Resources\WalletLogResource;
|
use App\Endpoint\Api\Http\Resources\WalletLogResource;
|
||||||
use App\Exceptions\BizException;
|
use App\Exceptions\InvalidPaySerialNumberException;
|
||||||
use App\Helpers\Paginator as PaginatorHelper;
|
use App\Helpers\Paginator as PaginatorHelper;
|
||||||
|
use App\Models\BalanceLog;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\PayLog;
|
use App\Models\PayLog;
|
||||||
use App\Models\WalletLog;
|
use App\Models\WalletLog;
|
||||||
|
use App\Services\BalanceService;
|
||||||
use App\Services\PayService;
|
use App\Services\PayService;
|
||||||
use App\Services\WalletService;
|
use App\Services\WalletService;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class WalletController extends Controller
|
class WalletController extends Controller
|
||||||
|
|
@ -88,29 +91,38 @@ class WalletController extends Controller
|
||||||
{
|
{
|
||||||
$validated = $request->validate([
|
$validated = $request->validate([
|
||||||
'pay_sn' => ['bail', 'required'],
|
'pay_sn' => ['bail', 'required'],
|
||||||
'pay_way' => ['bail', 'required'],
|
'pay_way' => ['bail', 'required', Rule::in([PayLog::PAY_WAY_WALLET, PayLog::PAY_WAY_BALANCE])],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
|
// todo 校验支付密码
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DB::transaction(function () use ($user, $validated) {
|
DB::transaction(function () use ($user, $validated) {
|
||||||
$payLog = PayLog::where('pay_sn', $validated['pay_sn'])->where('pay_way', $validated['pay_way'])->lockForUpdate()->firstOrFail();
|
$payLog = PayLog::where('pay_sn', $validated['pay_sn'])
|
||||||
|
->where('pay_way', $validated['pay_way'])
|
||||||
|
->lockForUpdate()
|
||||||
|
->first();
|
||||||
|
|
||||||
|
if ($payLog === null) {
|
||||||
|
throw new InvalidPaySerialNumberException();
|
||||||
|
}
|
||||||
|
|
||||||
$payable = $payLog->payable;
|
$payable = $payLog->payable;
|
||||||
|
|
||||||
switch (get_class($payable)) {
|
if ($payable instanceof Order) {
|
||||||
case Order::class:
|
if ($payLog->isWallet()) {
|
||||||
(new WalletService())->changeBalance($user, -$payable->total_amount, WalletLog::ACTION_ORDER_PAY, '订单支付扣款', $payable);
|
(new WalletService())->changeBalance($user, -$payable->total_amount, WalletLog::ACTION_ORDER_PAY, '订单-支付', $payable);
|
||||||
break;
|
} else {
|
||||||
|
(new BalanceService())->changeBalance($user, -$payable->total_amount, BalanceLog::ACTION_ORDER_PAY, '订单-支付', $payable);
|
||||||
default:
|
}
|
||||||
throw new BizException('非法操作');
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(new PayService())->handleSuccess($payLog);
|
(new PayService())->handleSuccess($payLog);
|
||||||
});
|
});
|
||||||
|
} catch (InvalidPaySerialNumberException $e) {
|
||||||
|
throw $e;
|
||||||
} catch (Throwable $e) {
|
} catch (Throwable $e) {
|
||||||
try {
|
try {
|
||||||
(new PayService())->handleFailedByPaySerialNumber($validated['pay_sn'], [
|
(new PayService())->handleFailedByPaySerialNumber($validated['pay_sn'], [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
class BalanceNotEnoughException extends BizException
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct('余额不足');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
class InvalidPaySerialNumberException extends BizException
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct('无效的支付流水号');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
class WalletNotEnoughException extends BizException
|
||||||
|
{
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct('可提不足');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Balance extends Model
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $attributes = [
|
||||||
|
'balance' => 0,
|
||||||
|
'total_revenue' => 0,
|
||||||
|
'total_expenses' => 0,
|
||||||
|
'transferable' => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'balance',
|
||||||
|
'total_expenses',
|
||||||
|
'total_revenue',
|
||||||
|
'transferable',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'transferable' => 'bool',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class BalanceLog extends Model
|
||||||
|
{
|
||||||
|
public const ACTION_ORDER_PAY = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'user_id',
|
||||||
|
'loggable_id',
|
||||||
|
'loggable_type',
|
||||||
|
'action',
|
||||||
|
'before_balance',
|
||||||
|
'change_balance',
|
||||||
|
'remarks',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取变动金额
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getChangeBalanceFormatAttribute()
|
||||||
|
{
|
||||||
|
return trim_trailing_zeros(bcdiv($this->attributes['change_balance'], 100, 2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -97,4 +97,14 @@ class PayLog extends Model
|
||||||
{
|
{
|
||||||
return $this->pay_way === static::PAY_WAY_WALLET;
|
return $this->pay_way === static::PAY_WAY_WALLET;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认支付方式是否是余额支付
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isBalance(): bool
|
||||||
|
{
|
||||||
|
return $this->pay_way === static::PAY_WAY_BALANCE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,22 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
||||||
return $this->hasMany(WalletLog::class, 'user_id');
|
return $this->hasMany(WalletLog::class, 'user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户的余额
|
||||||
|
*/
|
||||||
|
public function balance()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Balance::class, 'user_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户的余额日志
|
||||||
|
*/
|
||||||
|
public function balanceLogs()
|
||||||
|
{
|
||||||
|
return $this->hasOne(BalanceLog::class, 'user_id');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户的预收益
|
* 用户的预收益
|
||||||
*/
|
*/
|
||||||
|
|
@ -278,22 +294,6 @@ class User extends Model implements AuthorizableContract, AuthenticatableContrac
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取此用户的钱包并加行锁
|
|
||||||
*
|
|
||||||
* @return \App\Models\Wallet
|
|
||||||
*/
|
|
||||||
public function lockWallet(): Wallet
|
|
||||||
{
|
|
||||||
if ($wallet = $this->wallet()->lockForUpdate()->first()) {
|
|
||||||
return $wallet;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->wallet()->create();
|
|
||||||
|
|
||||||
return $this->wallet()->lockForUpdate()->first();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建用户
|
* 创建用户
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Exceptions\BalanceNotEnoughException;
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
class BalanceService
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 变更余额
|
||||||
|
*
|
||||||
|
* @param \App\Models\User $user
|
||||||
|
* @param int $changeBalance
|
||||||
|
* @param int $action
|
||||||
|
* @param string|null $remarks
|
||||||
|
* @param mixed $loggable
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function changeBalance(User $user, int $changeBalance, int $action, ?string $remarks = null, $loggable = null)
|
||||||
|
{
|
||||||
|
$balance = $user->balance()->lockForUpdate()->first();
|
||||||
|
|
||||||
|
if (is_null($balance)) {
|
||||||
|
throw new BalanceNotEnoughException();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 变更前余额
|
||||||
|
$beforeBalance = $balance->balance;
|
||||||
|
$_changeBalance = abs($changeBalance);
|
||||||
|
|
||||||
|
if ($changeBalance > 0) {
|
||||||
|
// 收入
|
||||||
|
$user->balance()->update([
|
||||||
|
'balance' => DB::raw("balance + {$_changeBalance}"),
|
||||||
|
'total_revenue' => DB::raw("total_revenue + {$_changeBalance}"),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// 支出
|
||||||
|
|
||||||
|
if ($balance->balance < $_changeBalance) {
|
||||||
|
throw new BalanceNotEnoughException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->balance()->update([
|
||||||
|
'balance' => DB::raw("balance - {$_changeBalance}"),
|
||||||
|
'total_expenses' => DB::raw("total_expenses + {$_changeBalance}"),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$user->balanceLogs()->create([
|
||||||
|
'loggable_id' => $loggable?->id,
|
||||||
|
'loggable_type' => $loggable?->getMorphClass(),
|
||||||
|
'before_balance' => $beforeBalance,
|
||||||
|
'change_balance' => $changeBalance,
|
||||||
|
'action' => $action,
|
||||||
|
'remarks' => $remarks,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Exceptions\BizException;
|
use App\Exceptions\BizException;
|
||||||
|
use App\Exceptions\InvalidPaySerialNumberException;
|
||||||
use App\Models\DistributionPreIncomeJob;
|
use App\Models\DistributionPreIncomeJob;
|
||||||
use App\Models\Order;
|
use App\Models\Order;
|
||||||
use App\Models\PayLog;
|
use App\Models\PayLog;
|
||||||
|
|
@ -17,11 +18,16 @@ class PayService
|
||||||
* @return \App\Models\PayLog
|
* @return \App\Models\PayLog
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\BizException
|
* @throws \App\Exceptions\BizException
|
||||||
|
* @throws \App\Exceptions\InvalidPaySerialNumberException
|
||||||
*/
|
*/
|
||||||
public function handleSuccessByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
|
public function handleSuccessByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
|
||||||
{
|
{
|
||||||
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
|
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
|
||||||
|
|
||||||
|
if ($payLog === null) {
|
||||||
|
throw new InvalidPaySerialNumberException();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->handleSuccess($payLog, $params);
|
return $this->handleSuccess($payLog, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,11 +39,12 @@ class PayService
|
||||||
* @return \App\Models\PayLog
|
* @return \App\Models\PayLog
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\BizException
|
* @throws \App\Exceptions\BizException
|
||||||
|
* @throws \App\Exceptions\InvalidPaySerialNumberException
|
||||||
*/
|
*/
|
||||||
public function handleSuccess(PayLog $payLog, array $params = []): PayLog
|
public function handleSuccess(PayLog $payLog, array $params = []): PayLog
|
||||||
{
|
{
|
||||||
if (! $payLog->isPending()) {
|
if (! $payLog->isPending()) {
|
||||||
throw new BizException('支付异常');
|
throw new InvalidPaySerialNumberException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$payLog->update([
|
$payLog->update([
|
||||||
|
|
@ -46,24 +53,32 @@ class PayService
|
||||||
'status' => PayLog::STATUS_SUCCESS,
|
'status' => PayLog::STATUS_SUCCESS,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if ($payLog->payable instanceof Order) {
|
$payable = $payLog->payable;
|
||||||
$order = $payLog->payable;
|
|
||||||
|
|
||||||
if ($order->isPaid()) {
|
if ($payable instanceof Order) {
|
||||||
|
if ($payable->isPaid()) {
|
||||||
throw new BizException('订单已支付');
|
throw new BizException('订单已支付');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($order->isCompleted()) {
|
if ($payable->isCompleted()) {
|
||||||
throw new BizException('订单已完成');
|
throw new BizException('订单已完成');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 支付方式
|
// 支付方式
|
||||||
$payWay = $payLog->pay_way;
|
$payWay = $payLog->pay_way;
|
||||||
|
|
||||||
if ($payLog->isWxpay()) {
|
if ($payLog->isWxpay()) {
|
||||||
|
// 微信支付
|
||||||
$payWay = Order::PAY_WAY_WXPAY;
|
$payWay = Order::PAY_WAY_WXPAY;
|
||||||
|
} elseif ($payLog->isWallet()) {
|
||||||
|
// 可提支付
|
||||||
|
$payWay = Order::PAY_WAY_WALLET;
|
||||||
|
} elseif ($payLog->isBalance()) {
|
||||||
|
// 余额支付
|
||||||
|
$payWay = Order::PAY_WAY_BALANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
$order->update([
|
$payable->update([
|
||||||
'pay_sn' => $payLog->pay_sn,
|
'pay_sn' => $payLog->pay_sn,
|
||||||
'pay_way' => $payWay,
|
'pay_way' => $payWay,
|
||||||
'pay_at' => $payLog->pay_at,
|
'pay_at' => $payLog->pay_at,
|
||||||
|
|
@ -72,8 +87,8 @@ class PayService
|
||||||
]);
|
]);
|
||||||
|
|
||||||
DistributionPreIncomeJob::create([
|
DistributionPreIncomeJob::create([
|
||||||
'jobable_id' => $order->id,
|
'jobable_id' => $payable->id,
|
||||||
'jobable_type' => $order->getMorphClass(),
|
'jobable_type' => $payable->getMorphClass(),
|
||||||
'remarks' => '支付订单',
|
'remarks' => '支付订单',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
@ -89,11 +104,16 @@ class PayService
|
||||||
* @return \App\Models\PayLog
|
* @return \App\Models\PayLog
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\BizException
|
* @throws \App\Exceptions\BizException
|
||||||
|
* @throws \App\Exceptions\InvalidPaySerialNumberException
|
||||||
*/
|
*/
|
||||||
public function handleFailedByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
|
public function handleFailedByPaySerialNumber(string $paySerialNumber, array $params = []): PayLog
|
||||||
{
|
{
|
||||||
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
|
$payLog = PayLog::where('pay_sn', $paySerialNumber)->lockForUpdate()->first();
|
||||||
|
|
||||||
|
if ($payLog === null) {
|
||||||
|
throw new InvalidPaySerialNumberException();
|
||||||
|
}
|
||||||
|
|
||||||
return $this->handleFailed($payLog, $params);
|
return $this->handleFailed($payLog, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,11 +125,12 @@ class PayService
|
||||||
* @return \App\Models\PayLog
|
* @return \App\Models\PayLog
|
||||||
*
|
*
|
||||||
* @throws \App\Exceptions\BizException
|
* @throws \App\Exceptions\BizException
|
||||||
|
* @throws \App\Exceptions\InvalidPaySerialNumberException
|
||||||
*/
|
*/
|
||||||
public function handleFailed(PayLog $payLog, array $params = []): PayLog
|
public function handleFailed(PayLog $payLog, array $params = []): PayLog
|
||||||
{
|
{
|
||||||
if (! $payLog->isPending()) {
|
if (! $payLog->isPending()) {
|
||||||
throw new BizException('支付异常');
|
throw new InvalidPaySerialNumberException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$payLog->update([
|
$payLog->update([
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use App\Exceptions\BizException;
|
use App\Exceptions\WalletNotEnoughException;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
|
|
@ -20,7 +20,11 @@ class WalletService
|
||||||
*/
|
*/
|
||||||
public function changeBalance(User $user, int $changeBalance, int $action, ?string $remarks = null, $loggable = null)
|
public function changeBalance(User $user, int $changeBalance, int $action, ?string $remarks = null, $loggable = null)
|
||||||
{
|
{
|
||||||
$wallet = $user->lockWallet();
|
$wallet = $user->wallet()->lockForUpdate()->first();
|
||||||
|
|
||||||
|
if (is_null($wallet)) {
|
||||||
|
throw new WalletNotEnoughException();
|
||||||
|
}
|
||||||
|
|
||||||
// 变更前余额
|
// 变更前余额
|
||||||
$beforeBalance = $wallet->balance;
|
$beforeBalance = $wallet->balance;
|
||||||
|
|
@ -36,7 +40,7 @@ class WalletService
|
||||||
// 支出
|
// 支出
|
||||||
|
|
||||||
if ($wallet->balance < $_changeBalance) {
|
if ($wallet->balance < $_changeBalance) {
|
||||||
throw new BizException('可提余额不足');
|
throw new WalletNotEnoughException();
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->wallet()->update([
|
$user->wallet()->update([
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateBalancesTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('balances', function (Blueprint $table) {
|
||||||
|
$table->unsignedBigInteger('user_id')->primary()->comment('用户ID');
|
||||||
|
$table->unsignedBigInteger('balance')->default(0)->comment('余额(分)');
|
||||||
|
$table->unsignedBigInteger('total_expenses')->default(0)->comment('总支出(分)');
|
||||||
|
$table->unsignedBigInteger('total_revenue')->default(0)->comment('总收入(分)');
|
||||||
|
$table->boolean('transferable')->default(true)->comment('是否可转账');
|
||||||
|
$table->timestamps();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('balances');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
class CreateBalanceLogsTable extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::create('balance_logs', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->unsignedBigInteger('user_id')->comment('用户ID');
|
||||||
|
$table->nullableMorphs('loggable');
|
||||||
|
$table->tinyInteger('action')->comment('操作类型');
|
||||||
|
$table->unsignedBigInteger('before_balance')->default(0)->comment('变更前的余额');
|
||||||
|
$table->bigInteger('change_balance')->default(0)->comment('变动余额(分)');
|
||||||
|
$table->string('remarks')->nullable()->comment('备注');
|
||||||
|
$table->timestamps();
|
||||||
|
|
||||||
|
$table->index('user_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function down()
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('balance_logs');
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue