Files
tcpserver-flow/app/flow/OperatorSessionManager.php
T
zimoyin f2ff4ae123 ai-chore(config): 调整流程配置及改进测试代码
- 将 FLOW_USE_CUSTOM_PROCESS 从 true 改为 false,禁用自定义流程
- 在 BlockTest 测试用例中改用 setBlockMode 方法设置阻断模式
- 设置统一的错误处理,将错误转为异常抛出
- 重命名 BlockTest 测试文件路径,优化测试组织结构
- 更新 IDE php include paths,调整依赖包引用顺序
- 删除无用的 tests/flow/Test.php 测试文件
- 微调 start.php、webman、windows.php 配置或代码模块
2026-03-11 13:48:40 +08:00

138 lines
3.7 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
{
$cache = $this->sessions[$readerId] ?? null;
if (empty($cache)) return false;
// 如果时间过去了,返回没有
if ($this->expire > 0 && isset($cache['time']) && (time() - $cache['time']) > $this->expire) {
return false;
}
return true;
}
/**
* 清除某读卡器的操作员会话(内镜卡刷卡后立即调用)
*/
public function clearOperator(string $readerId): void
{
unset($this->sessions[$readerId]);
}
/**
* 清除所有会话(测试用)
*/
public function clearAll(): void
{
$this->sessions = [];
}
public function pop(string $readerId): ?array
{
$op = $this->sessions[$readerId] ?? null;
$this->clearOperator($readerId);
return $op;
}
}