更新
This commit is contained in:
@@ -1058,7 +1058,8 @@ class DiagnosisController extends BaseAdminController
|
||||
+ ($control !== null ? $control->publicState() : []));
|
||||
}
|
||||
$emit('error', ['code' => $cancelled ? 'AI_ASSISTANT_CANCELLED' : DiagnosisAiLogic::getAssistantErrorCode(),
|
||||
'message' => $cancelled ? '本次请求已取消' : DiagnosisAiLogic::getError()]);
|
||||
'message' => $cancelled ? '本次请求已取消' : DiagnosisAiLogic::getError()]
|
||||
+ ($cancelled ? [] : DiagnosisAiLogic::getAssistantErrorMeta()));
|
||||
}
|
||||
|
||||
/** @param array<string,mixed> $prepared */
|
||||
|
||||
@@ -14,6 +14,7 @@ use app\common\service\NihaixiaClinicalSkill;
|
||||
use app\common\service\TcmAncientBooksReference;
|
||||
use app\adminapi\service\AssistantSseTiming;
|
||||
use app\adminapi\service\AiContextCompactionCache;
|
||||
use app\adminapi\service\AiRequiredSource;
|
||||
use app\adminapi\service\AssistantRequestControl;
|
||||
use think\facade\Db;
|
||||
use think\facade\Log;
|
||||
@@ -26,6 +27,9 @@ class DiagnosisAiLogic extends BaseLogic
|
||||
/** @var string Safe machine-readable code for the current assistant request. */
|
||||
private static $assistantErrorCode = 'AI_ASSISTANT_FAILED';
|
||||
|
||||
/** @var array<string,mixed> Safe final receipt, never upstream text/URLs. */
|
||||
private static $assistantErrorMeta = [];
|
||||
|
||||
private const PROMPT_VERSION = 'patient-context-case-explain-nihaixia-ancient-v4';
|
||||
|
||||
private const ASSISTANT_PROMPT_VERSION = 'patient-context-assistant-required-sources-v6';
|
||||
@@ -379,6 +383,7 @@ class DiagnosisAiLogic extends BaseLogic
|
||||
$status = 'error';
|
||||
try {
|
||||
self::$assistantErrorCode = 'AI_ASSISTANT_FAILED';
|
||||
self::$assistantErrorMeta = [];
|
||||
$task = strtolower(trim($task));
|
||||
if (!isset(self::ASSISTANT_TASKS[$task])) {
|
||||
self::setError('不支持的 AI 助手任务');
|
||||
@@ -517,6 +522,7 @@ class DiagnosisAiLogic extends BaseLogic
|
||||
?AssistantSseTiming $timing = null,
|
||||
array $options = []
|
||||
): ?array {
|
||||
self::$assistantErrorMeta = [];
|
||||
$diagnosisId = (int) ($prepared['diagnosis_id'] ?? 0);
|
||||
$profile = (string) ($prepared['profile'] ?? '');
|
||||
$adminId = (int) ($prepared['admin_id'] ?? 0);
|
||||
@@ -693,7 +699,9 @@ class DiagnosisAiLogic extends BaseLogic
|
||||
*/
|
||||
private static function formatAssistantResult(array $prepared, array $result): ?array
|
||||
{
|
||||
self::$assistantErrorMeta = [];
|
||||
if (empty($result['ok'])) {
|
||||
self::$assistantErrorMeta = self::safeAssistantErrorMeta($result);
|
||||
// 附带上游错误码,让医生反馈时管理员能直接定位是配置、体积还是上游拒绝。
|
||||
$message = (string) ($result['error'] ?? 'AI 助手暂时不可用,请稍后重试');
|
||||
$errorCode = trim((string) ($result['error_code'] ?? ''));
|
||||
@@ -753,6 +761,52 @@ class DiagnosisAiLogic extends BaseLogic
|
||||
return self::normaliseAssistantErrorCode(self::$assistantErrorCode);
|
||||
}
|
||||
|
||||
public static function getAssistantErrorMeta(): array
|
||||
{
|
||||
return self::$assistantErrorMeta;
|
||||
}
|
||||
|
||||
private static function safeAssistantErrorMeta(array $result): array
|
||||
{
|
||||
$meta = [];
|
||||
$sections = $result['required_sections'] ?? $result['source_summary']['required_sections'] ?? null;
|
||||
if (is_array($sections)) {
|
||||
$meta['required_sections'] = [];
|
||||
foreach ($sections as $section) {
|
||||
$key = is_array($section) ? ($section['key'] ?? null) : null;
|
||||
if (!is_string($key) || !isset(AiRequiredSource::LABELS[$key])) continue;
|
||||
$status = $section['status'] ?? '';
|
||||
if (!in_array($status, ['prepared', 'submitting', 'submitted', 'failed', 'omitted'], true)) continue;
|
||||
$meta['required_sections'][] = ['key' => $key, 'label' => AiRequiredSource::LABELS[$key],
|
||||
'count' => max(0, (int) ($section['count'] ?? 0)),
|
||||
'availability' => ($section['availability'] ?? '') === 'empty' ? 'empty' : 'present', 'status' => $status];
|
||||
}
|
||||
$meta['source_summary'] = ['required_sections' => $meta['required_sections']];
|
||||
}
|
||||
if (is_array($result['items'] ?? null)) {
|
||||
$meta['items'] = [];
|
||||
$labels = ['image' => '图片附件', 'document' => '文档附件', 'audio' => '音频附件', 'custom' => '附件'];
|
||||
$counts = [];
|
||||
foreach ($result['items'] as $item) {
|
||||
if (!is_array($item)) continue;
|
||||
$kind = $item['kind'] ?? '';
|
||||
$status = $item['status'] ?? '';
|
||||
if (!is_string($kind) || !isset($labels[$kind])
|
||||
|| !in_array($status, ['prepared', 'uploading', 'uploaded', 'submitting', 'submitted', 'failed', 'omitted'], true)) continue;
|
||||
$counts[$kind] = ($counts[$kind] ?? 0) + 1;
|
||||
$meta['items'][] = ['kind' => $kind, 'label' => $labels[$kind] . $counts[$kind], 'status' => $status];
|
||||
}
|
||||
}
|
||||
if (is_int($result['attachment_count'] ?? null)) $meta['attachment_count'] = max(0, $result['attachment_count']);
|
||||
if (in_array($result['attachment_transfer'] ?? '', ['remote_url_references', 'uploaded_files'], true)) {
|
||||
$meta['attachment_transfer'] = $result['attachment_transfer'];
|
||||
}
|
||||
if (($result['transfer_manifest_final'] ?? false) === true) $meta['transfer_manifest_final'] = true;
|
||||
if (is_int($result['upstream_http_status'] ?? null) && $result['upstream_http_status'] >= 100
|
||||
&& $result['upstream_http_status'] <= 599) $meta['upstream_http_status'] = $result['upstream_http_status'];
|
||||
return $meta;
|
||||
}
|
||||
|
||||
private static function normaliseAssistantErrorCode(string $code): string
|
||||
{
|
||||
$code = strtoupper(trim($code));
|
||||
|
||||
Reference in New Issue
Block a user