You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
|
|
|
|
|
|
|
use App\Models\DictItem;
|
|
|
|
|
|
use Carbon\Carbon;
|
|
|
|
|
|
use Carbon\CarbonInterface;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 星级 → 下次跟进日规则(对齐 prototype teachers.html / teacher-detail.html)。
|
|
|
|
|
|
*/
|
|
|
|
|
|
class TeacherFollowPlanService
|
|
|
|
|
|
{
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据星级字典项 value 计算下次跟进日;待定返回 null。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function nextFollowDateFromStar(?DictItem $starItem, ?CarbonInterface $base = null): ?Carbon
|
|
|
|
|
|
{
|
|
|
|
|
|
if (! $starItem) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$days = $this->daysByStarValue((string) $starItem->value);
|
|
|
|
|
|
if ($days === null) {
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$base = $base ? Carbon::parse($base) : Carbon::today();
|
|
|
|
|
|
|
|
|
|
|
|
return $base->copy()->addDays($days);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @return int|null 追加天数;null 表示不生成下次跟进日
|
|
|
|
|
|
*/
|
|
|
|
|
|
public function daysByStarValue(string $value): ?int
|
|
|
|
|
|
{
|
|
|
|
|
|
return match ($value) {
|
|
|
|
|
|
'1' => 365,
|
|
|
|
|
|
'2', '3' => 180,
|
|
|
|
|
|
'4', '5' => 90,
|
|
|
|
|
|
default => null,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function starLabelToValue(string $label): ?string
|
|
|
|
|
|
{
|
|
|
|
|
|
return match ($label) {
|
|
|
|
|
|
'一星' => '1',
|
|
|
|
|
|
'二星' => '2',
|
|
|
|
|
|
'三星' => '3',
|
|
|
|
|
|
'四星' => '4',
|
|
|
|
|
|
'五星' => '5',
|
|
|
|
|
|
'待定' => 'pending',
|
|
|
|
|
|
default => null,
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|