基于Laravel實現的用戶動態模塊開發

更新:2017-10-25    編輯:盤寬網    來源:GeGuai    人氣:加載中...    字號:|

標簽:實現  用戶  動態  Laravel  開發  基于  百度搜索

前言

信任大家都知道,幾乎所有的社區使用都有用戶動態這個部分,用戶可以通過好友動態獲能取到更多感興趣的內容,從而提高社區活躍度和用戶粘性。它的實現相對來講比普通的內容發布要繁雜一些,主要體現在內容多樣性上。

為領會決這個問題,我們得把這些不同類型的內容抽象,提取共性,應用相同的結構來處理,開發起來就會簡單很多。

概念抽象

用戶動態,顧名思義,動態的產生,就是一系列事件的歷史記載,所以首先關注“事件”這個名詞,它有哪些屬性:

我們將用戶動態抽象成只有 4 個根基屬性的結構,就對比容易實現了:

- description 事件描述 - causer_id 或者 user_id 事件觸發者 - subject_id 主體 ID - subject_type 主體類型 - properties 事件附加屬性 - created_at 事件產生光陰

而主體部分就是 Laravel 里的 morph relation, 多態關聯。

怎么展示

我們的動態展示需求通常有以下幾種:

最近正在開發 EasyWeChat 新版網站,其中也有用戶動態,舉例:

xxx 發布了討論 《請問大家怎么應用 xxx》 xxx 評論了 xxx 的話題 《請問大家怎么應用 xxx》 xxx 回復了 xxx 的評論 “我是遵照文檔上 ...” xxx 購買了 《微信開發:自定義菜單的應用》 xxx 關注了 xxx ...

你會發現,基本上每種動態的寫法都不一樣,所以我們還需要記載一個 “事件類型” ,比如 “關注”、 “發布”、“回復”、“購買”。

然后我們在 blade 或者其它模板引擎的應用中,就可以 switch ... case 寫法,來使用不同的模板渲染這些樣式,比如 blade 中,我的用法:

@switch($activity->properties['event'] ?? '') @case('discussion.created') ... @break @case('comment.created') ... @break @endswitch

代碼實現

前面我們已經討論完了數據存儲以及展示方面的設計,接著就是怎么實現,如果你對比勤勞,可以原生實現,終究上面的實現法子已經描述清晰,寫點代碼實現就搞定了,今天我要推選的是應用 spatie/laravel-activitylog 來實現:

安裝一直很簡單對吧:

$ composer install spatie/laravel-activitylog -vvv

記載動態

activity()->log('Look, I logged something');

當然了這種記載沒意義,幾乎沒有任何有用的信息,所以我們通常的用法應該是這樣:

activity() ->performedOn($anEloquentModel) ->causedBy($user) ->withProperties(['customProperty' => 'customValue']) ->log('Look, I logged something'); $lastLoggedActivity = Activity::all()->last(); $lastLoggedActivity->subject; //returns an instance of an eloquent model $lastLoggedActivity->causer; //returns an instance of your user model $lastLoggedActivity->getExtraProperty('customProperty'); //returns 'customValue' $lastLoggedActivity->description; //returns 'Look, I logged something'

法子介紹:

比如,我們要記載一條,用戶發布了討論:

$discussion = App\Discussion::create([...]); activity()->on($discussion) ->withProperty('event', 'discussion.created') ->log('發表了話題');

或者用戶注冊時,我要記載一條動態:

activity()->on($user) ->withProperty('event', 'user.created') ->log('加入 EasyWeChat');

你會發現我都沒有設置觸發者,因為這個模塊如果你沒設置觸發者默認就是當前登錄用戶。

展示動態

展示動態就是根據條件從數據庫拿出來,這里應用包供給的模型類:Spatie\Activitylog\Models\Activity

use Spatie\Activitylog\Models\Activity;

// 整個動態 $activities = Activity::all(); // 用戶 ID 為 2 的動態 $activities = Activity::causedBy(User::find(2))->paginate(15); // 以文章 ID 為 13 為主體的動態 $activities = Activity::forSubject(Post::find(13))->paginate(15);

接著就是遍歷展示就好了。

一些經驗與技術

設置一個專門的動態觀察者類來記載動態

$ ./artisan make:listener UserActivitySubscriber

代碼如下:

<?php namespace App\Listeners; class UserActivitySubscriber { protected $lisen = [ 'eloquent.created: App\User' => 'onUserCreated', 'eloquent.created: App\Discussion' => 'onDiscussionCreated', ]; public function subscribe($events) { foreach ($this->lisen as $event => $listener) { $events->lisen($event, __CLASS__.'@'.$listener); } } public function onUserCreated($user) { activity()->on($user) ->withProperty('event', 'user.created') ->log('加入 EasyWeChat'); } public function onDiscussionCreated($discussion) { activity()->on($discussion) ->withProperty('event', 'discussion.created')->log('發表了話題'); } }

然后我們去注冊這個訂閱類:

在 App\Providers\EventServiceProvider 中 $subscribe 中注冊這個訂閱類:

/** * @var array */ protected $subscribe = [ \App\Listeners\UserActivitySubscriber::class, ];

上面我們利用了 Eloquent 模型事件來監聽模型的變更,當各種模型事件創建的時候我們調用對應的法子來記載動態,所以實現起來非常的方便。

在事件屬性里記載關鍵信息

看到上面記載動態的時候你可能會問,只存儲了 ID,這種多態關聯,查詢的時候會壓力很大,比如,我們要將動態顯示為:

安小超 發布了文章 《自定義菜單的應用》

我們如果只是存儲了文章的 id 與類型,我們還需要查詢一次文章表,才干得到標題用于顯示,這樣一個動態列表的話,可能會幾十條 SQL 了,的確是這樣的,我的解決方案是這樣的:

其實我們的用戶動態是不要求 100% 精準的,所以,我如果在記載時把文章的標題一起存下來是不是就不用再查表了?其實就是,我們在動態列表需要展示的關鍵信息,比如標題這些一起用 withProperties 存起來,這樣就一條 SQL 解決了動態列表問題

這樣的做法也有弊端,比如文章改了標題的時候,這里就不同步了,當然你也可以在文章改動時來改這個屬性,不過我個人覺得沒有多大必要。終究動態就是記載了當時的情況,后來改標題了并沒有什么問題。

OK,用戶動態模塊的開發就分享到這里,如果你有更高檔的實現歡迎隨時交流。

關于好友動態部分的實現,根據你的使用量級,,以及好友關系的存儲各有不同,大家自己集思廣益即可,大部分都是先查好友關系再查動態,關聯查詢也可以,自己實現吧。

總結


評論列表(網友評論僅供網友表達個人看法,并不表明本站同意其觀點或證實其描述)

站點導航

您可能在找這些
黑龙江快乐十分走势图