前言
相信大家都知道,幾乎所有的社區應用都有用戶動態這個部分,用戶可以通過好友動態獲能取到更多感興趣的內容,從而提高社區活躍度和用戶粘性。它的實現相對來講比普通的內容發布要復雜一些,主要體現在內容多樣性上。
為了解決這個問題,我們得把這些不同類型的內容抽象,提取共性,使用相同的結構來處理,開發起來就會簡單很多。
概念抽象
用戶動態,顧名思義,動態的產生,就是一系列事件的歷史記錄,所以首先關注“事件”這個名詞,它有哪些屬性:
- 觸發者,基于社區所有的事件幾乎都是由用戶觸發的
- 事件主體,事件的主體信息,例如“xxx發布了文章” 中的 “文章”。
- 事件屬性,事件主體不同,所需要的附加信息也不同,比如事件類型。
- 發生時間,記錄事件產生的時間,當然了在我們的數據庫通常記錄了所有數據產生的時間。
我們將用戶動態抽象成只有 4 個基礎屬性的結構,就比較容易實現了:
- description 事件描述 - causer_id 或者 user_id 事件觸發者 - subject_id 主體 ID - subject_type 主體類型 - properties 事件附加屬性 - created_at 事件產生時間
而主體部分就是 Laravel 里的 morph relation, 多態關聯。
怎么展示
我們的動態展示需求通常有以下幾種:
- 我的好友的動態
- 某個人的動態,通常是個人中心
- 全部動態,比如 Laravel China 首頁的全部動態
- 動態搜索,比較少見
我最近正在開發 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'
方法介紹:
performedOn($model)
設置事件主體,也就是 Eloquent Model 實例causedBy($user)
設置事件觸發者, User 實例withProperties($properties)
上面我們概念里的事件屬性withProperty($key, $value)
事件屬性的單個用法log($description)
事件描述
比如,我們要記錄一條,用戶發布了討論:
$discussion = App\Discussion::create([...]); activity()->on($discussion) ->withProperty('event', 'discussion.created') ->log('發表了話題');
【網站聲明】本站除付費源碼經過測試外,其他素材未做測試,不保證完整性,網站上部分源碼僅限學習交流,請勿用于商業用途。如損害你的權益請聯系客服QQ:2655101040 給予處理,謝謝支持。