Laravel wallet ,如何快速開發出一個錢包功能的應用?

666666發表於2020-06-02

原因:

最近因為專案(基於laravel)需要一個使用者錢包功能,於是準備手擼一個,分析了一下我們專案對錢包需求的功能點,大概有:充值、消費(購買平臺服務)、轉賬、提現、並且需要檢視所有的資金變動記錄。

契機:

本著程式設計師最高的神聖規則:不重複製造輪子 。在 github 上搜尋 wallet,果然有人開源了一個:https://github.com/bavix/laravel-wallet 有兩百多個 start ,懷著試試的想法,我探索一下。

搭建實驗室:

安裝laravel框架:composer create-project --prefer-dist laravel/laravel laravel
修改.env 的資料
引入UI:composer require laravel/ui
建立使用者系統:artisan ui vue --auth
執行遷移:artisan migrate
編譯資源:yarn dev

開始引入laravel-wallet:

引入laravel-wallet:composer require bavix/laravel-wallet
【如果是用lumen需要在bootstrap/app.php新增:
    $app->register(\Bavix\Wallet\WalletServiceProvider::class);】
生成遷移檔案:artisan vendor:publish --tag=laravel-wallet-migrations
生成配置檔案:artisan vendor:publish --tag=laravel-wallet-config

資料庫中增加了三張表:

wallet表:
laravel wallet ,如何快速開發出一個錢包功能的應用?
transfers:表
laravel wallet ,如何快速開發出一個錢包功能的應用?
transactions表:
laravel wallet ,如何快速開發出一個錢包功能的應用?

開始簡單的測試:

先在系統中註冊兩個使用者,conner1, conner2;
修改 User 模型:

    use  Bavix\Wallet\Traits\HasWallet;
    use  Bavix\Wallet\Interfaces\Wallet; 
    class  User  extends  Model  implements  Wallet  {
        use  HasWallet;
    }

然後修改 預設的 HomeControoler.php, 根據文件測試功能

public function index(){
    //獲取當前使用者
    $user = Auth::user();
    //初始化錢包
    $user->balance;
}

上面程式碼會在 wallet 中建立一條使用者關聯的錢包,格式如下:

laravel wallet ,如何快速開發出一個錢包功能的應用?
接下來我們看看簡單的充值和提現功能

public function index(){
    //獲取當前使用者
    $user = Auth::user();
    //初始化錢包
    $user->balance;
    //充值 100
    $user->deposit(100);
    //列印看一下是個啥
    dd($user->balance); // 字串型別的一百
    // 繼續充兩次看看資料庫有些什麼記錄
    $user->deposit(100);
    $user->deposit(100);
}

transactions表中有這樣三條記錄:

laravel wallet ,如何快速開發出一個錢包功能的應用?

wallet表中為:

laravel wallet ,如何快速開發出一個錢包功能的應用?
然後繼續,我們試試提現:

$user->withdrap(50);

transactions表 增加一條記錄:

laravel wallet ,如何快速開發出一個錢包功能的應用?
wallet表 少50
到目前沒感覺不到有什麼特殊的地方,接下來我們來看看程式碼是怎麼實現的,首先是充值,deposit():
首先這個 Bavix\Wallet\Interfaces\Wallet 檔案中找到方法如下

/**
     * @param int $amount
     * @param array|null $meta
     * @param bool $confirmed
     * @return Transaction
     */
    public function deposit($amount, ?array $meta = null, bool $confirmed = true): Transaction;

註釋很清楚,繼續看 trait Bavix\Wallet\Traits\HasWallet; 中

/**
     * The input means in the system
     *
     * @param int $amount
     * @param array|null $meta
     * @param bool $confirmed
     *
     * @return Transaction
     * @throws
     */
    public function deposit($amount, ?array $meta = null, bool $confirmed = true): Transaction
    {
        $self = $this;
        return app(DbService::class)->transaction(static function () use ($self, $amount, $meta, $confirmed) {
            return app(CommonService::class)
                ->deposit($self, $amount, $meta, $confirmed);
        });
    }

到這裡還是沒有看到處理邏輯,只是加了一個當前錢包例項進去,$self,繼續深入,在commonService中:

 /**
     * @param Wallet $wallet
     * @param int $amount
     * @param array|null $meta
     * @param bool $confirmed
     * @return Transaction
     */
    public function deposit(Wallet $wallet, $amount, ?array $meta, bool $confirmed = true): Transaction
    {
        return app(LockService::class)->lock($this, __FUNCTION__, function () use ($wallet, $amount, $meta, $confirmed) {
            $walletService = app(WalletService::class);
            $walletService->checkAmount($amount);

            /**
             * @var WalletModel $wallet
             */
            $wallet = $walletService->getWallet($wallet);

            $transactions = $this->multiOperation($wallet, [
                app(Operation::class)
                    ->setType(Transaction::TYPE_DEPOSIT)
                    ->setConfirmed($confirmed)
                    ->setAmount($amount)
                    ->setMeta($meta)
            ]);

            return current($transactions);
        });
    }

這裡就是具體的呼叫了,驗證金額等,呼叫 Operation 定義的方法 來處理。
感覺還是挺優雅的………
有興趣的童鞋一起來探索吧:
bavix.github.io/laravel-wallet/

本作品採用《CC 協議》,轉載必須註明作者和本文連結

join_jiang

相關文章