Files
links/application/common/service/SplitNumberWeighService.php
T

77 lines
2.3 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
namespace app\common\service;
use app\admin\model\split\Link;
/**
* 分流链接随机打乱配置与落地页选号
*
* - random_shuffle=0:跨工单合并号码池,按 id 顺序全局严格轮转
* - random_shuffle=1:先按各工单开启号码数比例随机选工单,再在该工单内随机选号
* - 同步写入时 random_shuffle=1 还会打乱新号码 insert 顺序(影响 id 分布)
*/
class SplitNumberWeighService
{
/**
* 链接是否开启随机打乱
*/
public static function isRandomShuffleEnabled(int $linkId): bool
{
if ($linkId <= 0) {
return false;
}
return (int) Link::where('id', $linkId)->value('random_shuffle') === 1;
}
/**
* 解析本次访问应使用的号码下标(0 .. numberCount-1
*
* @param int $linkId 分流链接 ID
* @param int $numberCount 可用号码数量
* @param SplitRoundRobinStore $roundRobinStore 关闭随机打乱时的轮转计数器
* @param string $poolKey 选号池标识(preferred / deferred 等)
*/
public static function resolvePickIndex(
int $linkId,
int $numberCount,
SplitRoundRobinStore $roundRobinStore,
string $poolKey = 'main'
): int {
if ($numberCount <= 0) {
return 0;
}
if ($numberCount === 1) {
return 0;
}
if (self::isRandomShuffleEnabled($linkId)) {
return random_int(0, $numberCount - 1);
}
return $roundRobinStore->nextIndex($linkId, $numberCount, $poolKey);
}
/**
* 从号码行列表中按链接配置选一条(严格轮转或随机)
*
* @param array<int, array<string, mixed>|Number> $rows
* @return array<string, mixed>|Number|null
*/
public static function pickRowFromList(
int $linkId,
array $rows,
SplitRoundRobinStore $roundRobinStore,
string $poolKey = 'main'
) {
$count = count($rows);
if ($count === 0) {
return null;
}
$index = self::resolvePickIndex($linkId, $count, $roundRobinStore, $poolKey);
return $rows[$index] ?? $rows[0];
}
}