| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- import type { TopicDiscussionConfig } from '@/types/englishSpeaking'
- import { SPEAKING_CONFIG_API_BASE_URL } from '@/views/Editor/EnglishSpeaking/services/speakingApiConfig'
- const API_BASE = SPEAKING_CONFIG_API_BASE_URL
- export interface SpeakingConfigRecord {
- id: string
- config: TopicDiscussionConfig
- ownerUid?: string | null
- }
- async function parse<T>(res: Response): Promise<T> {
- if (!res.ok) {
- const detail = await res.text().catch(() => '')
- throw new Error(`[${res.status}] ${detail || res.statusText}`)
- }
- return res.json() as Promise<T>
- }
- /** 新建话题讨论配置 */
- export async function createSpeakingConfig(
- config: TopicDiscussionConfig,
- ownerUid?: string | null,
- ): Promise<SpeakingConfigRecord> {
- const res = await fetch(API_BASE, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ config, ownerUid: ownerUid ?? null }),
- })
- return parse<SpeakingConfigRecord>(res)
- }
- /** 读取话题讨论配置 */
- export async function getSpeakingConfig(id: string): Promise<SpeakingConfigRecord> {
- const res = await fetch(`${API_BASE}/${encodeURIComponent(id)}`)
- return parse<SpeakingConfigRecord>(res)
- }
- /** 更新话题讨论配置 */
- export async function updateSpeakingConfig(
- id: string,
- config: TopicDiscussionConfig,
- ): Promise<SpeakingConfigRecord> {
- const res = await fetch(`${API_BASE}/${encodeURIComponent(id)}`, {
- method: 'PUT',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({ config }),
- })
- return parse<SpeakingConfigRecord>(res)
- }
- import { SPEAKING_DIALOGUE_API_BASE_URL } from '@/views/Editor/EnglishSpeaking/services/speakingApiConfig'
- const DIALOGUE_BASE = SPEAKING_DIALOGUE_API_BASE_URL
- export interface ClassSessionSummary {
- userId: string
- sessionId: string
- status: 'active' | 'completed' | 'abandoned'
- overallStatus: 'ready' | 'generating' | 'failed' | null
- currentRound: number
- totalRounds: number
- overallScore: number | null
- dimensions: Record<string, number>
- topHighlights: string[]
- topImprovements: string[]
- createdAt: string | null
- completedAt: string | null
- }
- export interface ListSessionsByConfigResponse {
- summaries: ClassSessionSummary[]
- }
- export async function listSpeakingSessionsByConfig(
- configId: string,
- userIds: string[],
- ): Promise<ListSessionsByConfigResponse> {
- const params = new URLSearchParams({ configId, userIds: userIds.join(',') })
- const res = await fetch(`${DIALOGUE_BASE}/sessions/by-config?${params}`, {
- method: 'GET',
- credentials: 'include',
- })
- if (!res.ok) throw new Error(`listSpeakingSessionsByConfig failed: ${res.status}`)
- return res.json()
- }
- export interface ClassSummaryResponse {
- bullets: [string, string, string]
- generatedAt: string
- fromCache: boolean
- llmStatus: 'ok' | 'fallback'
- }
- export async function generateClassSummary(
- configId: string,
- userIds: string[],
- locale: 'zh' | 'en' | 'hk',
- ): Promise<ClassSummaryResponse> {
- const res = await fetch(`${DIALOGUE_BASE}/sessions/by-config/summary`, {
- method: 'POST',
- headers: { 'Content-Type': 'application/json' },
- credentials: 'include',
- body: JSON.stringify({ configId, userIds, locale }),
- })
- if (!res.ok) throw new Error(`generateClassSummary failed: ${res.status}`)
- return res.json()
- }
|