Files
tcpserver-flow/app/flow/OperatorSessionManager.php
T
2026-03-08 22:58:56 +08:00

132 lines
3.5 KiB
PHP
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
namespace app\flow;
use app\config\Config;
use app\utils\Logger;
/**
* 操作员会话管理器(进程内单例)
*
* 职责:记录每个读卡器上最近一次刷过的人员卡信息。
* 流程规则:
* 1. 先刷人员卡 → 记录到本管理器(以 readerId 为 key
* 2. 再刷内镜卡 → 从本管理器取出操作员信息,写入 ProcessContext,随即清除会话
* 3. 无论内镜卡刷卡结果正确还是错误,会话均立即清除,下次需重新刷人员卡
*/
class OperatorSessionManager
{
/**
* 单例实例
*/
private static ?self $instance = null;
/**
* 会话存储:[readerId => ['id'=>..., 'name'=>..., 'rfid'=>...]]
*/
private array $sessions = [];
/**
* 人员刷卡记录缓存记录多久
*/
public int $expire = 0;
/**
* 人员刷卡记录记录哪些读卡器的
* 设置为空则表示所有读卡器
*/
public array $recordReaders = [];
private function __construct()
{
$this->expire = Config::getInstance()->openCardRecordCacheTime;
$this->recordReaders = Config::getInstance()->openCardRecordReaders;
}
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 重置单例(测试用)
*/
public static function resetInstance(): void
{
self::$instance = null;
}
/**
* 记录某读卡器上的操作员信息
*
* @param string $readerId 读卡器ID
* @param string $userId 操作员ID
* @param string $userName 操作员姓名
* @param string $userRfid 操作员RFID
*/
public function setOperator(string $readerId, string $userId, string $userName, string $userRfid): void
{
$this->sessions[$readerId] = [
'id' => $userId,
'name' => $userName,
'rfid' => $userRfid,
'time' => time(),
];
}
/**
* 获取某读卡器上记录的操作员信息
*
* @param string $readerId 读卡器ID
* @return array|null ['id'=>..., 'name'=>..., 'rfid'=>...] 或 null(未登记)
*/
public function getOperator(string $readerId, string $readerType): ?array
{
$cache = $this->sessions[$readerId] ?? null;
$time = $cache['time'];
Logger::debug("OperatorSessionManager::getOperator($readerId, $readerType)");
if (empty($cache)) return null;
if ($this->expire > 0 && isset($time) && (time() - $time) <= $this->expire) {
if (in_array($readerType, $this->recordReaders) && empty($this->recordReaders)) {
return $cache;
}
}
return $this->pop($readerId);
}
/**
* 判断某读卡器是否已有操作员登记
*/
public function hasOperator(string $readerId): bool
{
return isset($this->sessions[$readerId]);
}
/**
* 清除某读卡器的操作员会话(内镜卡刷卡后立即调用)
*/
public function clearOperator(string $readerId): void
{
unset($this->sessions[$readerId]);
}
/**
* 清除所有会话(测试用)
*/
public function clearAll(): void
{
$this->sessions = [];
}
public function pop(string $readerId): ?array
{
$op = $this->getOperator($readerId);
$this->clearOperator($readerId);
return $op;
}
}