import Router from '@koa/router'; import { Context } from 'koa'; import * as TtsService from './tts.service'; import { BadRequestError } from '../../middleware/errorHandler'; import { optionalAuth } from '../../middleware/auth'; import { usageLimitMiddleware, checkWordLimit } from '../../middleware/usageLimit'; import { User } from '../../models/User'; import { Audio } from '../../models/Audio'; const router = new Router(); // 获取可用音色列表 router.get('/voices', async (ctx: Context) => { const voices = TtsService.getVoices(); ctx.body = { code: 0, message: 'success', data: { voices }, }; }); // 测试 MongoDB 连接 router.get('/test-db', async (ctx: Context) => { try { const count = await Audio.countDocuments(); ctx.body = { code: 0, message: 'success', data: { count, connectionState: 'connected' }, }; } catch (error: any) { ctx.body = { code: 500, message: 'error', data: { error: error.message }, }; } }); // 生成音频 router.post( '/generate', optionalAuth, async (ctx: Context) => { const userId = ctx.state.user?.userId; const { text, voiceId, voiceParams } = ctx.request.body as { text: string; voiceId: string; voiceParams?: { speed?: number; pitch?: number; volume?: number }; }; // 参数验证 if (!text || text.trim().length === 0) { throw new BadRequestError('请输入要转换的文本'); } if (!voiceId) { throw new BadRequestError('请选择音色'); } // 检查字数限制(测试模式:无限制) const wordCount = text.length; const quota = ctx.state.userQuota || { dailyLimit: -1, wordLimit: -1 }; if (quota.wordLimit !== -1 && wordCount > quota.wordLimit) { throw new BadRequestError(`文本字数超出限制(${quota.wordLimit}字)`); } // 默认参数 const params = { speed: voiceParams?.speed || 1.0, pitch: voiceParams?.pitch || 0, volume: voiceParams?.volume || 50, }; // 生成音频 const result = await TtsService.generateAudio(userId, text, voiceId, params); // 如果用户已登录,更新使用次数 if (userId) { const user = await User.findById(userId); if (user) { user.dailyUsage += 1; await user.save(); } } ctx.body = { code: 0, message: '音频生成成功', data: result, }; } ); // 预览音色 router.post('/preview', async (ctx: Context) => { const { voiceId, voiceParams } = ctx.request.body as { voiceId: string; voiceParams?: { speed?: number; pitch?: number; volume?: number }; }; if (!voiceId) { throw new BadRequestError('请选择音色'); } // 返回预览文本 ctx.body = { code: 0, message: 'success', data: { previewText: '这是一段预览文本,用于试听音色效果。', voiceId, }, }; }); export default router;