Files
zyt/server/app/common/service/qywx/QywxPromotionMemberRange.php
T
2026-08-31 15:17:34 +08:00

98 lines
3.3 KiB
PHP

<?php
declare(strict_types=1);
namespace app\common\service\qywx;
/** 计算应交给企业微信官方多人路由的成员范围。 */
class QywxPromotionMemberRange
{
/**
* @param list<array<string,mixed>> $members
* @return array{userids:list<string>,members:list<array<string,mixed>>,eligible_count:int}
*/
public static function evaluate(array $members, string $today, int $now, array $config = []): array
{
$userIds = [];
$backups = array_fill_keys((array) ($config['backup_userids'] ?? []), true);
$backupIds = [];
$scheduled = ($config['reception_mode'] ?? 'always') === 'scheduled';
$scheduledUsers = [];
if ($scheduled) {
foreach ((array) ($config['reception_schedule'] ?? []) as $slot) {
if (QywxPromotionConfig::matches($slot, $now)) {
foreach ((array) ($slot['member_userids'] ?? []) as $userId) {
$scheduledUsers[$userId] = true;
}
}
}
}
foreach ($members as &$member) {
if ((string) ($member['today_date'] ?? '') !== $today) {
$member['today_date'] = $today;
$member['today_count'] = 0;
}
$member['current_weight'] = 0;
if (!self::eligible($member, $now)) {
continue;
}
$userId = trim((string) ($member['userid'] ?? ''));
if ($userId !== '') {
if (isset($backups[$userId])) {
$backupIds[$userId] = true;
} elseif (!$scheduled || isset($scheduledUsers[$userId])) {
$userIds[$userId] = true;
}
}
}
unset($member);
$usingBackup = $userIds === [] && $backupIds !== [];
if ($usingBackup) {
$userIds = $backupIds;
}
return [
'userids' => array_keys($userIds),
'members' => array_values($members),
'eligible_count' => count($userIds),
'using_backup' => $usingBackup,
];
}
/** @param array<string,mixed> $member */
public static function eligible(array $member, int $now): bool
{
if ((int) ($member['enabled'] ?? 0) !== 1) {
return false;
}
$start = max(0, (int) ($member['active_start'] ?? 0));
$end = max(0, (int) ($member['active_end'] ?? 0));
if (($start > 0 && $start > $now) || ($end > 0 && $end < $now)) {
return false;
}
$limit = max(0, (int) ($member['daily_limit'] ?? 0));
return $limit === 0 || (int) ($member['today_count'] ?? 0) < $limit;
}
/** @param list<string> $left @param list<string> $right */
public static function same(array $left, array $right): bool
{
$normalise = static function (array $values): array {
$result = [];
foreach ($values as $value) {
$userId = trim((string) $value);
if ($userId !== '') {
$result[$userId] = true;
}
}
$result = array_keys($result);
sort($result, SORT_STRING);
return $result;
};
return $normalise($left) === $normalise($right);
}
}