|
|
@@ -7,6 +7,7 @@ export function useDialogueEngine() {
|
|
|
const sessionId = ref<string | null>(null)
|
|
|
const expiresAt = ref<string | null>(null)
|
|
|
const currentRound = ref(1)
|
|
|
+ const totalRounds = ref<number>(3)
|
|
|
const isComplete = ref(false)
|
|
|
const countdownSeconds = ref<number | null>(null)
|
|
|
|
|
|
@@ -16,6 +17,7 @@ export function useDialogueEngine() {
|
|
|
|
|
|
const isProcessing = computed(() => messages.value.some(m => m.status === 'loading'))
|
|
|
const canRecord = computed(() => !isProcessing.value && !isComplete.value)
|
|
|
+ const isFinalRound = computed(() => currentRound.value >= totalRounds.value)
|
|
|
|
|
|
// ==================== Session Attach ====================
|
|
|
|
|
|
@@ -27,9 +29,14 @@ export function useDialogueEngine() {
|
|
|
* expiresAt 由后端在 createSession 时基于 durationMinutes 计算下发,前端只读 ——
|
|
|
* 保证关页面/刷新/换设备重进都能接续同一个截止时刻,倒计时不暂停。
|
|
|
*/
|
|
|
- function attachSession(info: { sessionId: string; expiresAt?: string | null }) {
|
|
|
+ function attachSession(info: {
|
|
|
+ sessionId: string
|
|
|
+ expiresAt?: string | null
|
|
|
+ totalRounds: number
|
|
|
+ }) {
|
|
|
sessionId.value = info.sessionId
|
|
|
expiresAt.value = info.expiresAt ?? null
|
|
|
+ totalRounds.value = info.totalRounds
|
|
|
if (info.expiresAt) startCountdown(info.expiresAt)
|
|
|
}
|
|
|
|
|
|
@@ -419,11 +426,13 @@ export function useDialogueEngine() {
|
|
|
messages,
|
|
|
sessionId,
|
|
|
currentRound,
|
|
|
+ totalRounds,
|
|
|
isComplete,
|
|
|
isProcessing,
|
|
|
canRecord,
|
|
|
countdownSeconds,
|
|
|
greetingInflight,
|
|
|
+ isFinalRound,
|
|
|
|
|
|
attachSession,
|
|
|
generateGreeting,
|
|
|
@@ -466,3 +475,16 @@ function friendlyErrorMessage(raw: string | undefined): string {
|
|
|
if (!raw) return '请求失败,请重试'
|
|
|
return map[raw] || raw
|
|
|
}
|
|
|
+
|
|
|
+export type Recovery = 'retry' | 'rerecord' | 'restart'
|
|
|
+
|
|
|
+export function classifyError(
|
|
|
+ raw: string | undefined,
|
|
|
+ status: number | undefined,
|
|
|
+ role: 'student' | 'ai',
|
|
|
+): Recovery {
|
|
|
+ if (status === 404 || status === 409) return 'restart'
|
|
|
+ if (raw === 'Session not found' || raw === 'Session is not active') return 'restart'
|
|
|
+ if (raw === 'No speech detected' && role === 'student') return 'rerecord'
|
|
|
+ return 'retry'
|
|
|
+}
|