更新
This commit is contained in:
@@ -3963,9 +3963,9 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 药方名称反查:处方库(开方医师 creator_id + 公开模板),按 formula_type + 药材集合匹配,
|
// 药方名称反查:处方库(开方医师 → 公开 → 全库同药材集合兜底),按 formula_type + 药材集合匹配。
|
||||||
// 复刻前端 resolveSlipAuxLibraryName 口径(主方/辅方均如此;处方记录 prescription_name 仅做兜底)。
|
// 辅方模板额外全量加载,避免「系统代开 / 非模板所属医师」因 creator 范围过窄丢辅方名。
|
||||||
[$libByDoctor, $libPublic] = self::buildPrescriptionLibraryNameIndexForExport($rxById);
|
[$libByDoctor, $libPublic, $libAny] = self::buildPrescriptionLibraryNameIndexForExport($rxById);
|
||||||
|
|
||||||
if ($needGuahaoChannel) {
|
if ($needGuahaoChannel) {
|
||||||
$yejiChannelHighlightByDiag = [];
|
$yejiChannelHighlightByDiag = [];
|
||||||
@@ -4174,11 +4174,12 @@ class PrescriptionOrderLogic
|
|||||||
|
|
||||||
$item['export_medication_form'] = self::formatMedicationFormForExport(\is_array($rx) ? $rx : []);
|
$item['export_medication_form'] = self::formatMedicationFormForExport(\is_array($rx) ? $rx : []);
|
||||||
|
|
||||||
// 药方名称:主方/辅方均反查处方库取名称(与处方笺一致),带标签;甘草/无匹配留空
|
// 药方名称:主方/辅方均反查处方库取名称(与处方笺一致),带标签;有辅方药材时即使未匹配到库名也保留「辅方」标记
|
||||||
[$mainRxName, $auxRxName] = self::resolvePrescriptionNamesForExport(
|
[$mainRxName, $auxRxName] = self::resolvePrescriptionNamesForExport(
|
||||||
\is_array($rx) ? $rx : [],
|
\is_array($rx) ? $rx : [],
|
||||||
$libByDoctor,
|
$libByDoctor,
|
||||||
$libPublic
|
$libPublic,
|
||||||
|
$libAny
|
||||||
);
|
);
|
||||||
$rxNameParts = [];
|
$rxNameParts = [];
|
||||||
if ($mainRxName !== '') {
|
if ($mainRxName !== '') {
|
||||||
@@ -4298,19 +4299,24 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出药方名称反查:批量加载相关开方医师处方库(creator_id 命中 + 公开模板),
|
* 导出药方名称反查:批量加载相关开方医师处方库(creator_id 命中 + 公开模板 + 全量辅方模板),
|
||||||
* 建立 [creator_id][formula_type][herbKey] => name 与 公开 [formula_type][herbKey] => name 两级索引。
|
* 建立三级索引:医师私有 / 公开 / 任意已加载(跨医师同药材集合兜底)。
|
||||||
*
|
*
|
||||||
* @param array<int, array> $rxById 处方 id => 处方行(需含 herbs / creator_id)
|
* @param array<int, array> $rxById 处方 id => 处方行(需含 herbs / creator_id)
|
||||||
*
|
*
|
||||||
* @return array{0: array<int, array<string, array<string, string>>>, 1: array<string, array<string, string>>}
|
* @return array{
|
||||||
|
* 0: array<int, array<string, array<string, string>>>,
|
||||||
|
* 1: array<string, array<string, string>>,
|
||||||
|
* 2: array<string, array<string, string>>
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
private static function buildPrescriptionLibraryNameIndexForExport(array $rxById): array
|
private static function buildPrescriptionLibraryNameIndexForExport(array $rxById): array
|
||||||
{
|
{
|
||||||
$libByDoctor = [];
|
$libByDoctor = [];
|
||||||
$libPublic = [];
|
$libPublic = [];
|
||||||
|
$libAny = [];
|
||||||
if ($rxById === []) {
|
if ($rxById === []) {
|
||||||
return [$libByDoctor, $libPublic];
|
return [$libByDoctor, $libPublic, $libAny];
|
||||||
}
|
}
|
||||||
|
|
||||||
$doctorIds = [];
|
$doctorIds = [];
|
||||||
@@ -4323,12 +4329,15 @@ class PrescriptionOrderLogic
|
|||||||
$doctorIdList = array_keys($doctorIds);
|
$doctorIdList = array_keys($doctorIds);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 开方医师私有 + 公开模板 + 全量辅方模板(辅方常被非模板所有者的「系统代开」处方复用)
|
||||||
$libRows = PrescriptionLibrary::whereNull('delete_time')
|
$libRows = PrescriptionLibrary::whereNull('delete_time')
|
||||||
->where(function ($q) use ($doctorIdList) {
|
->where(function ($q) use ($doctorIdList) {
|
||||||
if ($doctorIdList !== []) {
|
if ($doctorIdList !== []) {
|
||||||
$q->whereIn('creator_id', $doctorIdList)->whereOr('is_public', 1);
|
$q->whereIn('creator_id', $doctorIdList)
|
||||||
|
->whereOr('is_public', 1)
|
||||||
|
->whereOr('formula_type', '辅方');
|
||||||
} else {
|
} else {
|
||||||
$q->where('is_public', 1);
|
$q->where('is_public', 1)->whereOr('formula_type', '辅方');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->field(['prescription_name', 'formula_type', 'herbs', 'creator_id', 'is_public'])
|
->field(['prescription_name', 'formula_type', 'herbs', 'creator_id', 'is_public'])
|
||||||
@@ -4337,7 +4346,7 @@ class PrescriptionOrderLogic
|
|||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::warning('buildPrescriptionLibraryNameIndexForExport failed: ' . $e->getMessage());
|
Log::warning('buildPrescriptionLibraryNameIndexForExport failed: ' . $e->getMessage());
|
||||||
|
|
||||||
return [$libByDoctor, $libPublic];
|
return [$libByDoctor, $libPublic, $libAny];
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($libRows as $lib) {
|
foreach ($libRows as $lib) {
|
||||||
@@ -4359,6 +4368,9 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
$ft = ((string) ($lib['formula_type'] ?? '')) === '辅方' ? '辅方' : '主方';
|
$ft = ((string) ($lib['formula_type'] ?? '')) === '辅方' ? '辅方' : '主方';
|
||||||
|
|
||||||
|
// 跨医师兜底:同药材集合优先保留先写入的名称(稳定、可预期)
|
||||||
|
$libAny[$ft][$key] ??= $name;
|
||||||
|
|
||||||
if ((int) ($lib['is_public'] ?? 0) === 1) {
|
if ((int) ($lib['is_public'] ?? 0) === 1) {
|
||||||
$libPublic[$ft][$key] ??= $name;
|
$libPublic[$ft][$key] ??= $name;
|
||||||
}
|
}
|
||||||
@@ -4368,23 +4380,28 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [$libByDoctor, $libPublic];
|
return [$libByDoctor, $libPublic, $libAny];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反查单张处方的主方 / 辅方名称(与处方笺展示一致):
|
* 反查单张处方的主方 / 辅方名称(与处方笺展示一致):
|
||||||
* - 主方:主方药材集合匹配开方医师/公开处方库(formula_type=主方);兜底取处方 prescription_name。
|
* - 主方:主方药材集合匹配 开方医师 → 公开 → 任意已加载;兜底取处方 prescription_name。
|
||||||
* - 辅方:仅在实际存在辅方药材时,优先 aux_usage.prescription_name / library_name,
|
* - 辅方:仅在实际存在辅方药材时,优先 aux_usage.prescription_name / library_name,
|
||||||
* 否则按辅方药材集合匹配(formula_type=辅方)。
|
* 否则按辅方药材集合匹配;仍无匹配时回落为「辅方」(保证导出名含辅方标记)。
|
||||||
*
|
*
|
||||||
* @param array $rx 处方行(含 herbs / creator_id / prescription_name / aux_usage)
|
* @param array $rx 处方行(含 herbs / creator_id / prescription_name / aux_usage)
|
||||||
* @param array<int, array<string, array<string, string>>> $libByDoctor
|
* @param array<int, array<string, array<string, string>>> $libByDoctor
|
||||||
* @param array<string, array<string, string>> $libPublic
|
* @param array<string, array<string, string>> $libPublic
|
||||||
|
* @param array<string, array<string, string>> $libAny
|
||||||
*
|
*
|
||||||
* @return array{0: string, 1: string} [主方名称, 辅方名称]
|
* @return array{0: string, 1: string} [主方名称, 辅方名称]
|
||||||
*/
|
*/
|
||||||
private static function resolvePrescriptionNamesForExport(array $rx, array $libByDoctor, array $libPublic): array
|
private static function resolvePrescriptionNamesForExport(
|
||||||
{
|
array $rx,
|
||||||
|
array $libByDoctor,
|
||||||
|
array $libPublic,
|
||||||
|
array $libAny = []
|
||||||
|
): array {
|
||||||
if ($rx === []) {
|
if ($rx === []) {
|
||||||
return ['', ''];
|
return ['', ''];
|
||||||
}
|
}
|
||||||
@@ -4393,7 +4410,7 @@ class PrescriptionOrderLogic
|
|||||||
|
|
||||||
[$mainHerbs, $auxHerbs] = self::splitPrescriptionHerbsFromRx($rx);
|
[$mainHerbs, $auxHerbs] = self::splitPrescriptionHerbsFromRx($rx);
|
||||||
|
|
||||||
$lookup = static function (string $ft, array $hs) use ($doctorId, $libByDoctor, $libPublic): string {
|
$lookup = static function (string $ft, array $hs) use ($doctorId, $libByDoctor, $libPublic, $libAny): string {
|
||||||
if ($hs === []) {
|
if ($hs === []) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
@@ -4404,8 +4421,11 @@ class PrescriptionOrderLogic
|
|||||||
if ($doctorId > 0 && isset($libByDoctor[$doctorId][$ft][$key])) {
|
if ($doctorId > 0 && isset($libByDoctor[$doctorId][$ft][$key])) {
|
||||||
return $libByDoctor[$doctorId][$ft][$key];
|
return $libByDoctor[$doctorId][$ft][$key];
|
||||||
}
|
}
|
||||||
|
if (isset($libPublic[$ft][$key])) {
|
||||||
|
return $libPublic[$ft][$key];
|
||||||
|
}
|
||||||
|
|
||||||
return (string) ($libPublic[$ft][$key] ?? '');
|
return (string) ($libAny[$ft][$key] ?? '');
|
||||||
};
|
};
|
||||||
|
|
||||||
// 主方
|
// 主方
|
||||||
@@ -4432,6 +4452,10 @@ class PrescriptionOrderLogic
|
|||||||
if ($auxName === '') {
|
if ($auxName === '') {
|
||||||
$auxName = $lookup('辅方', $auxHerbs);
|
$auxName = $lookup('辅方', $auxHerbs);
|
||||||
}
|
}
|
||||||
|
// 有辅方药材但未匹配到库名/持久化名时,仍输出标记,避免导出名静默丢掉辅方
|
||||||
|
if ($auxName === '') {
|
||||||
|
$auxName = '辅方';
|
||||||
|
}
|
||||||
|
|
||||||
return [$mainName, $auxName];
|
return [$mainName, $auxName];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,88 +1,110 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
require dirname(__DIR__, 2) . '/vendor/autoload.php';
|
require dirname(__DIR__, 2) . '/vendor/autoload.php';
|
||||||
|
|
||||||
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
|
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
|
||||||
|
|
||||||
$passed = 0;
|
$passed = 0;
|
||||||
$assertSame = static function (mixed $expected, mixed $actual, string $message) use (&$passed): void {
|
$assertSame = static function (mixed $expected, mixed $actual, string $message) use (&$passed): void {
|
||||||
if ($expected !== $actual) {
|
if ($expected !== $actual) {
|
||||||
throw new RuntimeException(sprintf(
|
throw new RuntimeException(sprintf(
|
||||||
"%s\nExpected: %s\nActual: %s",
|
"%s\nExpected: %s\nActual: %s",
|
||||||
$message,
|
$message,
|
||||||
var_export($expected, true),
|
var_export($expected, true),
|
||||||
var_export($actual, true)
|
var_export($actual, true)
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
++$passed;
|
++$passed;
|
||||||
};
|
};
|
||||||
|
|
||||||
$resolveNames = new ReflectionMethod(PrescriptionOrderLogic::class, 'resolvePrescriptionNamesForExport');
|
$resolveNames = new ReflectionMethod(PrescriptionOrderLogic::class, 'resolvePrescriptionNamesForExport');
|
||||||
|
|
||||||
$mainHerb = ['name' => '黄芪', 'dosage' => 10, 'formula_type' => '主方'];
|
$mainHerb = ['name' => '黄芪', 'dosage' => 10, 'formula_type' => '主方'];
|
||||||
$auxHerb = ['name' => '龙骨', 'dosage' => 15, 'formula_type' => '辅方'];
|
$auxHerb = ['name' => '龙骨', 'dosage' => 15, 'formula_type' => '辅方'];
|
||||||
|
|
||||||
$assertSame(
|
$assertSame(
|
||||||
['主方名', ''],
|
['主方名', ''],
|
||||||
$resolveNames->invoke(null, [
|
$resolveNames->invoke(null, [
|
||||||
'prescription_name' => '主方名',
|
'prescription_name' => '主方名',
|
||||||
'herbs' => [$mainHerb],
|
'herbs' => [$mainHerb],
|
||||||
'aux_usage' => ['prescription_name' => '已删除的辅方名'],
|
'aux_usage' => ['prescription_name' => '已删除的辅方名'],
|
||||||
], [], []),
|
], [], []),
|
||||||
'export must ignore a stale auxiliary prescription name when no auxiliary herbs exist'
|
'export must ignore a stale auxiliary prescription name when no auxiliary herbs exist'
|
||||||
);
|
);
|
||||||
|
|
||||||
$assertSame(
|
$assertSame(
|
||||||
['主方名', ''],
|
['主方名', ''],
|
||||||
$resolveNames->invoke(null, [
|
$resolveNames->invoke(null, [
|
||||||
'prescription_name' => '主方名',
|
'prescription_name' => '主方名',
|
||||||
'herbs' => json_encode([$mainHerb], JSON_UNESCAPED_UNICODE),
|
'herbs' => json_encode([$mainHerb], JSON_UNESCAPED_UNICODE),
|
||||||
'aux_usage' => json_encode(['library_name' => '已删除的处方库辅方名'], JSON_UNESCAPED_UNICODE),
|
'aux_usage' => json_encode(['library_name' => '已删除的处方库辅方名'], JSON_UNESCAPED_UNICODE),
|
||||||
], [], []),
|
], [], []),
|
||||||
'JSON-backed export data must ignore a stale auxiliary library name when no auxiliary herbs exist'
|
'JSON-backed export data must ignore a stale auxiliary library name when no auxiliary herbs exist'
|
||||||
);
|
);
|
||||||
|
|
||||||
$assertSame(
|
$assertSame(
|
||||||
['主方名', ''],
|
['主方名', ''],
|
||||||
$resolveNames->invoke(null, [
|
$resolveNames->invoke(null, [
|
||||||
'prescription_name' => '主方名',
|
'prescription_name' => '主方名',
|
||||||
'creator_id' => 7,
|
'creator_id' => 7,
|
||||||
'herbs' => [$mainHerb],
|
'herbs' => [$mainHerb],
|
||||||
'aux_usage' => ['prescription_name' => '残留名称', 'usage_days' => 7],
|
'aux_usage' => ['prescription_name' => '残留名称', 'usage_days' => 7],
|
||||||
], [
|
], [
|
||||||
7 => [
|
7 => [
|
||||||
'辅方' => ['龙骨:15' => '不应命中的处方库辅方名'],
|
'辅方' => ['龙骨:15' => '不应命中的处方库辅方名'],
|
||||||
],
|
],
|
||||||
], [
|
], [
|
||||||
'辅方' => ['龙骨:15' => '不应命中的公开辅方名'],
|
'辅方' => ['龙骨:15' => '不应命中的公开辅方名'],
|
||||||
]),
|
]),
|
||||||
'stale auxiliary usage and library indexes must not imply that an auxiliary formula exists'
|
'stale auxiliary usage and library indexes must not imply that an auxiliary formula exists'
|
||||||
);
|
);
|
||||||
|
|
||||||
$assertSame(
|
$assertSame(
|
||||||
['主方名', '持久化辅方名'],
|
['主方名', '持久化辅方名'],
|
||||||
$resolveNames->invoke(null, [
|
$resolveNames->invoke(null, [
|
||||||
'prescription_name' => '主方名',
|
'prescription_name' => '主方名',
|
||||||
'herbs' => [$mainHerb, $auxHerb],
|
'herbs' => [$mainHerb, $auxHerb],
|
||||||
'aux_usage' => json_encode(['prescription_name' => '持久化辅方名'], JSON_UNESCAPED_UNICODE),
|
'aux_usage' => json_encode(['prescription_name' => '持久化辅方名'], JSON_UNESCAPED_UNICODE),
|
||||||
], [], []),
|
], [], []),
|
||||||
'export must keep the persisted auxiliary prescription name when auxiliary herbs exist'
|
'export must keep the persisted auxiliary prescription name when auxiliary herbs exist'
|
||||||
);
|
);
|
||||||
|
|
||||||
$assertSame(
|
$assertSame(
|
||||||
['主方名', '处方库辅方名'],
|
['主方名', '处方库辅方名'],
|
||||||
$resolveNames->invoke(null, [
|
$resolveNames->invoke(null, [
|
||||||
'prescription_name' => '主方名',
|
'prescription_name' => '主方名',
|
||||||
'creator_id' => 7,
|
'creator_id' => 7,
|
||||||
'herbs' => [$mainHerb, $auxHerb],
|
'herbs' => [$mainHerb, $auxHerb],
|
||||||
], [
|
], [
|
||||||
7 => [
|
7 => [
|
||||||
'辅方' => ['龙骨:15' => '处方库辅方名'],
|
'辅方' => ['龙骨:15' => '处方库辅方名'],
|
||||||
],
|
],
|
||||||
], []),
|
], []),
|
||||||
'export must still resolve an auxiliary prescription name from the library when auxiliary herbs exist'
|
'export must still resolve an auxiliary prescription name from the library when auxiliary herbs exist'
|
||||||
);
|
);
|
||||||
|
|
||||||
fwrite(STDOUT, sprintf("Prescription order export name regression tests passed: %d\n", $passed));
|
$assertSame(
|
||||||
|
['系统代开', '失眠(辅方)'],
|
||||||
|
$resolveNames->invoke(null, [
|
||||||
|
'prescription_name' => '系统代开',
|
||||||
|
'creator_id' => 99,
|
||||||
|
'herbs' => [$mainHerb, $auxHerb],
|
||||||
|
], [], [], [
|
||||||
|
'辅方' => ['龙骨:15' => '失眠(辅方)'],
|
||||||
|
]),
|
||||||
|
'export must resolve auxiliary name via cross-doctor libAny when creator has no private/public hit'
|
||||||
|
);
|
||||||
|
|
||||||
|
$assertSame(
|
||||||
|
['系统代开', '辅方'],
|
||||||
|
$resolveNames->invoke(null, [
|
||||||
|
'prescription_name' => '系统代开',
|
||||||
|
'creator_id' => 99,
|
||||||
|
'herbs' => [$mainHerb, $auxHerb],
|
||||||
|
], [], [], []),
|
||||||
|
'export must still mark 辅方 when auxiliary herbs exist but no library/persisted name matches'
|
||||||
|
);
|
||||||
|
|
||||||
|
fwrite(STDOUT, sprintf("Prescription order export name regression tests passed: %d\n", $passed));
|
||||||
|
|||||||
Reference in New Issue
Block a user