更新
This commit is contained in:
@@ -14,6 +14,7 @@ use app\common\service\prescriptionai\PrescriptionAiPolicy as Policy;
|
||||
use app\common\service\prescriptionai\PrescriptionAiProgress as Progress;
|
||||
use app\common\service\prescriptionai\PrescriptionAiStatistics;
|
||||
use app\common\service\prescriptionai\PrescriptionAiStore as Store;
|
||||
use app\common\service\prescriptionai\PrescriptionAiVisibility as Visibility;
|
||||
use DomainException;
|
||||
use think\facade\Db;
|
||||
|
||||
@@ -22,15 +23,16 @@ final class PrescriptionAiLogic
|
||||
public static function statuses(array $ids, int $actor, array $info): array
|
||||
{
|
||||
self::requirePermission('statuses', $actor, $info);
|
||||
$agreementVisible = Visibility::agreementVisible($actor);
|
||||
if (!Store::enabled()) {
|
||||
return ['enabled' => false, 'items' => []];
|
||||
return ['enabled' => false, 'agreement_visible' => $agreementVisible, 'items' => []];
|
||||
}
|
||||
$ids = array_values(array_unique(array_map('intval', $ids)));
|
||||
if (count($ids) > 100 || array_filter($ids, static fn ($id): bool => $id <= 0)) {
|
||||
throw new DomainException('最多查询100个有效处方');
|
||||
}
|
||||
if ($ids === []) {
|
||||
return ['enabled' => true, 'items' => []];
|
||||
return ['enabled' => true, 'agreement_visible' => $agreementVisible, 'items' => []];
|
||||
}
|
||||
$subjects = Db::name('prescription_ai_subject')->whereIn('prescription_id', $ids)->column('latest_batch_id', 'prescription_id');
|
||||
$batches = $subjects ? Db::name('prescription_ai_batch')->whereIn('id', array_values($subjects))->select()->toArray() : [];
|
||||
@@ -50,18 +52,20 @@ final class PrescriptionAiLogic
|
||||
// Do not reveal that a report with a broader source scope exists.
|
||||
continue;
|
||||
}
|
||||
$items[] = $batch ? self::formatBatch($batch, $modelMap[(int) $batch['id']] ?? [], $rx) : [
|
||||
$item = $batch ? self::formatBatch($batch, $modelMap[(int) $batch['id']] ?? [], $rx) : [
|
||||
'prescription_id' => $id, 'batch_id' => null,
|
||||
'status' => (int) ($rx['is_system_auto'] ?? 0) === 1 ? 'blank' : 'not_generated',
|
||||
'coverage_status' => 'pending', 'validity' => 'current', 'comparison_type' => 'unavailable', 'models' => [],
|
||||
];
|
||||
$items[] = Visibility::projectBatch($item, $agreementVisible);
|
||||
}
|
||||
return ['enabled' => true, 'items' => $items];
|
||||
return ['enabled' => true, 'agreement_visible' => $agreementVisible, 'items' => $items];
|
||||
}
|
||||
|
||||
public static function reports(array $params, int $actor, array $info): array
|
||||
{
|
||||
self::requirePermission('reports', $actor, $info);
|
||||
$agreementVisible = Visibility::agreementVisible($actor);
|
||||
$rxId = (int) ($params['prescription_id'] ?? 0);
|
||||
$diagnosisId = (int) ($params['diagnosis_id'] ?? 0);
|
||||
if (($rxId > 0) === ($diagnosisId > 0)) {
|
||||
@@ -100,22 +104,24 @@ final class PrescriptionAiLogic
|
||||
} while (count($chunk) === 200);
|
||||
$rows = array_slice($visible, ($page - 1) * $size, $size);
|
||||
$modelMap = self::models(array_column($rows, 'id'), false);
|
||||
return ['lists' => array_map(static fn ($b): array => self::formatBatch($b, $modelMap[(int) $b['id']] ?? []), $rows),
|
||||
return ['agreement_visible' => $agreementVisible,
|
||||
'lists' => array_map(static fn ($b): array => Visibility::projectBatch(self::formatBatch($b, $modelMap[(int) $b['id']] ?? []), $agreementVisible), $rows),
|
||||
'count' => count($visible), 'page_no' => $page, 'page_size' => $size];
|
||||
}
|
||||
|
||||
public static function detail(int $batchId, int $actor, array $info): array
|
||||
{
|
||||
self::requirePermission('detail', $actor, $info);
|
||||
$agreementVisible = Visibility::agreementVisible($actor);
|
||||
$batch = self::loadBatch($batchId, $actor, $info);
|
||||
$models = self::models([$batchId], true);
|
||||
$models = self::models([$batchId], true, $agreementVisible);
|
||||
$detail = self::formatBatch($batch, $models[$batchId] ?? [], Access::prescription((int) $batch['prescription_id'], $actor, $info));
|
||||
// loadBatch has checked both current prescription and historical source permissions.
|
||||
// This cipher is saved at enqueue time, so it is available before models start and
|
||||
// remains the correct original when the user selects an older report revision.
|
||||
$detail['doctor_snapshot'] = empty($batch['prescription_cipher']) ? null
|
||||
: DoctorSnapshot::project((new Cipher())->decrypt($batch['prescription_cipher'], 'prescription'));
|
||||
return $detail;
|
||||
return Visibility::projectBatch($detail, $agreementVisible);
|
||||
}
|
||||
|
||||
public static function regenerate(int $rxId, string $reason, int $actor, array $info): array
|
||||
@@ -205,6 +211,9 @@ final class PrescriptionAiLogic
|
||||
|
||||
public static function statistics(array $params, int $actor, array $info): array
|
||||
{
|
||||
if (!Visibility::agreementVisible($actor)) {
|
||||
throw new DomainException('无权查看处方AI一致度统计');
|
||||
}
|
||||
self::requirePermission('statistics', $actor, $info);
|
||||
self::requirePermission('detail', $actor, $info);
|
||||
$from = self::date((string) ($params['date_from'] ?? date('Y-m-d', strtotime('-30 days'))));
|
||||
@@ -271,7 +280,7 @@ final class PrescriptionAiLogic
|
||||
'metric_label' => '药味与剂量一致度(不代表临床准确率)'];
|
||||
}
|
||||
|
||||
private static function models(array $batchIds, bool $full): array
|
||||
private static function models(array $batchIds, bool $full, bool $agreementVisible = true): array
|
||||
{
|
||||
if ($batchIds === []) {
|
||||
return [];
|
||||
@@ -301,7 +310,7 @@ final class PrescriptionAiLogic
|
||||
foreach ($results as $result) {
|
||||
$body = $full ? (new Cipher())->decrypt($result['body_cipher'], 'result:' . $result['batch_id'] . ':' . $result['model_key']) : [];
|
||||
if ($full) {
|
||||
$body = self::localizeSourceMetadata($body);
|
||||
$body = Visibility::reportBody(self::localizeSourceMetadata($body), $agreementVisible);
|
||||
}
|
||||
unset($result['body_cipher']);
|
||||
$result['score'] = $result['score'] === null ? null : (float) $result['score'];
|
||||
|
||||
Reference in New Issue
Block a user