12 KiB
12 KiB
内镜清洗流程管理系统 - 使用与配置
一、快速开始
1.1 基础使用示例
use app\flow\FlowProcessor;
use app\flow\config\ProcessConfig;
use app\net\PacketContext;
// 接收刷卡数据
public function onMessage(TcpConnection $connection, $data): void
{
// 1. 解析数据包
$packet = PacketParserFactory::parse($data);
$packetContext = new PacketContext($connection, $packet);
// 2. 创建流程处理器(使用标准配置)
$config = ProcessConfig::createStandard();
$processor = new FlowProcessor($config);
// 3. 处理流程
$result = $processor->process($packetContext);
// 4. 输出结果
if ($result->success) {
echo "语音播报: " . $result->getFullVoice();
echo "当前步骤: " . $result->currentStep;
echo "批次号: " . $result->batchNo;
} else {
echo "错误: " . $result->errorMessage;
}
}
二、配置方式
2.1 预置配置
use app\flow\config\ProcessConfig;
// 标准完整流程
$config = ProcessConfig::createStandard();
// 无晨洗流程
$config = ProcessConfig::createNoMorningWash();
// 简化流程(只清洗)
$config = ProcessConfig::createSimple();
// 机洗流程
$config = ProcessConfig::createMachineWash();
// 无干燥流程
$config = ProcessConfig::createNoDry();
// 仅干燥流程
$config = ProcessConfig::createDryOnly();
2.2 自定义配置
use app\flow\config\ProcessConfig;
$config = new ProcessConfig([
// 定义的 steps 是带有顺序的
// 流程步骤配置
'steps' => [
['code' => '清洗', 'class' => 'WashNode', 'enabled' => true],
['code' => '消毒', 'class' => 'DisinfectNode', 'enabled' => true],
['code' => '结束', 'class' => 'EndNode', 'enabled' => true],
],
// 晨洗配置
'morning_wash' => [
'mode' => 'storage_time', // 根据存储时间判断
'storage_threshold' => 4, // 4小时阈值
'morning_start_time' => '06:00:00',
],
// 时间验证配置
'time_validation' => [
'durations' => [
'清洗' => 300, // 5分钟
'消毒' => 600, // 10分钟(自定义)
],
],
// 语音模板配置
'voice_templates' => [
'custom' => [
'清洗' => '第一步清洗开始',
'消毒' => '第三步消毒开始,请确保消毒时间',
],
],
]);
2.3 动态调整配置
use app\flow\ProcessEngine;
$engine = ProcessEngine::createStandard();
// 禁用某些步骤
$engine->disableNode('干燥');
$engine->disableNode('终末漂洗');
// 启用步骤
$engine->enableNode('干燥');
// 设置自定义语音
$engine->setStepVoice('清洗', '请开始清洗');
// 设置晨洗模式
$engine->setMorningWashMode('none');
三、晨洗模式配置
3.1 不需要晨洗
$config = new ProcessConfig([
'morning_wash' => [
'mode' => 'none',
],
]);
3.2 所有镜子都需要晨洗
$config = new ProcessConfig([
'morning_wash' => [
'mode' => 'all',
],
]);
3.3 根据存储时间判断(义乌模式)
$config = new ProcessConfig([
'morning_wash' => [
'mode' => 'storage_time',
'storage_threshold' => 4, // 超过4小时需要晨洗
'morning_start_time' => '06:00:00',
],
]);
3.4 每天第一次需要晨洗(忠县模式)
$config = new ProcessConfig([
'morning_wash' => [
'mode' => 'daily_first',
'morning_start_time' => '06:00:00',
],
]);
3.5 特定类型镜子需要晨洗
$config = new ProcessConfig([
'morning_wash' => [
'mode' => 'specific_types',
'specific_types' => ['胃镜', '十二指肠镜'],
],
]);
四、医院特殊流程配置
4.1 机洗后不允许刷终末漂洗
use app\flow\ProcessEngine;
$engine = ProcessEngine::createStandard();
// 获取终末漂洗节点并配置
$finalRinseNode = $engine->getNode('终末漂洗');
$finalRinseNode->setAllowAfterMachineWash(false);
效果:机洗完成后,刷卡到终末漂洗读卡器会提示错误,只能刷干燥或结束。
4.2 机洗后必须直接刷干燥
$dryNode = $engine->getNode('干燥');
$dryNode->setRequireDirectAfterMachineWash(true);
效果:机洗完成后,必须刷干燥或结束,不能刷其他步骤。
4.3 自定义步骤时间
use app\flow\strategies\TimeValidationStrategy;
$strategy = new TimeValidationStrategy([
'durations' => [
'清洗' => 600, // 10分钟
'消毒' => 900, // 15分钟
],
]);
$engine->addStrategy('time_validation', $strategy);
4.4 自定义语音模板
$engine->setStepVoice('清洗', '第一步:请开始清洗内镜');
$engine->setStepVoice('消毒', '第三步:消毒时间必须达到5分钟');
$engine->setStepVoice('结束', '清洗流程完成,请妥善保管');
五、从配置文件加载
5.1 创建配置文件
// config/flow/hospital_a.php
return [
'name' => '医院A-无晨洗流程',
'morning_wash' => [
'mode' => 'none',
],
'steps' => [
['code' => '清洗', 'class' => 'WashNode', 'enabled' => true],
['code' => '漂洗', 'class' => 'RinseNode', 'enabled' => true],
['code' => '消毒', 'class' => 'DisinfectNode', 'enabled' => true],
['code' => '终末漂洗', 'class' => 'FinalRinseNode', 'enabled' => true],
['code' => '干燥', 'class' => 'DryNode', 'enabled' => true],
['code' => '结束', 'class' => 'EndNode', 'enabled' => true],
],
];
5.2 加载配置
$config = ProcessConfig::fromFile(__DIR__ . '/config/flow/hospital_a.php');
$processor = new FlowProcessor($config);
六、全局配置类(Config.php)
6.1 配置类说明
系统提供全局配置单例类 app\config\Config,用于统一管理数据库配置和自定义流程配置:
use app\config\Config;
// 获取配置实例
$config = Config::getInstance();
// 获取数据库配置
$databaseConfig = $config->database;
// 获取自定义流程配置(从 app/config/custom_process_config.php 加载)
$customProcess = $config->customProcess;
6.2 配置文件位置
自定义流程配置文件位于:app/config/custom_process_config.php
该文件返回一个数组,包含多种预设的医院流程配置:
return [
'standard' => [...], // 标准完整流程
'no_morning_wash' => [...], // 无晨洗流程
'partial_morning_wash' => [...], // 部分镜子晨洗(义乌模式)
'no_dry' => [...], // 无干燥流程
'dry_only' => [...], // 仅干燥流程
'machine_wash' => [...], // 机洗流程
'simple' => [...], // 简化流程
'custom_voice' => [...], // 自定义语音流程
];
6.3 使用全局配置创建流程
use app\config\Config;
use app\flow\ProcessConfig;
use app\flow\FlowProcessor;
// 获取全局配置
$globalConfig = Config::getInstance();
// 从全局配置中获取特定医院配置
$hospitalConfig = $globalConfig->customProcess['no_morning_wash'] ?? null;
if ($hospitalConfig) {
// 创建流程配置
$processConfig = ProcessConfig::fromArray($hospitalConfig);
// 创建流程处理器
$processor = new FlowProcessor($processConfig);
// 处理刷卡请求...
}
6.4 配置优先级
配置加载优先级(从高到低):
- 代码中动态设置的配置(
$engine->setStepVoice()) - 从配置文件加载的配置(
ProcessConfig::fromFile()) - 全局配置类中的配置(
Config::getInstance()->customProcess) - 默认配置(
ProcessConfig::createStandard())
七、多医院配置示例
class HospitalFlowManager
{
protected array $processors = [];
public function __construct()
{
// 医院A:标准流程
$this->processors['hospital_a'] = new FlowProcessor(
ProcessConfig::createStandard()
);
// 医院B:无晨洗
$this->processors['hospital_b'] = new FlowProcessor(
ProcessConfig::createNoMorningWash()
);
// 医院C:义乌模式
$configC = new ProcessConfig([
'morning_wash' => [
'mode' => 'storage_time',
'storage_threshold' => 4,
],
]);
$this->processors['hospital_c'] = new FlowProcessor($configC);
// 医院D:机洗流程
$this->processors['hospital_d'] = new FlowProcessor(
ProcessConfig::createMachineWash()
);
}
public function process(string $hospitalId, PacketContext $packetContext): ProcessContext
{
$processor = $this->processors[$hospitalId] ?? $this->processors['hospital_a'];
return $processor->process($packetContext);
}
}
八、处理结果
8.1 成功结果
$result = $processor->process($packetContext);
if ($result->isSuccess()) {
// 基础信息
$result->endoscopeId; // 内镜ID
$result->endoscopeName; // 内镜名称
$result->currentStep; // 当前步骤
$result->processType; // 流程类型
$result->batchNo; // 批次号
// 语音播报
$voice = $result->getFullVoice(); // 完整语音(含内镜名称)
$voice = $result->voiceMessage; // 仅流程语音
// 数据库标记
$result->needDbInsert; // 是否需要插入数据库
$result->dbOperation; // insert / update
// WebSocket标记
$result->needWebSocketNotify; // 是否需要发送通知
}
8.2 失败结果
if (!$result->isSuccess()) {
$errorMessage = $result->errorMessage; // 错误信息
$voice = $result->voiceMessage; // 错误语音
// 常见错误:
// - "刷错,清洗剩余180秒"(时间未到)
// - "刷卡错误,请刷消毒"(步骤错误)
// - "内镜未绑定"(数据错误)
}
九、数据库表结构参考
9.1 流程配置表(ect_meta_process)
CREATE TABLE `ect_meta_process` (
`process_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`process_name` varchar(255) COMMENT '流程名称(清洗/消毒/干燥等)',
`process_duration` int COMMENT '流程时长(秒)',
`process_type` varchar(20) COMMENT '洗消类型(手工洗/机洗等)',
`optional` int COMMENT '0=选配 1=必配',
`process_order` int COMMENT '顺序',
`status` int COMMENT '1=启用 0=禁用',
PRIMARY KEY (`process_id`)
);
9.2 操作记录表(ect_actions)
CREATE TABLE `ect_actions` (
`action_id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`batch_no` varchar(50) COMMENT '批次号(同一次清洗流程相同)',
`action_type` int COMMENT '操作类型',
`action_type_name` varchar(50) COMMENT '操作类型名称',
`process_name` varchar(50) COMMENT '流程名称(清洗/消毒等)',
`reader_id` bigint COMMENT '读卡器ID',
`reader_no` varchar(50) COMMENT '读卡器编号',
`endoscope_id` bigint COMMENT '内镜ID',
`endoscope_rfid` varchar(50) COMMENT '内镜RFID',
`endoscope_name` varchar(100) COMMENT '内镜名称',
`op_starttime` datetime COMMENT '操作开始时间',
`op_endtime` datetime COMMENT '操作结束时间',
`created_at` datetime,
PRIMARY KEY (`action_id`)
);
十、常见问题
Q1: 如何跳过某个步骤?
$engine->disableNode('干燥');
Q2: 如何修改步骤时间?
$config = new ProcessConfig([
'time_validation' => [
'durations' => ['消毒' => 600],
],
]);
Q3: 批次号如何保证分布式一致?
系统会从数据库查询该内镜未完成的流程批次号,如果存在则使用已有批次号,不存在则生成新的。
Q4: 如何添加自定义语音?
$engine->setStepVoice('清洗', '自定义语音内容');
Q5: 如何支持新的流程类型?
- 创建新的节点类继承
AbstractProcessNode - 在配置中添加步骤
- 实现
canHandle()和doHandle()方法