48 lines
2.7 KiB
PHP
48 lines
2.7 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace app\adminapi\service;
|
||
|
||
/** Consultation workflow boundary. Never edits source records or generated bytes. */
|
||
final class TcmConsultationPulsePolicy
|
||
{
|
||
public const VERSION = 'consultation-pulse-excluded-r36c';
|
||
|
||
public static function instruction(): string
|
||
{
|
||
return \app\common\service\TcmClinicalResponsePolicy::consultationInstruction();
|
||
}
|
||
|
||
/** Reject active pulse assessment/solicitation instead of hiding its text. */
|
||
public static function validate(array $ledger, string $report): array
|
||
{
|
||
if (!mb_check_encoding($report, 'UTF-8')) {
|
||
return ['valid' => false, 'issues' => [['code' => 'CONSULTATION_INVALID_UTF8', 'source_id' => 'report']]];
|
||
}
|
||
// Only an entire, dated, exact historical quotation can carry pulse
|
||
// wording. Mask it for this check alone; displayed/source bytes stay intact.
|
||
// A current row, an altered quote or an appended inference cannot borrow
|
||
// this historical role. Existing source/state validators still run.
|
||
$probe = preg_replace_callback('/^(?:历史|历史记录|既往记录)[::]\s*(日期未记录|(?:19|20)\d{2}-\d{2}-\d{2})\s*“([^”\r\n]+)”\s*((s[1-9][0-9]*))[。;;\s]*$/mu',
|
||
static function (array $match) use ($ledger): string {
|
||
$source = $ledger['sources'][$match[3]] ?? null;
|
||
if (!is_array($source) || ($source['scope'] ?? '') !== 'historical'
|
||
|| ($source['quote'] ?? null) !== $match[2]
|
||
|| (($source['date'] ?? '') === '' ? $match[1] !== '日期未记录' : $source['date'] !== $match[1])) return $match[0];
|
||
return str_repeat(' ', strlen($match[0]));
|
||
}, $report) ?? $report;
|
||
// Bind traditional examination wording/features. Cardiovascular nouns
|
||
// such as 冠状动脉、静脉、脉压、脉率 and pulse rate remain ordinary facts.
|
||
$feature = '无力|有力|浮|沉|迟|数|虚|实|滑|涩|弦|细|洪|弱|缓|紧|濡|微|促|结|代|正常|无异常';
|
||
$pulse = '/\bpulse\b(?![\s_-]*(?:rate|pressure)\b)|舌脉|脉(?:象|诊|[::])'
|
||
. '|(?:诊|把|切|搭|按|察|查|补采|采集|记录)脉(?!率|压|搏|络|管)'
|
||
. '|(?:缺|缺少|缺乏|补|未采集|未记录)脉(?!率|压|搏|络|管)'
|
||
. '|脉[::\s]*(?:(?:呈|为|见|可见|表现为|按之)[::\s]*)?(?:不|未|无)?(?:' . $feature . ')'
|
||
. '|(?:' . $feature . ')脉(?!络|管|压|率)/iu';
|
||
$invalid = preg_match($pulse, $probe) === 1;
|
||
return ['valid' => !$invalid, 'issues' => $invalid
|
||
? [['code' => 'PULSE_EXCLUDED_FROM_ASSESSMENT', 'source_id' => 'report']] : []];
|
||
}
|
||
}
|