diff --git a/cloudfunctions/tts/index.js b/cloudfunctions/tts/index.js index 0cbe409..dc70be2 100644 --- a/cloudfunctions/tts/index.js +++ b/cloudfunctions/tts/index.js @@ -80,12 +80,23 @@ exports.main = async (event) => { // If the client passed a cached fileID, try to get a fresh temp URL // from it — this is the fast path (no synthesis, no upload). - if (fileID) { + const db = cloud.database() + const cacheKey = `${promptKey}-${voiceType || 'default'}-v${volume != null ? volume : 0}-s${speed != null ? speed : 0}` + + // 解析 fileID:优先 client 传入,否则查服务端 tts_cache,防 client 传 null 强制重合成(刷 TTS 账单) + let resolvedFileID = fileID || null + if (!resolvedFileID) { try { - const urlRes = await cloud.getTempFileURL({ fileList: [fileID] }) + const r = await db.collection('tts_cache').doc(cacheKey).get() + if (r.data && r.data.length && r.data[0].fileID) resolvedFileID = r.data[0].fileID + } catch (e) {} // 集合/文档不存在,走合成 + } + if (resolvedFileID) { + try { + const urlRes = await cloud.getTempFileURL({ fileList: [resolvedFileID] }) const url = urlRes.fileList[0].tempFileURL if (url) { - return { success: true, audioUrl: url, fileID, text, cached: true } + return { success: true, audioUrl: url, fileID: resolvedFileID, text, cached: true } } } catch (e) { // fileID stale or file deleted — fall through to re-synthesize @@ -101,6 +112,8 @@ exports.main = async (event) => { if (!url) { return { success: false, error: 'getTempFileURL returned empty URL', text } } + // 写服务端 tts_cache,下次相同参数直接命中,不重复合成 + try { await db.collection('tts_cache').doc(cacheKey).set({ data: { fileID: newFileID, updatedAt: db.serverDate() } }) } catch (e) {} return { success: true, audioUrl: url, fileID: newFileID, text, cached: false } } catch (e) { return { success: false, error: e.message, text }