feat: 联调对话功能
This commit is contained in:
+129
-27
@@ -1,4 +1,11 @@
|
||||
import { createTrainingSession, type PatientConfigPayload, type TrainingMode } from './session'
|
||||
import {
|
||||
FASTAPI_BASE_URL,
|
||||
authHeaders,
|
||||
createTrainingSession,
|
||||
readError,
|
||||
type PatientConfigPayload,
|
||||
type TrainingMode
|
||||
} from './session'
|
||||
|
||||
export type ScenarioRecommendation = {
|
||||
id: string
|
||||
@@ -11,6 +18,7 @@ export type ScenarioRecommendation = {
|
||||
export type ScenarioOption = {
|
||||
value: string
|
||||
label: string
|
||||
description?: string
|
||||
}
|
||||
|
||||
export type ScenarioForm = {
|
||||
@@ -27,6 +35,12 @@ export type ScenarioOptions = {
|
||||
personalities: ScenarioOption[]
|
||||
}
|
||||
|
||||
export type TrainingConfigRecommended = {
|
||||
recommended: ScenarioForm
|
||||
recommendedLabels: Record<ScenarioFormKey, string>
|
||||
options: ScenarioOptions
|
||||
}
|
||||
|
||||
export type ScenarioConfigPayload = ScenarioForm & {
|
||||
caseId: string
|
||||
caseNo: string
|
||||
@@ -34,6 +48,61 @@ export type ScenarioConfigPayload = ScenarioForm & {
|
||||
recommendationId?: string
|
||||
}
|
||||
|
||||
type TrainingConfigApiKey = 'visit_environment' | 'age_group' | 'education_level' | 'personality'
|
||||
|
||||
const DEFAULT_CASE_ID = 1
|
||||
|
||||
type ApiEnvelope<T> = {
|
||||
code: string
|
||||
message: string
|
||||
data: T
|
||||
}
|
||||
|
||||
type ScenarioFormKey = keyof ScenarioForm
|
||||
|
||||
type TrainingConfigRecommendedResponse = {
|
||||
case_id: number
|
||||
recommended: {
|
||||
visit_environment: string
|
||||
age_group: string
|
||||
education_level: string
|
||||
personality: string
|
||||
}
|
||||
recommended_labels: {
|
||||
visit_environment: string
|
||||
age_group: string
|
||||
education_level: string
|
||||
personality: string
|
||||
}
|
||||
options?: Partial<Record<TrainingConfigApiKey, ScenarioOption[] | Record<string, string>>>
|
||||
}
|
||||
|
||||
export const DEFAULT_SCENARIO_OPTIONS: ScenarioOptions = {
|
||||
environments: [
|
||||
{ value: 'outpatient', label: '门诊' },
|
||||
{ value: 'emergency', label: '急诊' },
|
||||
{ value: 'ward', label: '病房' }
|
||||
],
|
||||
ageGroups: [
|
||||
{ value: 'child', label: '儿童' },
|
||||
{ value: 'youth', label: '青年' },
|
||||
{ value: 'middle_aged', label: '中年' },
|
||||
{ value: 'elderly', label: '老年' }
|
||||
],
|
||||
educations: [
|
||||
{ value: 'primary_or_below', label: '小学及以下' },
|
||||
{ value: 'secondary', label: '中等教育' },
|
||||
{ value: 'higher', label: '高等教育' }
|
||||
],
|
||||
personalities: [
|
||||
{ value: 'calm', label: '平和' },
|
||||
{ value: 'anxious', label: '焦虑' },
|
||||
{ value: 'impatient', label: '急躁' },
|
||||
{ value: 'cooperative', label: '配合' },
|
||||
{ value: 'suspicious', label: '多疑' }
|
||||
]
|
||||
}
|
||||
|
||||
export function fetchScenarioOptions() {
|
||||
return Promise.resolve({
|
||||
recommendations: [
|
||||
@@ -62,37 +131,70 @@ export function fetchScenarioOptions() {
|
||||
}
|
||||
}
|
||||
] as ScenarioRecommendation[],
|
||||
options: {
|
||||
environments: [
|
||||
{ value: 'outpatient', label: '门诊' },
|
||||
{ value: 'emergency', label: '急诊' },
|
||||
{ value: 'ward', label: '病房' }
|
||||
],
|
||||
ageGroups: [
|
||||
{ value: 'child', label: '儿童' },
|
||||
{ value: 'youth', label: '青年' },
|
||||
{ value: 'middle_aged', label: '中年' },
|
||||
{ value: 'elderly', label: '老年' }
|
||||
],
|
||||
educations: [
|
||||
{ value: 'primary_or_below', label: '小学及以下' },
|
||||
{ value: 'secondary', label: '中等教育' },
|
||||
{ value: 'higher', label: '高等教育' }
|
||||
],
|
||||
personalities: [
|
||||
{ value: 'calm', label: '平和' },
|
||||
{ value: 'anxious', label: '焦虑' },
|
||||
{ value: 'impatient', label: '急躁' },
|
||||
{ value: 'cooperative', label: '配合' },
|
||||
{ value: 'suspicious', label: '多疑' }
|
||||
]
|
||||
} as ScenarioOptions
|
||||
options: DEFAULT_SCENARIO_OPTIONS
|
||||
})
|
||||
}
|
||||
|
||||
function normalizeApiOptions(
|
||||
source: TrainingConfigRecommendedResponse['options'] | undefined,
|
||||
key: keyof TrainingConfigRecommendedResponse['recommended'],
|
||||
fallback: ScenarioOption[]
|
||||
) {
|
||||
const value = source?.[key]
|
||||
if (Array.isArray(value)) return value
|
||||
if (value && typeof value === 'object') {
|
||||
return Object.entries(value).map(([optionValue, label]) => ({
|
||||
value: optionValue,
|
||||
label: String(label)
|
||||
}))
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
function normalizeTrainingConfig(payload: TrainingConfigRecommendedResponse): TrainingConfigRecommended {
|
||||
return {
|
||||
recommended: {
|
||||
environment: payload.recommended.visit_environment,
|
||||
ageGroup: payload.recommended.age_group,
|
||||
education: payload.recommended.education_level,
|
||||
personality: payload.recommended.personality
|
||||
},
|
||||
recommendedLabels: {
|
||||
environment: payload.recommended_labels.visit_environment,
|
||||
ageGroup: payload.recommended_labels.age_group,
|
||||
education: payload.recommended_labels.education_level,
|
||||
personality: payload.recommended_labels.personality
|
||||
},
|
||||
options: {
|
||||
environments: normalizeApiOptions(payload.options, 'visit_environment', DEFAULT_SCENARIO_OPTIONS.environments),
|
||||
ageGroups: normalizeApiOptions(payload.options, 'age_group', DEFAULT_SCENARIO_OPTIONS.ageGroups),
|
||||
educations: normalizeApiOptions(payload.options, 'education_level', DEFAULT_SCENARIO_OPTIONS.educations),
|
||||
personalities: normalizeApiOptions(payload.options, 'personality', DEFAULT_SCENARIO_OPTIONS.personalities)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchTrainingConfigOptions(caseId: number) {
|
||||
const response = await fetch(`${FASTAPI_BASE_URL}/training-config/options?case_id=${encodeURIComponent(caseId)}`, {
|
||||
method: 'GET',
|
||||
headers: authHeaders()
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(await readError(response))
|
||||
}
|
||||
|
||||
const result = (await response.json()) as ApiEnvelope<TrainingConfigRecommendedResponse>
|
||||
if (result.code !== 'OK' || !result.data?.recommended) {
|
||||
throw new Error(result.message || '推荐配置加载失败')
|
||||
}
|
||||
|
||||
return normalizeTrainingConfig(result.data)
|
||||
}
|
||||
|
||||
export function createScenarioConfig(payload: ScenarioConfigPayload) {
|
||||
return createTrainingSession({
|
||||
case_id: 1,
|
||||
case_id: DEFAULT_CASE_ID,
|
||||
training_type: 'diagnosis_treatment',
|
||||
mode: payload.mode,
|
||||
score_type: 'percentage',
|
||||
|
||||
Reference in New Issue
Block a user