2025-10-14 17:03:05 +08:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace app\cunkebao\controller;
|
|
|
|
|
|
|
|
|
|
class RFMController extends BaseController
|
|
|
|
|
{
|
|
|
|
|
/**
|
|
|
|
|
* 计算 RFM 评分(默认规则)
|
|
|
|
|
* @param int|null $recencyDays 最近购买天数
|
|
|
|
|
* @param int $frequency 购买次数
|
|
|
|
|
* @param float $monetary 购买金额
|
|
|
|
|
* @return array{R:int,F:int,M:int}
|
|
|
|
|
*/
|
2025-10-20 14:22:20 +08:00
|
|
|
public static function calcRfmScores($recencyDays = 30, $frequency, $monetary)
|
2025-10-14 17:03:05 +08:00
|
|
|
{
|
|
|
|
|
$recencyDays = is_numeric($recencyDays) ? (int)$recencyDays : 9999;
|
|
|
|
|
$frequency = max(0, (int)$frequency);
|
|
|
|
|
$monetary = max(0, (float)$monetary);
|
|
|
|
|
return [
|
|
|
|
|
'R' => self::scoreR_Default($recencyDays),
|
|
|
|
|
'F' => self::scoreF_Default($frequency),
|
|
|
|
|
'M' => self::scoreM_Default($monetary),
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 默认规则
|
|
|
|
|
protected static function scoreR_Default(int $days): int
|
|
|
|
|
{
|
|
|
|
|
if ($days <= 30) return 5;
|
|
|
|
|
if ($days <= 60) return 4;
|
|
|
|
|
if ($days <= 90) return 3;
|
|
|
|
|
if ($days <= 120) return 2;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
protected static function scoreF_Default(int $times): int
|
|
|
|
|
{
|
|
|
|
|
if ($times >= 10) return 5;
|
|
|
|
|
if ($times >= 6) return 4;
|
|
|
|
|
if ($times >= 3) return 3;
|
|
|
|
|
if ($times >= 2) return 2;
|
|
|
|
|
if ($times >= 1) return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
protected static function scoreM_Default(float $amount): int
|
|
|
|
|
{
|
|
|
|
|
if ($amount >= 2000) return 5;
|
|
|
|
|
if ($amount >= 1000) return 4;
|
|
|
|
|
if ($amount >= 500) return 3;
|
|
|
|
|
if ($amount >= 200) return 2;
|
|
|
|
|
if ($amount > 0) return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|