Files
tcpserver-flow/app/flow/docs/02-使用配置.md
T
2026-03-08 22:58:56 +08:00

12 KiB
Raw Blame History

内镜清洗流程管理系统 - 使用与配置

一、快速开始

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 配置优先级

配置加载优先级(从高到低):

  1. 代码中动态设置的配置($engine->setStepVoice()
  2. 从配置文件加载的配置(ProcessConfig::fromFile()
  3. 全局配置类中的配置(Config::getInstance()->customProcess
  4. 默认配置(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: 如何支持新的流程类型?

  1. 创建新的节点类继承 AbstractProcessNode
  2. 在配置中添加步骤
  3. 实现 canHandle()doHandle() 方法