活跃的用户
This commit is contained in:
parent
cffe2ec89c
commit
d1e0c21a9a
44
app/Console/Commands/CalculateActiveUser.php
Normal file
44
app/Console/Commands/CalculateActiveUser.php
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class CalculateActiveUser extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'larabbs:calculate-active-user';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = '生成活跃用户';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
* @param User $user
|
||||||
|
*/
|
||||||
|
public function handle(User $user)
|
||||||
|
{
|
||||||
|
$this->info('开始计算!');
|
||||||
|
$user->calculateAndCacheActiveUsers();
|
||||||
|
$this->info('生成成功!');
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ class Kernel extends ConsoleKernel
|
||||||
{
|
{
|
||||||
// $schedule->command('inspire')
|
// $schedule->command('inspire')
|
||||||
// ->hourly();
|
// ->hourly();
|
||||||
|
$schedule->command('larabbs:calculate-active-user')->hourly();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4,13 +4,15 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\Topic;
|
use App\Models\Topic;
|
||||||
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class CategoriesController extends Controller
|
class CategoriesController extends Controller
|
||||||
{
|
{
|
||||||
public function show(Category $category, Request $request)
|
public function show(Category $category, Request $request, User $user)
|
||||||
{
|
{
|
||||||
$topics = Topic::where('category_id', $category->id)->withOrder($request->order)->with('user', 'category')->paginate();
|
$topics = Topic::where('category_id', $category->id)->withOrder($request->order)->with('user', 'category')->paginate();
|
||||||
return view('topics.index', compact('topics', 'category'));
|
$active_users = $user->getActiveUsers();
|
||||||
|
return view('topics.index', compact('topics', 'category', 'active_users'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace App\Http\Controllers;
|
||||||
use App\Http\Requests\TopicRequest;
|
use App\Http\Requests\TopicRequest;
|
||||||
use App\Models\Category;
|
use App\Models\Category;
|
||||||
use App\Models\Topic;
|
use App\Models\Topic;
|
||||||
|
use App\Models\User;
|
||||||
use App\Tools\ImageUploadTool;
|
use App\Tools\ImageUploadTool;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
@ -22,10 +23,11 @@ class TopicsController extends Controller
|
||||||
return view('topics.create_and_edit', compact('topic', 'categories'));
|
return view('topics.create_and_edit', compact('topic', 'categories'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request, Topic $topic)
|
public function index(Request $request, Topic $topic, User $user)
|
||||||
{
|
{
|
||||||
|
$active_users = $user->getActiveUsers();
|
||||||
$topics = $topic->with('user', 'category')->withOrder($request->order)->paginate();
|
$topics = $topic->with('user', 'category')->withOrder($request->order)->paginate();
|
||||||
return view('topics.index', compact('topics'));
|
return view('topics.index', compact('topics', 'active_users'));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function show(Topic $topic, Request $request)
|
public function show(Topic $topic, Request $request)
|
||||||
|
|
96
app/Models/Traits/ActiveUserHelper.php
Normal file
96
app/Models/Traits/ActiveUserHelper.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Created by PhpStorm.
|
||||||
|
* User: xing
|
||||||
|
* Date: 2018/6/2
|
||||||
|
* Time: 17:16
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Models\Traits;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Models\Reply;
|
||||||
|
use App\Models\Topic;
|
||||||
|
use Carbon\Carbon;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
trait ActiveUserHelper
|
||||||
|
{
|
||||||
|
protected $users = [];
|
||||||
|
|
||||||
|
protected $topic_weight = 4;
|
||||||
|
protected $reply_weight = 1;
|
||||||
|
protected $pass_days = 7;
|
||||||
|
protected $user_number = 6;
|
||||||
|
|
||||||
|
protected $cache_key = 'larabbs_active_users';
|
||||||
|
protected $cache_expire_in_minutes = 65;
|
||||||
|
|
||||||
|
public function getActiveUsers()
|
||||||
|
{
|
||||||
|
return Cache::remember($this->cache_key, $this->cache_expire_in_minutes, function () {
|
||||||
|
return $this->calculateActiveUsers();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculateActiveUsers()
|
||||||
|
{
|
||||||
|
$this->calculateTopicScore();
|
||||||
|
$this->calculateReplyScore();
|
||||||
|
$users = array_sort($this->users, function ($user) {
|
||||||
|
return $user['score'];
|
||||||
|
});
|
||||||
|
$users = array_reverse($users, true);
|
||||||
|
$users = array_slice($users, 0, $this->user_number, true);
|
||||||
|
$active_users = collect();
|
||||||
|
foreach ($users as $user_id => $user) {
|
||||||
|
$user = $this->find($user_id);
|
||||||
|
if ($user) {
|
||||||
|
$active_users->push($user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $active_users;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function calculateTopicScore()
|
||||||
|
{
|
||||||
|
// 从话题数据表里取出限定时间范围($pass_days)内,有发表过话题的用户
|
||||||
|
// 并且同时取出用户此段时间内发布话题的数量
|
||||||
|
$topic_users = Topic::query()->select(\DB::raw('user_id, count(*) as topic_count'))
|
||||||
|
->where('created_at', '>=', Carbon::now()->subDays($this->pass_days))
|
||||||
|
->groupBy('user_id')
|
||||||
|
->get();
|
||||||
|
// 根据话题数量计算得分
|
||||||
|
foreach ($topic_users as $value) {
|
||||||
|
$this->users[$value->user_id]['score'] = $value->topic_count * $this->topic_weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function calculateReplyScore()
|
||||||
|
{
|
||||||
|
$reply_users = Reply::query()
|
||||||
|
->select(\DB::raw('user_id,count(*) as reply_count'))
|
||||||
|
->where('created_at', '>=', Carbon::now()->subDays($this->pass_days))
|
||||||
|
->groupBy('user_id')
|
||||||
|
->get();
|
||||||
|
foreach ($reply_users as $value) {
|
||||||
|
$reply_score = $value->reply_count * $this->reply_weight;
|
||||||
|
if (isset($this->users[$value->user_id])) {
|
||||||
|
$this->users[$value->user_id]['score'] += $reply_score;
|
||||||
|
} else {
|
||||||
|
$this->users[$value->user_id]['score'] = $reply_score;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function calculateAndCacheActiveUsers()
|
||||||
|
{
|
||||||
|
$active_users = $this->calculateActiveUsers();
|
||||||
|
$this->cacheActiveUsers($active_users);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function cacheActiveUsers($active_users)
|
||||||
|
{
|
||||||
|
Cache::put($this->cache_key, $active_users, $this->cache_expire_in_minutes);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Models\Traits\ActiveUserHelper;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
@ -13,6 +14,7 @@ class User extends Authenticatable
|
||||||
notify as protected laravelNotify;
|
notify as protected laravelNotify;
|
||||||
}
|
}
|
||||||
use HasRoles;
|
use HasRoles;
|
||||||
|
use ActiveUserHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The attributes that are mass assignable.
|
* The attributes that are mass assignable.
|
||||||
|
|
19
public/css/app.css
vendored
19
public/css/app.css
vendored
|
@ -8457,6 +8457,25 @@ body {
|
||||||
border-bottom: 1px solid #efefef;
|
border-bottom: 1px solid #efefef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
sidebar
|
||||||
|
*/
|
||||||
|
|
||||||
|
.sidebar .panel-body {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar hr {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar .active-users a.media {
|
||||||
|
color: #797878;
|
||||||
|
line-height: 26px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
|
||||||
/* Topic Index Page */
|
/* Topic Index Page */
|
||||||
|
|
||||||
.topics-index-page .topic-list .nav > li > a,
|
.topics-index-page .topic-list .nav > li > a,
|
||||||
|
|
22
resources/assets/sass/app.scss
vendored
22
resources/assets/sass/app.scss
vendored
|
@ -112,6 +112,28 @@ body {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
sidebar
|
||||||
|
*/
|
||||||
|
.sidebar {
|
||||||
|
.panel-body {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-users {
|
||||||
|
a.media {
|
||||||
|
color: #797878;
|
||||||
|
line-height: 26px;
|
||||||
|
font-size: 0.9em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Topic Index Page */
|
/* Topic Index Page */
|
||||||
.topics-index-page, .categories-show-page {
|
.topics-index-page, .categories-show-page {
|
||||||
.topic-list {
|
.topic-list {
|
||||||
|
|
|
@ -6,3 +6,22 @@
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@if(count($active_users))
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-body active_users">
|
||||||
|
<div class="text-center">活跃用户</div>
|
||||||
|
<hr>
|
||||||
|
@foreach($active_users as $active_user)
|
||||||
|
<a class="media" href="{{route('users.show',$active_user->id)}}">
|
||||||
|
<div class="media-left media-middle">
|
||||||
|
<img src="{{$active_user->avatar}}" width="24px" height="24px" class="img-circle media-object"
|
||||||
|
alt="header">
|
||||||
|
</div>
|
||||||
|
<div class="media-body">
|
||||||
|
<span class="media-heading">{{$active_user->name}}</span>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"site_name": "larabbs - Powered by LaraBBS",
|
"site_name": "larabbs - Powered by LaraBBS",
|
||||||
"contact_email": "fthvgb1@163.com",
|
"contact_email": "fthvgb2@163.com",
|
||||||
"seo_description": "laravel\u642d\u5efa\u7684bbs",
|
"seo_description": "laravel\u642d\u5efa\u7684bbs",
|
||||||
"seo_keyword": "laravel,bbs,laravel\u793e\u533a"
|
"seo_keyword": "laravel,bbs,laravel\u793e\u533a"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user