下号比率恢复 + 触线降权 + 同步裁决
This commit is contained in:
@@ -12,15 +12,21 @@ use think\Collection;
|
||||
* 分流链接落地页:查链、跨工单合并选号、拼接跳转 URL、访问计数
|
||||
*
|
||||
* 号码池为同一 split_link_id 下全部 status=normal 的号码;
|
||||
* 优先选用 ratio_deferred=0 的号码,全部触线降权时回退至降权池仍可轮转。
|
||||
* random_shuffle 关闭时严格轮转,开启时每次访问随机选号。
|
||||
*/
|
||||
class SplitRedirectService
|
||||
{
|
||||
private SplitRoundRobinStore $roundRobinStore;
|
||||
|
||||
public function __construct(?SplitRoundRobinStore $roundRobinStore = null)
|
||||
{
|
||||
private SplitNumberVisitRuleService $visitRuleService;
|
||||
|
||||
public function __construct(
|
||||
?SplitRoundRobinStore $roundRobinStore = null,
|
||||
?SplitNumberVisitRuleService $visitRuleService = null
|
||||
) {
|
||||
$this->roundRobinStore = $roundRobinStore ?? new SplitRoundRobinStore();
|
||||
$this->visitRuleService = $visitRuleService ?? new SplitNumberVisitRuleService();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,18 +59,16 @@ class SplitRedirectService
|
||||
$numbers = Number::where('split_link_id', (int) $link['id'])
|
||||
->where('status', 'normal')
|
||||
->order('id', 'asc')
|
||||
->field('id,number,number_type,number_type_custom')
|
||||
->field('id,number,number_type,number_type_custom,ratio_deferred')
|
||||
->select();
|
||||
|
||||
$count = is_countable($numbers) ? count($numbers) : 0;
|
||||
if ($count === 0) {
|
||||
$list = $numbers instanceof Collection ? $numbers->all() : (array) $numbers;
|
||||
if ($list === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$linkId = (int) $link->getAttr('id');
|
||||
$index = SplitNumberWeighService::resolvePickIndex($linkId, $count, $this->roundRobinStore);
|
||||
$list = $numbers instanceof \think\Collection ? $numbers->all() : (array) $numbers;
|
||||
$picked = $list[$index] ?? $list[0] ?? null;
|
||||
$picked = $this->pickNumberRow($linkId, $list);
|
||||
if ($picked === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -93,8 +97,38 @@ class SplitRedirectService
|
||||
$numberId = is_array($picked) ? (int) ($picked['id'] ?? 0) : (int) $picked->getAttr('id');
|
||||
if ($numberId > 0) {
|
||||
Number::where('id', $numberId)->setInc('visit_count');
|
||||
$this->visitRuleService->recordVisitAfterRedirect($numberId);
|
||||
}
|
||||
|
||||
return $redirectUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* 双层选号:优先 ratio_deferred=0,否则回退至降权池
|
||||
*
|
||||
* @param array<int, array<string, mixed>|Number> $rows
|
||||
* @return array<string, mixed>|Number|null
|
||||
*/
|
||||
private function pickNumberRow(int $linkId, array $rows)
|
||||
{
|
||||
$preferred = [];
|
||||
$deferred = [];
|
||||
foreach ($rows as $row) {
|
||||
$deferredFlag = is_array($row)
|
||||
? (int) ($row['ratio_deferred'] ?? 0)
|
||||
: (int) $row->getAttr('ratio_deferred');
|
||||
if ($deferredFlag === 1) {
|
||||
$deferred[] = $row;
|
||||
} else {
|
||||
$preferred[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
$picked = SplitNumberWeighService::pickRowFromList($linkId, $preferred, $this->roundRobinStore, 'preferred');
|
||||
if ($picked !== null) {
|
||||
return $picked;
|
||||
}
|
||||
|
||||
return SplitNumberWeighService::pickRowFromList($linkId, $deferred, $this->roundRobinStore, 'deferred');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user