feat: 完善人生轨迹详情页功能及微信小程序登录优化

This commit is contained in:
2026-06-15 10:17:30 +08:00
parent cb3c5e6724
commit 74a2c15b6b
37 changed files with 1974 additions and 516 deletions
+70 -1
View File
@@ -2,7 +2,13 @@ import { computed, onUnmounted, ref } from 'vue'
import { createTtsTask, getTtsTask, getTtsTaskBySource } from '../services/tts.js'
import analytics from '../services/analytics.js'
const readResponseData = (response) => response?.data ?? response ?? null
const readResponseData = (response) => {
if (!response) return null
if (Object.prototype.hasOwnProperty.call(response, 'data')) {
return response.data ?? null
}
return response
}
export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {}) => {
const task = ref(null)
@@ -11,6 +17,8 @@ export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {})
const statusText = ref('')
let audio = null
let timer = null
let prewarmPromise = null
let prewarmSourceId = ''
const buttonText = computed(() => {
if (loading.value) return '正在生成朗读'
@@ -155,6 +163,49 @@ export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {})
}
}
const prewarmSource = async (sourceId) => {
if (!sourceId) return null
if (task.value?.status === 'success' && task.value?.sourceId === sourceId) {
return task.value
}
if (prewarmPromise && prewarmSourceId === sourceId) {
return prewarmPromise
}
prewarmSourceId = sourceId
prewarmPromise = (async () => {
try {
const existingResponse = await getTtsTaskBySource({ sourceType, sourceId })
const existingTask = readResponseData(existingResponse)
if (existingTask?.id) {
setTask(existingTask)
}
if (existingTask?.status === 'success' || existingTask?.status === 'pending' || existingTask?.status === 'processing') {
return existingTask
}
} catch (error) {
// Old scripts may not have a task yet; create one silently below.
}
try {
const createResponse = await createTtsTask({ sourceType, sourceId })
const nextTask = readResponseData(createResponse)
if (nextTask?.id) {
setTask(nextTask)
}
return nextTask
} catch (error) {
track('script_tts_error', sourceId, { error: error?.message || error?.errMsg || 'prewarm failed' })
return null
} finally {
prewarmPromise = null
prewarmSourceId = ''
}
})()
return prewarmPromise
}
const playSource = async (sourceId) => {
if (!sourceId) {
uni.showToast({ title: '生成保存后可播放', icon: 'none' })
@@ -162,6 +213,21 @@ export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {})
}
if (loading.value) return
if (prewarmPromise && prewarmSourceId === sourceId) {
const warmedTask = await prewarmPromise
if (warmedTask?.status === 'success') {
setTask(warmedTask)
play(sourceId)
return
}
if ((warmedTask?.status === 'pending' || warmedTask?.status === 'processing') && warmedTask?.id) {
setTask(warmedTask)
loading.value = true
pollTask(warmedTask.id, sourceId)
return
}
}
if (task.value?.status === 'success') {
play(sourceId)
return
@@ -195,6 +261,8 @@ export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {})
setTask(null)
statusText.value = ''
loading.value = false
prewarmPromise = null
prewarmSourceId = ''
}
onUnmounted(reset)
@@ -205,6 +273,7 @@ export const useTtsPlayer = ({ pagePath = '', sourceType = 'epic_script' } = {})
playing,
statusText,
buttonText,
prewarmSource,
playSource,
reset
}