feat: TTS服务 + 数字人面试组件 (P1)
This commit is contained in:
@@ -28,7 +28,9 @@ export class InterviewController {
|
||||
@Param('id') id: string,
|
||||
@CurrentUser('userId') userId: string,
|
||||
@Body('answer') answer: string,
|
||||
@Body('avatar') avatar?: boolean,
|
||||
) {
|
||||
if (avatar) return this.interviewService.answerWithAvatar(id, userId, answer)
|
||||
return this.interviewService.answer(id, userId, answer)
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { InterviewService } from './interview.service'
|
||||
import { Interview, InterviewSchema } from './interview.schema'
|
||||
import { Progress, ProgressSchema } from '../schemas/progress.schema'
|
||||
import { UserModule } from '../user/user.module'
|
||||
import { TtsModule } from '../tts/tts.module'
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -13,6 +14,7 @@ import { UserModule } from '../user/user.module'
|
||||
{ name: Progress.name, schema: ProgressSchema },
|
||||
]),
|
||||
UserModule,
|
||||
TtsModule,
|
||||
],
|
||||
controllers: [InterviewController],
|
||||
providers: [InterviewService],
|
||||
|
||||
@@ -6,6 +6,7 @@ import { Progress, ProgressDocument } from '../schemas/progress.schema'
|
||||
import { AiService } from '../ai/ai.service'
|
||||
import { UserService } from '../user/user.service'
|
||||
import { QuotaService } from '../user/quota.service'
|
||||
import { TtsService } from '../tts/tts.service'
|
||||
import { analyzeSpeech } from '../../common/utils/filler-words'
|
||||
|
||||
@Injectable()
|
||||
@@ -16,6 +17,7 @@ export class InterviewService {
|
||||
private aiService: AiService,
|
||||
private userService: UserService,
|
||||
private quotaService: QuotaService,
|
||||
private ttsService: TtsService,
|
||||
) {}
|
||||
|
||||
async create(userId: string, position: string) {
|
||||
@@ -99,6 +101,20 @@ ${conversationHistory}
|
||||
}
|
||||
}
|
||||
|
||||
async answerWithAvatar(interviewId: string, userId: string, answer: string) {
|
||||
const base = await this.answer(interviewId, userId, answer)
|
||||
const aiMsg = base.messages?.find(m => m.role === 'ai')
|
||||
if (aiMsg?.content) {
|
||||
try {
|
||||
const tts = await this.ttsService.synthesize(aiMsg.content)
|
||||
return { ...base, ttsHash: tts.hash, ttsDurationMs: tts.durationMs }
|
||||
} catch {
|
||||
// TTS failure is non-critical, return without audio
|
||||
}
|
||||
}
|
||||
return base
|
||||
}
|
||||
|
||||
async complete(interviewId: string, userId: string) {
|
||||
const interview = await this.interviewModel.findOne({ _id: interviewId, userId }).exec()
|
||||
if (!interview) throw new HttpException('面试不存在', HttpStatus.NOT_FOUND)
|
||||
|
||||
Reference in New Issue
Block a user