> $herbs * @param callable(array):array> $loadByIds * @param callable(array):array> $loadByNames * @return array> */ 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 $row */ private static function isActive(array $row): bool { return (int) ($row['id'] ?? 0) > 0 && (int) ($row['status'] ?? 0) === 1 && ($row['delete_time'] ?? null) === null; } }