fix(tts): 服务端 tts_cache 去重,防传 null 强制重合成刷 TTS 账单

- 合成前先查 tts_cache 集合,命中则直接 getTempFileURL,不重复合成
- 合成后写 tts_cache,相同参数组合只合成一次
- 集合不存在时 catch 走原合成路径不崩(需在云开发控制台建 tts_cache 集合启用去重)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
liucheng
2026-07-25 14:55:23 +08:00
parent 1c140bd503
commit 88a2c349f4
+16 -3
View File
@@ -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 }