mirror of
https://gitee.com/koogua/course-tencent-cloud.git
synced 2025-06-25 12:09:09 +08:00
更新课程综合评分算法
This commit is contained in:
parent
1ff7aa3be6
commit
281ec37970
44
app/Console/Tasks/SyncCourseScoreTask.php
Normal file
44
app/Console/Tasks/SyncCourseScoreTask.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Tasks;
|
||||||
|
|
||||||
|
use App\Repos\Course as CourseRepo;
|
||||||
|
use App\Services\CourseStat as CourseStatService;
|
||||||
|
use App\Services\Sync\CourseScore as CourseScoreSync;
|
||||||
|
|
||||||
|
class SyncCourseScoreTask extends Task
|
||||||
|
{
|
||||||
|
|
||||||
|
public function mainAction()
|
||||||
|
{
|
||||||
|
$redis = $this->getRedis();
|
||||||
|
|
||||||
|
$key = $this->getSyncKey();
|
||||||
|
|
||||||
|
$courseIds = $redis->sRandMember($key, 1000);
|
||||||
|
|
||||||
|
if (!$courseIds) return;
|
||||||
|
|
||||||
|
$courseRepo = new CourseRepo();
|
||||||
|
|
||||||
|
$courses = $courseRepo->findByIds($courseIds);
|
||||||
|
|
||||||
|
if ($courses->count() == 0) return;
|
||||||
|
|
||||||
|
$statService = new CourseStatService();
|
||||||
|
|
||||||
|
foreach ($courses as $course) {
|
||||||
|
$statService->updateScore($course->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
$redis->sRem($key, ...$courseIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getSyncKey()
|
||||||
|
{
|
||||||
|
$sync = new CourseScoreSync();
|
||||||
|
|
||||||
|
return $sync->getSyncKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -4,6 +4,7 @@ namespace App\Models;
|
|||||||
|
|
||||||
use App\Caches\MaxCourseId as MaxCourseIdCache;
|
use App\Caches\MaxCourseId as MaxCourseIdCache;
|
||||||
use App\Services\Sync\CourseIndex as CourseIndexSync;
|
use App\Services\Sync\CourseIndex as CourseIndexSync;
|
||||||
|
use App\Services\Sync\CourseScore as CourseScoreSync;
|
||||||
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
use Phalcon\Mvc\Model\Behavior\SoftDelete;
|
||||||
use Phalcon\Text;
|
use Phalcon\Text;
|
||||||
|
|
||||||
@ -309,6 +310,9 @@ class Course extends Model
|
|||||||
if (time() - $this->update_time > 3 * 3600) {
|
if (time() - $this->update_time > 3 * 3600) {
|
||||||
$sync = new CourseIndexSync();
|
$sync = new CourseIndexSync();
|
||||||
$sync->addItem($this->id);
|
$sync->addItem($this->id);
|
||||||
|
|
||||||
|
$sync = new CourseScoreSync();
|
||||||
|
$sync->addItem($this->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Text::startsWith($this->cover, 'http')) {
|
if (Text::startsWith($this->cover, 'http')) {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Models\Course as CourseModel;
|
||||||
use App\Repos\Course as CourseRepo;
|
use App\Repos\Course as CourseRepo;
|
||||||
use App\Repos\CourseRating as CourseRatingRepo;
|
use App\Repos\CourseRating as CourseRatingRepo;
|
||||||
|
|
||||||
@ -58,9 +59,19 @@ class CourseStat extends Service
|
|||||||
|
|
||||||
public function updateScore($courseId)
|
public function updateScore($courseId)
|
||||||
{
|
{
|
||||||
/**
|
$courseRepo = new CourseRepo();
|
||||||
* @todo 计算综合评分
|
|
||||||
*/
|
$course = $courseRepo->findById($courseId);
|
||||||
|
|
||||||
|
if ($course->market_price == 0) {
|
||||||
|
$score = $this->calculateFreeCourseScore($course);
|
||||||
|
} else {
|
||||||
|
$score = $this->calculateChargeCourseScore($course);
|
||||||
|
}
|
||||||
|
|
||||||
|
$course->score = $score;
|
||||||
|
|
||||||
|
$course->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateReadAttrs($courseId)
|
public function updateReadAttrs($courseId)
|
||||||
@ -181,4 +192,72 @@ class CourseStat extends Service
|
|||||||
$course->update(['attrs' => $attrs]);
|
$course->update(['attrs' => $attrs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function calculateFreeCourseScore(CourseModel $course)
|
||||||
|
{
|
||||||
|
$weight = [
|
||||||
|
'factor1' => 0.1,
|
||||||
|
'factor2' => 0.25,
|
||||||
|
'factor3' => 0.2,
|
||||||
|
'factor4' => 0.1,
|
||||||
|
'factor5' => 0.25,
|
||||||
|
'factor6' => 0.1,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->calculateCourseScore($course, $weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function calculateChargeCourseScore(CourseModel $course)
|
||||||
|
{
|
||||||
|
$weight = [
|
||||||
|
'factor1' => 0.1,
|
||||||
|
'factor2' => 0.3,
|
||||||
|
'factor3' => 0.15,
|
||||||
|
'factor4' => 0.15,
|
||||||
|
'factor5' => 0.2,
|
||||||
|
'factor6' => 0.1,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $this->calculateCourseScore($course, $weight);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function calculateCourseScore(CourseModel $course, $weight)
|
||||||
|
{
|
||||||
|
$items = [
|
||||||
|
'factor1' => 0.0,
|
||||||
|
'factor2' => 0.0,
|
||||||
|
'factor3' => 0.0,
|
||||||
|
'factor4' => 0.0,
|
||||||
|
'factor5' => 0.0,
|
||||||
|
'factor6' => 0.0,
|
||||||
|
];
|
||||||
|
|
||||||
|
$items['factor1'] = ($course->featured == 1 ? 1 : 0) * 10 * $weight['factor1'];
|
||||||
|
|
||||||
|
if ($course->user_count > 0) {
|
||||||
|
$items['factor2'] = log($course->user_count) * $weight['factor2'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course->favorite_count > 0) {
|
||||||
|
$items['factor3'] = log($course->favorite_count) * $weight['factor3'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course->consult_count > 0) {
|
||||||
|
$items['factor4'] = log($course->consult_count) * $weight['factor4'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($course->review_count > 0 && $course->rating > 0) {
|
||||||
|
$items['factor5'] = log($course->review_count * $course->rating) * $weight['factor5'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$sumCount = $course->lesson_count + $course->package_count + $course->resource_count;
|
||||||
|
|
||||||
|
if ($sumCount > 0) {
|
||||||
|
$items['factor6'] = log($sumCount) * $weight['factor6'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$score = array_sum($items) / log(time() - $course->create_time);
|
||||||
|
|
||||||
|
return round($score, 4);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
33
app/Services/Sync/CourseScore.php
Normal file
33
app/Services/Sync/CourseScore.php
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Services\Sync;
|
||||||
|
|
||||||
|
use App\Services\Service;
|
||||||
|
|
||||||
|
class CourseScore extends Service
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $lifetime = 86400;
|
||||||
|
|
||||||
|
public function addItem($courseId)
|
||||||
|
{
|
||||||
|
$redis = $this->getRedis();
|
||||||
|
|
||||||
|
$key = $this->getSyncKey();
|
||||||
|
|
||||||
|
$redis->sAdd($key, $courseId);
|
||||||
|
|
||||||
|
if ($redis->sCard($key) == 1) {
|
||||||
|
$redis->expire($key, $this->lifetime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSyncKey()
|
||||||
|
{
|
||||||
|
return 'sync_course_score';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -40,6 +40,9 @@ $scheduler->php($script, $bin, ['--task' => 'sync_group_index', '--action' => 'm
|
|||||||
$scheduler->php($script, $bin, ['--task' => 'sync_user_index', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'sync_user_index', '--action' => 'main'])
|
||||||
->hourly(23);
|
->hourly(23);
|
||||||
|
|
||||||
|
$scheduler->php($script, $bin, ['--task' => 'sync_course_score', '--action' => 'main'])
|
||||||
|
->hourly(29);
|
||||||
|
|
||||||
$scheduler->php($script, $bin, ['--task' => 'clean_log', '--action' => 'main'])
|
$scheduler->php($script, $bin, ['--task' => 'clean_log', '--action' => 'main'])
|
||||||
->daily(3, 3);
|
->daily(3, 3);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user