Files
zyt/server/app/common/service/pharmacy/PharmacyHerbIdentityResolver.php
T
2026-07-22 14:50:34 +08:00

101 lines
3.4 KiB
PHP

<?php
declare(strict_types=1);
namespace app\common\service\pharmacy;
use DomainException;
final class PharmacyHerbIdentityResolver
{
/**
* @param array<int,array<string,mixed>> $herbs
* @param callable(array<int,int>):array<int,array<string,mixed>> $loadByIds
* @param callable(array<int,string>):array<int,array<string,mixed>> $loadByNames
* @return array<int,array<string,mixed>>
*/
public static function resolve(array $herbs, callable $loadByIds, callable $loadByNames): array
{
$ids = [];
$names = [];
foreach ($herbs as $herb) {
if (!is_array($herb)) {
continue;
}
$id = (int) ($herb['medicine_id'] ?? $herb['id'] ?? 0);
if ($id > 0) {
$ids[] = $id;
continue;
}
$name = trim((string) ($herb['name'] ?? $herb['title'] ?? ''));
if ($name !== '') {
$names[] = $name;
}
}
$byId = [];
foreach ($ids === [] ? [] : $loadByIds(array_values(array_unique($ids))) as $row) {
if (self::isActive($row)) {
$byId[(int) $row['id']] = $row;
}
}
$byName = [];
foreach ($names === [] ? [] : $loadByNames(array_values(array_unique($names))) as $row) {
if (!self::isActive($row)) {
continue;
}
$name = trim((string) ($row['name'] ?? ''));
if ($name !== '') {
$byName[$name][] = $row;
}
}
$resolved = [];
foreach ($herbs as $herb) {
if (!is_array($herb)) {
continue;
}
$name = trim((string) ($herb['name'] ?? $herb['title'] ?? ''));
$id = (int) ($herb['medicine_id'] ?? $herb['id'] ?? 0);
if ($id > 0) {
$row = $byId[$id] ?? null;
if (!is_array($row)) {
throw new DomainException('药材“' . ($name !== '' ? $name : (string) $id) . '”对应的本地药材不存在或已停用');
}
} else {
if ($name === '') {
throw new DomainException('药材名称不能为空');
}
$candidates = $byName[$name] ?? [];
if (count($candidates) === 0) {
throw new DomainException('药材“' . $name . '”未在本地药材库中找到');
}
if (count($candidates) !== 1) {
throw new DomainException('药材“' . $name . '”存在多个同名记录,请重新选择具体药材');
}
$row = $candidates[0];
$id = (int) $row['id'];
}
$herb['medicine_id'] = $id;
$herb['name'] = trim((string) ($row['name'] ?? $name));
unset($herb['id'], $herb['title'], $herb['local_medicine_id']);
$resolved[] = $herb;
}
if ($resolved === []) {
throw new DomainException('处方药材不能为空');
}
return $resolved;
}
/** @param array<string,mixed> $row */
private static function isActive(array $row): bool
{
return (int) ($row['id'] ?? 0) > 0
&& (int) ($row['status'] ?? 0) === 1
&& ($row['delete_time'] ?? null) === null;
}
}