Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | /** * AI 调用日志 —— 记录每次大模型 / TTS API 请求,方便对账 * * 写入策略:fire-and-forget,不阻塞业务请求 */ import { prisma } from '../models'; export interface LogCallParams { callType: string; // tts_create | tts_poll | tts_download | llm_chat | llm_tools provider: string; // minimax | bailian | volcengine model: string; // speech-2.8-hd | qwen3-tts-instruct-flash | MiniMax-M2.7 textLen?: number; prompt?: string; // 提示词内容 tokenCount?: number; duration?: number; success?: boolean; errorMsg?: string; bookId?: number; chapterId?: number; } /** * 记录一次 AI 调用(异步写入,不阻塞) */ export function logAiCall(params: LogCallParams): void { // Always log to console so we know it was called console.log(`[AiCallLog] ${params.callType} | ${params.provider} | ${params.model} | ${params.success ? 'OK' : 'FAIL'} | ${params.textLen || 0}字`); prisma.aiCallLog.create({ data: { callType: params.callType, provider: params.provider, model: params.model, textLen: params.textLen ?? 0, prompt: params.prompt ?? null, duration: params.duration ?? 0, success: params.success ?? true, errorMsg: params.errorMsg?.substring(0, 200) ?? null, bookId: params.bookId ?? null, chapterId: params.chapterId ?? null, }, }).then(result => { // Successfully written }).catch(err => { console.error('[AiCallLog] ❌ 写入数据库失败:', err.message); }); } /** * 包装异步函数,自动计时 + 记录日志 * * 用法: * const result = await withAiLog( * () => axios.post(url, body), * { callType: 'tts_create', provider: 'minimax', model: 'speech-2.8-hd', textLen: 1000 } * ); */ export async function withAiLog<T>( fn: () => Promise<T>, params: LogCallParams, ): Promise<T> { const t0 = Date.now(); try { const result = await fn(); logAiCall({ ...params, duration: Date.now() - t0 }); return result; } catch (err: any) { logAiCall({ ...params, duration: Date.now() - t0, success: false, errorMsg: err.message }); throw err; } } |